Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / test / chromedriver / chrome / navigation_tracker_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string>
6
7 #include "base/compiler_specific.h"
8 #include "base/json/json_reader.h"
9 #include "base/values.h"
10 #include "chrome/test/chromedriver/chrome/navigation_tracker.h"
11 #include "chrome/test/chromedriver/chrome/status.h"
12 #include "chrome/test/chromedriver/chrome/stub_devtools_client.h"
13 #include "chrome/test/chromedriver/chrome/version.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace {
17
18 void AssertPendingState(NavigationTracker* tracker,
19                         const std::string& frame_id,
20                         bool expected_is_pending) {
21   bool is_pending = !expected_is_pending;
22   ASSERT_EQ(kOk, tracker->IsPendingNavigation(frame_id, &is_pending).code());
23   ASSERT_EQ(expected_is_pending, is_pending);
24 }
25
26 void AssertTrackerExpectsSingleStopEvent(BrowserInfo* browser_info) {
27   StubDevToolsClient client;
28   NavigationTracker tracker(&client, browser_info);
29   base::DictionaryValue params;
30   params.SetString("frameId", "f");
31
32   // pending_frames_set_.size() == 0
33   ASSERT_EQ(
34       kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
35   // pending_frames_set_.size() == 1
36   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
37   ASSERT_EQ(
38       kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
39   // pending_frames_set_.size() == 2
40   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
41   ASSERT_EQ(
42       kOk, tracker.OnEvent(&client, "Page.frameStoppedLoading", params).code());
43   // pending_frames_set_.size() == 0
44   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
45 }
46
47 void AssertTrackerExpectsMultipleStopEvents(BrowserInfo* browser_info) {
48   StubDevToolsClient client;
49   NavigationTracker tracker(&client, browser_info);
50   base::DictionaryValue params;
51
52   // pending_frames_set_.size() == 0
53   params.SetString("frameId", "1");
54   ASSERT_EQ(
55       kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
56   // pending_frames_set_.size() == 1
57   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "1", true));
58   params.SetString("frameId", "2");
59   ASSERT_EQ(
60       kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
61   // pending_frames_set_.size() == 2
62   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "2", true));
63   params.SetString("frameId", "2");
64   ASSERT_EQ(
65       kOk, tracker.OnEvent(&client, "Page.frameStoppedLoading", params).code());
66   // pending_frames_set_.size() == 1
67   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "2", true));
68   params.SetString("frameId", "1");
69   ASSERT_EQ(
70       kOk, tracker.OnEvent(&client, "Page.frameStoppedLoading", params).code());
71   // pending_frames_set_.size() == 0
72   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "1", false));
73   params.SetString("frameId", "3");
74   ASSERT_EQ(
75       kOk, tracker.OnEvent(&client, "Page.frameStoppedLoading", params).code());
76   // pending_frames_set_.size() == 0
77   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "3", false));
78   ASSERT_EQ(
79       kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
80   // pending_frames_set_.size() == 1
81   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "3", true));
82 }
83
84 }  // namespace
85
86 TEST(NavigationTracker, FrameLoadStartStop) {
87   StubDevToolsClient client;
88   BrowserInfo browser_info;
89   NavigationTracker tracker(&client, &browser_info);
90
91   base::DictionaryValue params;
92   params.SetString("frameId", "f");
93
94   ASSERT_EQ(
95       kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
96   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
97   ASSERT_EQ(
98       kOk, tracker.OnEvent(&client, "Page.frameStoppedLoading", params).code());
99   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
100 }
101
102 // When a frame fails to load due to (for example) a DNS resolution error, we
103 // can sometimes see two Page.frameStartedLoading events with only a single
104 // Page.frameStoppedLoading event.
105 TEST(NavigationTracker, FrameLoadStartStartStop) {
106   StubDevToolsClient client;
107   BrowserInfo browser_info;
108   NavigationTracker tracker(&client, &browser_info);
109
110   base::DictionaryValue params;
111   params.SetString("frameId", "f");
112
113   ASSERT_EQ(
114       kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
115   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
116   ASSERT_EQ(
117       kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
118   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
119   ASSERT_EQ(
120       kOk, tracker.OnEvent(&client, "Page.frameStoppedLoading", params).code());
121   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
122 }
123
124 // NavigationTracker::OnEvent handles the Page.frameStoppedLoading event
125 // differently, depending on the browser and blink version. See the comment in
126 // NavigationTracker::OnEvent for details.
127
128 TEST(NavigationTracker, MultipleFramesLoadOldDevtools) {
129   BrowserInfo kOldChromeWithNewBlink("chrome", std::string(), 1916, 170248);
130   AssertTrackerExpectsSingleStopEvent(&kOldChromeWithNewBlink);
131
132   BrowserInfo kWebViewWithOldBlink("webview", std::string(), 9999, 170247);
133   AssertTrackerExpectsSingleStopEvent(&kWebViewWithOldBlink);
134 }
135
136 TEST(NavigationTracker, MultipleFramesLoad) {
137   BrowserInfo kNewChromeWithNewBlink("chrome", std::string(), 1917, 170248);
138   AssertTrackerExpectsMultipleStopEvents(&kNewChromeWithNewBlink);
139
140   BrowserInfo kWebViewWithNewBlink("webview", std::string(), 9999, 170248);
141   AssertTrackerExpectsMultipleStopEvents(&kWebViewWithNewBlink);
142 }
143
144 TEST(NavigationTracker, NavigationScheduledThenLoaded) {
145   StubDevToolsClient client;
146   BrowserInfo browser_info;
147   NavigationTracker tracker(
148       &client, NavigationTracker::kNotLoading, &browser_info);
149   base::DictionaryValue params;
150   params.SetString("frameId", "f");
151   base::DictionaryValue params_scheduled;
152   params_scheduled.SetInteger("delay", 0);
153   params_scheduled.SetString("frameId", "f");
154
155   ASSERT_EQ(
156       kOk,
157       tracker.OnEvent(
158           &client, "Page.frameScheduledNavigation", params_scheduled).code());
159   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
160   ASSERT_EQ(
161       kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
162   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
163   ASSERT_EQ(
164       kOk,
165       tracker.OnEvent(&client, "Page.frameClearedScheduledNavigation", params)
166           .code());
167   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
168   ASSERT_EQ(
169       kOk, tracker.OnEvent(&client, "Page.frameStoppedLoading", params).code());
170   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
171 }
172
173 TEST(NavigationTracker, NavigationScheduledForOtherFrame) {
174   StubDevToolsClient client;
175   BrowserInfo browser_info;
176   NavigationTracker tracker(
177       &client, NavigationTracker::kNotLoading, &browser_info);
178   base::DictionaryValue params_scheduled;
179   params_scheduled.SetInteger("delay", 0);
180   params_scheduled.SetString("frameId", "other");
181
182   ASSERT_EQ(
183       kOk,
184       tracker.OnEvent(
185           &client, "Page.frameScheduledNavigation", params_scheduled).code());
186   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
187 }
188
189 TEST(NavigationTracker, NavigationScheduledThenCancelled) {
190   StubDevToolsClient client;
191   BrowserInfo browser_info;
192   NavigationTracker tracker(
193       &client, NavigationTracker::kNotLoading, &browser_info);
194   base::DictionaryValue params;
195   params.SetString("frameId", "f");
196   base::DictionaryValue params_scheduled;
197   params_scheduled.SetInteger("delay", 0);
198   params_scheduled.SetString("frameId", "f");
199
200   ASSERT_EQ(
201       kOk,
202       tracker.OnEvent(
203           &client, "Page.frameScheduledNavigation", params_scheduled).code());
204   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
205   ASSERT_EQ(
206       kOk,
207       tracker.OnEvent(&client, "Page.frameClearedScheduledNavigation", params)
208           .code());
209   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
210 }
211
212 TEST(NavigationTracker, NavigationScheduledTooFarAway) {
213   StubDevToolsClient client;
214   BrowserInfo browser_info;
215   NavigationTracker tracker(
216       &client, NavigationTracker::kNotLoading, &browser_info);
217
218   base::DictionaryValue params_scheduled;
219   params_scheduled.SetInteger("delay", 10);
220   params_scheduled.SetString("frameId", "f");
221   ASSERT_EQ(
222       kOk,
223       tracker.OnEvent(
224           &client, "Page.frameScheduledNavigation", params_scheduled).code());
225   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
226 }
227
228 TEST(NavigationTracker, DiscardScheduledNavigationsOnMainFrameCommit) {
229   StubDevToolsClient client;
230   BrowserInfo browser_info;
231   NavigationTracker tracker(
232       &client, NavigationTracker::kNotLoading, &browser_info);
233
234   base::DictionaryValue params_scheduled;
235   params_scheduled.SetString("frameId", "subframe");
236   params_scheduled.SetInteger("delay", 0);
237   ASSERT_EQ(
238       kOk,
239       tracker.OnEvent(
240           &client, "Page.frameScheduledNavigation", params_scheduled).code());
241   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "subframe", true));
242
243   base::DictionaryValue params_navigated;
244   params_navigated.SetString("frame.parentId", "something");
245   ASSERT_EQ(
246       kOk,
247       tracker.OnEvent(&client, "Page.frameNavigated", params_navigated).code());
248   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "subframe", true));
249   params_navigated.Clear();
250   ASSERT_EQ(
251       kOk,
252       tracker.OnEvent(&client, "Page.frameNavigated", params_navigated).code());
253   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "subframe", false));
254 }
255
256 namespace {
257
258 class FailToEvalScriptDevToolsClient : public StubDevToolsClient {
259  public:
260   virtual ~FailToEvalScriptDevToolsClient() {}
261
262   virtual Status SendCommandAndGetResult(
263       const std::string& method,
264       const base::DictionaryValue& params,
265       scoped_ptr<base::DictionaryValue>* result) OVERRIDE {
266     EXPECT_STREQ("Runtime.evaluate", method.c_str());
267     return Status(kUnknownError, "failed to eval script");
268   }
269 };
270
271 }  // namespace
272
273 TEST(NavigationTracker, UnknownStateFailsToDetermineState) {
274   FailToEvalScriptDevToolsClient client;
275   BrowserInfo browser_info;
276   NavigationTracker tracker(&client, &browser_info);
277   bool is_pending;
278   ASSERT_EQ(kUnknownError,
279             tracker.IsPendingNavigation("f", &is_pending).code());
280 }
281
282 namespace {
283
284 class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
285  public:
286   DeterminingLoadStateDevToolsClient(
287       bool is_loading,
288       const std::string& send_event_first,
289       base::DictionaryValue* send_event_first_params)
290       : is_loading_(is_loading),
291         send_event_first_(send_event_first),
292         send_event_first_params_(send_event_first_params) {}
293
294   virtual ~DeterminingLoadStateDevToolsClient() {}
295
296   virtual Status SendCommandAndGetResult(
297       const std::string& method,
298       const base::DictionaryValue& params,
299       scoped_ptr<base::DictionaryValue>* result) OVERRIDE {
300     if (send_event_first_.length()) {
301       Status status = listeners_.front()
302           ->OnEvent(this, send_event_first_, *send_event_first_params_);
303       if (status.IsError())
304         return status;
305     }
306
307     base::DictionaryValue result_dict;
308     result_dict.SetBoolean("result.value", is_loading_);
309     result->reset(result_dict.DeepCopy());
310     return Status(kOk);
311   }
312
313  private:
314   bool is_loading_;
315   std::string send_event_first_;
316   base::DictionaryValue* send_event_first_params_;
317 };
318
319 }  // namespace
320
321 TEST(NavigationTracker, UnknownStateForcesStart) {
322   base::DictionaryValue params;
323   DeterminingLoadStateDevToolsClient client(true, std::string(), &params);
324   BrowserInfo browser_info;
325   NavigationTracker tracker(&client, &browser_info);
326   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
327 }
328
329 TEST(NavigationTracker, UnknownStateForcesStartReceivesStop) {
330   base::DictionaryValue params;
331   params.SetString("frameId", "f");
332   DeterminingLoadStateDevToolsClient client(
333       true, "Page.frameStoppedLoading", &params);
334   BrowserInfo browser_info;
335   NavigationTracker tracker(&client, &browser_info);
336   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
337 }
338
339 TEST(NavigationTracker, OnSuccessfulNavigate) {
340   base::DictionaryValue params;
341   params.SetString("frameId", "f");
342   DeterminingLoadStateDevToolsClient client(
343       true, "Page.frameStoppedLoading", &params);
344   BrowserInfo browser_info;
345   NavigationTracker tracker(
346       &client, NavigationTracker::kNotLoading, &browser_info);
347   tracker.OnCommandSuccess(&client, "Page.navigate");
348   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
349 }
350
351 TEST(NavigationTracker, OnSuccessfulNavigateStillWaiting) {
352   base::DictionaryValue params;
353   params.SetString("frameId", "f");
354   DeterminingLoadStateDevToolsClient client(true, std::string(), &params);
355   BrowserInfo browser_info;
356   NavigationTracker tracker(
357       &client, NavigationTracker::kNotLoading, &browser_info);
358   tracker.OnCommandSuccess(&client, "Page.navigate");
359   ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
360 }