1 // Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include "include/base/cef_bind.h"
6 #include "include/base/cef_scoped_ptr.h"
7 #include "include/wrapper/cef_closure_task.h"
8 #include "include/wrapper/cef_stream_resource_handler.h"
9 #include "tests/ceftests/test_handler.h"
10 #include "tests/ceftests/test_util.h"
11 #include "tests/gtest/include/gtest/gtest.h"
12 #include "tests/shared/browser/client_app_browser.h"
13 #include "tests/shared/renderer/client_app_renderer.h"
14
15 using client::ClientAppBrowser;
16 using client::ClientAppRenderer;
17
18 namespace {
19
20 // The frame navigation test harness work as follows:
21 //
22 // In the browser process:
23 // 1. TEST() function creates a new FrameNavTestHandler instance with a unique
24 // FrameNavFactoryId.
25 // 2. FrameNavTestHandler calls FrameNavExpectationsFactoryBrowser::FromID to
26 // create a new factory instance.
27 // 3. FrameNavTestHandler calls FrameNavExpectationsFactoryBrowser::Create to
28 // create a new FrameNavExpectationsBrowser instance for the current
29 // navigation.
30 // 4. FrameNavTestHandler retrieves the URL to load via
31 // FrameNavExpectationsBrowser::GetMainURL and calls either CreateBrowser
32 // (for the first navigation) or LoadURL (for the following navigations).
33 // 5. If the renderer process does not already exist CEF creates it with
34 // command-line arguments that specify the FrameNavFactoryId via
35 // FrameNavBrowserTest::OnBeforeChildProcessLaunch.
36 //
37 // In the renderer process:
38 // 6. If the renderer process is newly created FrameNavRendererTest calls
39 // FrameNavExpectationsFactoryRenderer::FromID to create a new factory
40 // instance.
41 // 7. FrameNavRendererTest calls FrameNavExpectationsFactoryRenderer::Create to
42 // create a new FrameNavExpectationsRenderer instance for the current
43 // navigation.
44 //
45 // In both processes:
46 // 8. Callback notifications are sent to the FrameNavExpectations* instances.
47 //
48 // In the renderer process:
49 // 9. When the FrameNavExpectationsRenderer instance determines that the
50 // renderer side of the test is complete it calls SignalComplete which
51 // finalizes and deletes the FrameNavExpectationsRenderer instance and
52 // sends an IPC message to the browser process.
53 //
54 // In the browser process:
55 // 11.FrameNavExpectationsBrowser::OnRendererComplete is called in response to
56 // renderer-side test completion message.
57 // 12.When the FrameNavExpectationsBrowser instance determines that the browser
58 // side of the test is complete it calls SignalComplete which finalizes and
59 // deletes the FrameNavExpectationsBrowser instance.
60 // 13.If FrameNavExpectationsFactoryBrowser::HasMoreNavigations returns false
61 // then DestroyTest is called and the test ends. Otherwise, the navigation
62 // count is incremented and the process repeats starting with step #3.
63 //
64 //
65 // To add a new test case:
66 // 1. Add a new value to the FrameNavFactoryId enumeration.
67 // 2. Provide implementations of FrameNavExpectations*.
68 // 3. Add a case for the new factory ID to FrameNavExpectationsFactory*::FromID.
69 // 4. Implement a TEST() function that creates a FrameNavTestHandler instance
70 // and passes the new factory ID.
71 //
72 //
73 // Run with the `--single-process` command-line flag to see expectation failures
74 // from the renderer process.
75 //
76
77 // All known factory IDs.
78 enum FrameNavFactoryId {
79 FNF_ID_INVALID = 0,
80 FNF_ID_SINGLE_NAV_HARNESS,
81 FNF_ID_SINGLE_NAV,
82 FNF_ID_MULTI_NAV_HARNESS,
83 FNF_ID_MULTI_NAV,
84 FNF_ID_NESTED_IFRAMES_SAME_ORIGIN,
85 FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN,
86 };
87
88 // IPC message name.
89 const char kFrameNavMsg[] = "FrameTest.Navigation";
90
91 // Extra info parameter keys.
92 const char kFrameNavTestCmdKey[] = "frame-nav-test";
93
94 // Origins used in tests.
95 const char kFrameNavOrigin0[] = "http://tests-framenav0.com/";
96 const char kFrameNavOrigin1[] = "http://tests-framenav1.com/";
97 const char kFrameNavOrigin2[] = "http://tests-framenav2.com/";
98 const char kFrameNavOrigin3[] = "http://tests-framenav3.com/";
99
100 // Maximum number of navigations. Should be kept synchronized with the number
101 // of kFrameNavOrigin* values. Don't modify this value without checking the
102 // below use cases.
103 const int kMaxMultiNavNavigations = 4;
104
105 // Abstract base class representing expectations that result from a navigation.
106 class FrameNavExpectations {
107 public:
108 typedef base::Callback<void(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>)>
109 CompletionCallback;
110
FrameNavExpectations(int nav,bool renderer)111 FrameNavExpectations(int nav, bool renderer)
112 : nav_(nav), renderer_(renderer) {}
~FrameNavExpectations()113 virtual ~FrameNavExpectations() {}
114
115 // Browser and renderer notifications.
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)116 virtual bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
117 bool isLoading) {
118 return true;
119 }
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)120 virtual bool OnLoadStart(CefRefPtr<CefBrowser> browser,
121 CefRefPtr<CefFrame> frame) {
122 return true;
123 }
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)124 virtual bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
125 CefRefPtr<CefFrame> frame) {
126 return true;
127 }
128
129 // Final expectations check before this object is deleted.
130 virtual bool Finalize() = 0;
131
132 // Signal that all expectations are completed. Should be called as a result of
133 // notifications.
SignalComplete(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)134 void SignalComplete(CefRefPtr<CefBrowser> browser,
135 CefRefPtr<CefFrame> frame) {
136 if (!completion_callback_.is_null()) {
137 // Execute the callback asynchronously to avoid any issues with what's
138 // currently on the stack.
139 CefPostTask((renderer_ ? TID_RENDERER : TID_UI),
140 base::Bind(completion_callback_, browser, frame));
141 completion_callback_.Reset();
142 }
143 }
144
145 // Returns the current navigation count. In the browser process this value
146 // increments over the life span of the FrameNavTestHandler instance. In the
147 // renderer process this value increments over the life span of a single
148 // renderer instance (i.e. cross-origin navigations will cause this value to
149 // reset).
nav() const150 int nav() const { return nav_; }
151
152 // Returns true if this is a renderer-side expectation object.
renderer() const153 bool renderer() const { return renderer_; }
154
set_completion_callback(const CompletionCallback & completion_callback)155 void set_completion_callback(const CompletionCallback& completion_callback) {
156 completion_callback_ = completion_callback;
157 }
158
159 private:
160 int nav_;
161 bool renderer_;
162 CompletionCallback completion_callback_;
163 };
164
165 // Browser process expectations abstract base class.
166 class FrameNavExpectationsBrowser : public FrameNavExpectations {
167 public:
FrameNavExpectationsBrowser(int nav)168 explicit FrameNavExpectationsBrowser(int nav)
169 : FrameNavExpectations(nav, false) {}
170
171 // Loading information.
172 virtual std::string GetMainURL() = 0;
173 virtual std::string GetContentForURL(const std::string& url) = 0;
174
175 // Browser-only notifications.
OnAfterCreated(CefRefPtr<CefBrowser> browser)176 virtual bool OnAfterCreated(CefRefPtr<CefBrowser> browser) {
177 EXPECT_TRUE(browser.get());
178 return true;
179 }
OnBeforeBrowse(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const std::string & url)180 virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
181 CefRefPtr<CefFrame> frame,
182 const std::string& url) {
183 EXPECT_TRUE(browser.get());
184 EXPECT_TRUE(frame.get());
185 EXPECT_FALSE(url.empty());
186 return true;
187 }
GetResourceHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)188 virtual bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
189 CefRefPtr<CefFrame> frame) {
190 EXPECT_TRUE(browser.get());
191 EXPECT_TRUE(frame.get());
192 return true;
193 }
194
195 // Called when the renderer signals completion.
196 virtual bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
197 CefRefPtr<CefFrame> frame,
198 int renderer_nav,
199 bool renderer_result) = 0;
200 };
201
202 // Renderer process expectations abstract base class.
203 class FrameNavExpectationsRenderer : public FrameNavExpectations {
204 public:
FrameNavExpectationsRenderer(int nav)205 explicit FrameNavExpectationsRenderer(int nav)
206 : FrameNavExpectations(nav, true) {}
207 };
208
209 // Abstract base class for the factory that creates expectations objects.
210 class FrameNavExpectationsFactory {
211 public:
FrameNavExpectationsFactory()212 FrameNavExpectationsFactory() {}
~FrameNavExpectationsFactory()213 virtual ~FrameNavExpectationsFactory() {}
214
215 // Returns the unique ID for this factory type.
216 virtual FrameNavFactoryId GetID() const = 0;
217 };
218
219 // Browser process expectations factory abstact base class.
220 class FrameNavExpectationsFactoryBrowser : public FrameNavExpectationsFactory {
221 public:
FrameNavExpectationsFactoryBrowser()222 FrameNavExpectationsFactoryBrowser() {}
223
224 // Create a new factory instance of the specified type.
225 static scoped_ptr<FrameNavExpectationsFactoryBrowser> FromID(
226 FrameNavFactoryId id);
227
228 // Returns true if there will be more navigations in the browser process
229 // handler.
230 virtual bool HasMoreNavigations() const = 0;
231
232 // Verify final expectations results.
233 virtual bool Finalize() = 0;
234
Create(int nav,const FrameNavExpectations::CompletionCallback & completion_callback)235 scoped_ptr<FrameNavExpectationsBrowser> Create(
236 int nav,
237 const FrameNavExpectations::CompletionCallback& completion_callback) {
238 scoped_ptr<FrameNavExpectationsBrowser> expectations;
239 expectations = Create(nav);
240 expectations->set_completion_callback(completion_callback);
241 return expectations.Pass();
242 }
243
244 protected:
245 // Implement in the test-specific factory instance.
246 virtual scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) = 0;
247 };
248
249 // Renderer process expectations factory abstact base class.
250 class FrameNavExpectationsFactoryRenderer : public FrameNavExpectationsFactory {
251 public:
FrameNavExpectationsFactoryRenderer()252 FrameNavExpectationsFactoryRenderer() {}
253
254 // Create a new factory instance of the specified type.
255 static scoped_ptr<FrameNavExpectationsFactoryRenderer> FromID(
256 FrameNavFactoryId id);
257
Create(int nav,const FrameNavExpectations::CompletionCallback & completion_callback)258 scoped_ptr<FrameNavExpectationsRenderer> Create(
259 int nav,
260 const FrameNavExpectations::CompletionCallback& completion_callback) {
261 scoped_ptr<FrameNavExpectationsRenderer> expectations;
262 expectations = Create(nav);
263 expectations->set_completion_callback(completion_callback);
264 return expectations.Pass();
265 }
266
267 protected:
268 // Implement in the test-specific factory instance.
269 virtual scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) = 0;
270 };
271
272 // Renderer side handler.
273 class FrameNavRendererTest : public ClientAppRenderer::Delegate,
274 public CefLoadHandler {
275 public:
FrameNavRendererTest()276 FrameNavRendererTest() : run_test_(false), nav_(0) {}
277
OnBrowserCreated(CefRefPtr<ClientAppRenderer> app,CefRefPtr<CefBrowser> browser,CefRefPtr<CefDictionaryValue> extra_info)278 void OnBrowserCreated(CefRefPtr<ClientAppRenderer> app,
279 CefRefPtr<CefBrowser> browser,
280 CefRefPtr<CefDictionaryValue> extra_info) override {
281 if (!extra_info->HasKey(kFrameNavTestCmdKey))
282 return;
283
284 FrameNavFactoryId factory_id =
285 static_cast<FrameNavFactoryId>(extra_info->GetInt(kFrameNavTestCmdKey));
286 run_test_ = factory_id != FNF_ID_INVALID;
287 if (!run_test_)
288 return;
289
290 factory_ = FrameNavExpectationsFactoryRenderer::FromID(factory_id);
291 }
292
GetLoadHandler(CefRefPtr<ClientAppRenderer> app)293 CefRefPtr<CefLoadHandler> GetLoadHandler(
294 CefRefPtr<ClientAppRenderer> app) override {
295 if (!run_test_)
296 return nullptr;
297
298 return this;
299 }
300
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading,bool canGoBack,bool canGoForward)301 void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
302 bool isLoading,
303 bool canGoBack,
304 bool canGoForward) override {
305 CreateExpectationsIfNecessary();
306 EXPECT_TRUE(expectations_->OnLoadingStateChange(browser, isLoading))
307 << "isLoading = " << isLoading << ", nav = " << nav_;
308 }
309
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,TransitionType transition_type)310 void OnLoadStart(CefRefPtr<CefBrowser> browser,
311 CefRefPtr<CefFrame> frame,
312 TransitionType transition_type) override {
313 CreateExpectationsIfNecessary();
314 EXPECT_TRUE(expectations_->OnLoadStart(browser, frame)) << "nav = " << nav_;
315 }
316
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int httpStatusCode)317 void OnLoadEnd(CefRefPtr<CefBrowser> browser,
318 CefRefPtr<CefFrame> frame,
319 int httpStatusCode) override {
320 CreateExpectationsIfNecessary();
321 EXPECT_TRUE(expectations_->OnLoadEnd(browser, frame)) << "nav = " << nav_;
322 }
323
324 protected:
325 // Create a new expectations object if one does not already exist for the
326 // current navigation.
CreateExpectationsIfNecessary()327 void CreateExpectationsIfNecessary() {
328 if (expectations_)
329 return;
330 expectations_ = factory_->Create(
331 nav_, base::Bind(&FrameNavRendererTest::SendTestResults, this));
332 }
333
334 // Send the test results.
335 // Will be called via FrameNavExpectations::SignalComplete.
SendTestResults(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)336 void SendTestResults(CefRefPtr<CefBrowser> browser,
337 CefRefPtr<CefFrame> frame) {
338 // End of the current expectations object.
339 EXPECT_TRUE(expectations_->Finalize()) << "nav = " << nav_;
340 expectations_.reset(nullptr);
341
342 // Check if the test has failed.
343 bool result = !TestFailed();
344
345 // Return the result to the browser process.
346 CefRefPtr<CefProcessMessage> return_msg =
347 CefProcessMessage::Create(kFrameNavMsg);
348 CefRefPtr<CefListValue> args = return_msg->GetArgumentList();
349 EXPECT_TRUE(args.get());
350 EXPECT_TRUE(args->SetInt(0, nav_));
351 EXPECT_TRUE(args->SetBool(1, result));
352
353 const int64 frame_id = frame->GetIdentifier();
354 EXPECT_TRUE(args->SetInt(2, CefInt64GetLow(frame_id)));
355 EXPECT_TRUE(args->SetInt(3, CefInt64GetHigh(frame_id)));
356
357 frame->SendProcessMessage(PID_BROWSER, return_msg);
358
359 nav_++;
360 }
361
362 bool run_test_;
363 int nav_;
364 scoped_ptr<FrameNavExpectationsFactoryRenderer> factory_;
365 scoped_ptr<FrameNavExpectationsRenderer> expectations_;
366
367 IMPLEMENT_REFCOUNTING(FrameNavRendererTest);
368 };
369
370 // Browser side handler.
371 class FrameNavTestHandler : public TestHandler {
372 public:
FrameNavTestHandler(FrameNavFactoryId factory_id)373 explicit FrameNavTestHandler(FrameNavFactoryId factory_id)
374 : nav_(0),
375 factory_(FrameNavExpectationsFactoryBrowser::FromID(factory_id)) {}
376
~FrameNavTestHandler()377 ~FrameNavTestHandler() override { EXPECT_TRUE(got_destroyed_); }
378
RunTest()379 void RunTest() override {
380 // Create the first expectations object.
381 expectations_ = factory_->Create(
382 nav_, base::Bind(&FrameNavTestHandler::RunNextNav, this));
383
384 CefRefPtr<CefDictionaryValue> extra_info = CefDictionaryValue::Create();
385 extra_info->SetInt(kFrameNavTestCmdKey, factory_->GetID());
386
387 // Create the browser with the initial URL.
388 CreateBrowser(expectations_->GetMainURL(), nullptr, extra_info);
389
390 // Time out the test after a reasonable period of time.
391 SetTestTimeout(15000);
392 }
393
394 // Transition to the next navigation.
395 // Will be called via FrameNavExpectations::SignalComplete.
RunNextNav(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)396 void RunNextNav(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame) {
397 // End of the current expectations object.
398 EXPECT_TRUE(expectations_->Finalize());
399 expectations_.reset(nullptr);
400
401 if (!factory_->HasMoreNavigations()) {
402 // End of the test.
403 DestroyTest();
404 return;
405 }
406
407 nav_++;
408
409 // Create the next expectations object.
410 expectations_ = factory_->Create(
411 nav_, base::Bind(&FrameNavTestHandler::RunNextNav, this));
412
413 // Load the main URL.
414 browser->GetMainFrame()->LoadURL(expectations_->GetMainURL());
415 }
416
OnAfterCreated(CefRefPtr<CefBrowser> browser)417 void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
418 TestHandler::OnAfterCreated(browser);
419
420 EXPECT_TRUE(expectations_->OnAfterCreated(browser)) << "nav = " << nav_;
421 }
422
GetResourceHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request)423 CefRefPtr<CefResourceHandler> GetResourceHandler(
424 CefRefPtr<CefBrowser> browser,
425 CefRefPtr<CefFrame> frame,
426 CefRefPtr<CefRequest> request) override {
427 const std::string& url = request->GetURL();
428 if (IgnoreURL(url))
429 return nullptr;
430
431 EXPECT_TRUE(expectations_->GetResourceHandler(browser, frame))
432 << "nav = " << nav_;
433
434 const std::string& content = expectations_->GetContentForURL(url);
435 EXPECT_TRUE(!content.empty()) << "nav = " << nav_;
436
437 CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
438 static_cast<void*>(const_cast<char*>(content.c_str())),
439 content.length());
440 return new CefStreamResourceHandler("text/html", stream);
441 }
442
OnBeforeBrowse(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,bool user_gesture,bool is_redirect)443 bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
444 CefRefPtr<CefFrame> frame,
445 CefRefPtr<CefRequest> request,
446 bool user_gesture,
447 bool is_redirect) override {
448 EXPECT_TRUE(
449 expectations_->OnBeforeBrowse(browser, frame, request->GetURL()))
450 << "nav = " << nav_;
451
452 return false;
453 }
454
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading,bool canGoBack,bool canGoForward)455 void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
456 bool isLoading,
457 bool canGoBack,
458 bool canGoForward) override {
459 EXPECT_TRUE(expectations_->OnLoadingStateChange(browser, isLoading))
460 << "isLoading = " << isLoading << ", nav = " << nav_;
461 ;
462 }
463
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,TransitionType transition_type)464 void OnLoadStart(CefRefPtr<CefBrowser> browser,
465 CefRefPtr<CefFrame> frame,
466 TransitionType transition_type) override {
467 EXPECT_TRUE(expectations_->OnLoadStart(browser, frame)) << "nav = " << nav_;
468 }
469
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int httpStatusCode)470 void OnLoadEnd(CefRefPtr<CefBrowser> browser,
471 CefRefPtr<CefFrame> frame,
472 int httpStatusCode) override {
473 EXPECT_TRUE(expectations_->OnLoadEnd(browser, frame)) << "nav = " << nav_;
474 }
475
OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefProcessId source_process,CefRefPtr<CefProcessMessage> message)476 bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
477 CefRefPtr<CefFrame> frame,
478 CefProcessId source_process,
479 CefRefPtr<CefProcessMessage> message) override {
480 if (message->GetName().ToString() == kFrameNavMsg) {
481 // Test that the renderer side succeeded.
482 CefRefPtr<CefListValue> args = message->GetArgumentList();
483 EXPECT_TRUE(args.get());
484
485 EXPECT_TRUE(expectations_->OnRendererComplete(
486 browser, frame, args->GetInt(0), args->GetBool(1)))
487 << "nav = " << nav_;
488
489 // Test that browser and render process frame IDs match.
490 const int64 frame_id = CefInt64Set(args->GetInt(2), args->GetInt(3));
491 EXPECT_EQ(frame->GetIdentifier(), frame_id);
492
493 return true;
494 }
495
496 // Message not handled.
497 return false;
498 }
499
DestroyTest()500 void DestroyTest() override {
501 if (got_destroyed_)
502 return;
503
504 got_destroyed_.yes();
505
506 // The expectations should have been tested already.
507 EXPECT_FALSE(expectations_.get());
508
509 // Test that factory conditions we met.
510 EXPECT_TRUE(factory_->Finalize()) << "nav = " << nav_;
511
512 TestHandler::DestroyTest();
513 }
514
515 int nav_;
516 TrackCallback got_destroyed_;
517 scoped_ptr<FrameNavExpectationsFactoryBrowser> factory_;
518 scoped_ptr<FrameNavExpectationsBrowser> expectations_;
519
520 IMPLEMENT_REFCOUNTING(FrameNavTestHandler);
521 };
522
523 // Helper for defining frame tests.
524 #define FRAME_TEST(name, factory_id) \
525 TEST(FrameTest, name) { \
526 CefRefPtr<FrameNavTestHandler> handler = \
527 new FrameNavTestHandler(factory_id); \
528 handler->ExecuteTest(); \
529 ReleaseAndWaitForDestructor(handler); \
530 }
531
532 // Browser process expectations for a single navigation.
533 class FrameNavExpectationsBrowserSingleNav
534 : public FrameNavExpectationsBrowser {
535 public:
FrameNavExpectationsBrowserSingleNav(int nav)536 explicit FrameNavExpectationsBrowserSingleNav(int nav)
537 : FrameNavExpectationsBrowser(nav) {}
538
~FrameNavExpectationsBrowserSingleNav()539 ~FrameNavExpectationsBrowserSingleNav() override {
540 EXPECT_TRUE(got_finalize_);
541 }
542
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)543 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
544 bool isLoading) override {
545 if (isLoading) {
546 EXPECT_FALSE(got_loading_state_change_start_);
547 got_loading_state_change_start_.yes();
548 } else {
549 EXPECT_FALSE(got_loading_state_change_end_);
550 got_loading_state_change_end_.yes();
551 SignalCompleteIfDone(browser, browser->GetMainFrame());
552 }
553 return true;
554 }
555
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)556 bool OnLoadStart(CefRefPtr<CefBrowser> browser,
557 CefRefPtr<CefFrame> frame) override {
558 EXPECT_FALSE(got_load_start_);
559 got_load_start_.yes();
560 return true;
561 }
562
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)563 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
564 CefRefPtr<CefFrame> frame) override {
565 EXPECT_FALSE(got_load_end_);
566 got_load_end_.yes();
567 SignalCompleteIfDone(browser, frame);
568 return true;
569 }
570
OnAfterCreated(CefRefPtr<CefBrowser> browser)571 bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
572 EXPECT_FALSE(got_after_created_);
573 got_after_created_.yes();
574 return true;
575 }
576
OnBeforeBrowse(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const std::string & url)577 bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
578 CefRefPtr<CefFrame> frame,
579 const std::string& url) override {
580 EXPECT_FALSE(got_before_browse_);
581 got_before_browse_.yes();
582 return true;
583 }
584
GetResourceHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)585 bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
586 CefRefPtr<CefFrame> frame) override {
587 EXPECT_FALSE(got_get_resource_handler_);
588 got_get_resource_handler_.yes();
589 return true;
590 }
591
OnRendererComplete(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int renderer_nav,bool renderer_result)592 bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
593 CefRefPtr<CefFrame> frame,
594 int renderer_nav,
595 bool renderer_result) override {
596 EXPECT_EQ(nav(), renderer_nav);
597 EXPECT_TRUE(renderer_result);
598 EXPECT_FALSE(got_renderer_done_);
599 got_renderer_done_.yes();
600 SignalCompleteIfDone(browser, frame);
601 return true;
602 }
603
Finalize()604 bool Finalize() override {
605 V_DECLARE();
606 V_EXPECT_TRUE(got_load_start_);
607 V_EXPECT_TRUE(got_load_end_);
608 V_EXPECT_TRUE(got_loading_state_change_start_);
609 V_EXPECT_TRUE(got_loading_state_change_end_);
610 V_EXPECT_TRUE(got_renderer_done_);
611 V_EXPECT_TRUE(got_after_created_);
612 V_EXPECT_TRUE(got_before_browse_);
613 V_EXPECT_TRUE(got_get_resource_handler_);
614 V_EXPECT_FALSE(got_finalize_);
615
616 got_finalize_.yes();
617
618 V_RETURN();
619 }
620
621 private:
SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)622 void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
623 CefRefPtr<CefFrame> frame) {
624 if (got_renderer_done_ && got_load_end_ && got_loading_state_change_end_)
625 SignalComplete(browser, frame);
626 }
627
628 TrackCallback got_load_start_;
629 TrackCallback got_load_end_;
630 TrackCallback got_loading_state_change_start_;
631 TrackCallback got_loading_state_change_end_;
632 TrackCallback got_renderer_done_;
633 TrackCallback got_after_created_;
634 TrackCallback got_before_browse_;
635 TrackCallback got_get_resource_handler_;
636 TrackCallback got_finalize_;
637 };
638
639 // Renderer process expectations for a single navigation.
640 class FrameNavExpectationsRendererSingleNav
641 : public FrameNavExpectationsRenderer {
642 public:
FrameNavExpectationsRendererSingleNav(int nav)643 explicit FrameNavExpectationsRendererSingleNav(int nav)
644 : FrameNavExpectationsRenderer(nav) {}
645
~FrameNavExpectationsRendererSingleNav()646 ~FrameNavExpectationsRendererSingleNav() override {
647 EXPECT_TRUE(got_finalize_);
648 }
649
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)650 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
651 bool isLoading) override {
652 if (isLoading) {
653 EXPECT_FALSE(got_loading_state_change_start_);
654 got_loading_state_change_start_.yes();
655 } else {
656 EXPECT_FALSE(got_loading_state_change_end_);
657 got_loading_state_change_end_.yes();
658 SignalCompleteIfDone(browser, browser->GetMainFrame());
659 }
660 return true;
661 }
662
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)663 bool OnLoadStart(CefRefPtr<CefBrowser> browser,
664 CefRefPtr<CefFrame> frame) override {
665 EXPECT_FALSE(got_load_start_);
666 got_load_start_.yes();
667 return true;
668 }
669
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)670 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
671 CefRefPtr<CefFrame> frame) override {
672 EXPECT_FALSE(got_load_end_);
673 got_load_end_.yes();
674 SignalCompleteIfDone(browser, frame);
675 return true;
676 }
677
Finalize()678 bool Finalize() override {
679 V_DECLARE();
680 V_EXPECT_TRUE(got_load_start_);
681 V_EXPECT_TRUE(got_load_end_);
682 V_EXPECT_TRUE(got_loading_state_change_start_);
683 V_EXPECT_TRUE(got_loading_state_change_end_);
684 V_EXPECT_FALSE(got_finalize_);
685
686 got_finalize_.yes();
687
688 V_RETURN();
689 }
690
691 private:
SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)692 void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
693 CefRefPtr<CefFrame> frame) {
694 if (got_load_end_ && got_loading_state_change_end_)
695 SignalComplete(browser, frame);
696 }
697
698 TrackCallback got_load_start_;
699 TrackCallback got_load_end_;
700 TrackCallback got_loading_state_change_start_;
701 TrackCallback got_loading_state_change_end_;
702 TrackCallback got_finalize_;
703 };
704
705 // Test that the single nav harness works.
706 class FrameNavExpectationsBrowserTestSingleNavHarness
707 : public FrameNavExpectationsBrowserSingleNav {
708 public:
709 typedef FrameNavExpectationsBrowserSingleNav parent;
710
FrameNavExpectationsBrowserTestSingleNavHarness(int nav)711 explicit FrameNavExpectationsBrowserTestSingleNavHarness(int nav)
712 : parent(nav) {}
713
~FrameNavExpectationsBrowserTestSingleNavHarness()714 ~FrameNavExpectationsBrowserTestSingleNavHarness() override {
715 EXPECT_TRUE(got_finalize_);
716 }
717
GetMainURL()718 std::string GetMainURL() override {
719 EXPECT_FALSE(got_get_main_url_);
720 got_get_main_url_.yes();
721 return kFrameNavOrigin0;
722 }
723
GetContentForURL(const std::string & url)724 std::string GetContentForURL(const std::string& url) override {
725 EXPECT_FALSE(got_get_content_for_url_);
726 got_get_content_for_url_.yes();
727 EXPECT_STREQ(kFrameNavOrigin0, url.c_str());
728 return "<html><body>Nav</body></html>";
729 }
730
Finalize()731 bool Finalize() override {
732 EXPECT_FALSE(got_finalize_);
733 got_finalize_.yes();
734
735 V_DECLARE();
736 V_EXPECT_TRUE(got_get_main_url_);
737 V_EXPECT_TRUE(got_get_content_for_url_);
738 V_EXPECT_TRUE(parent::Finalize());
739 V_RETURN();
740 }
741
742 private:
743 TrackCallback got_get_main_url_;
744 TrackCallback got_get_content_for_url_;
745 TrackCallback got_finalize_;
746 };
747
748 class FrameNavExpectationsRendererTestSingleNavHarness
749 : public FrameNavExpectationsRendererSingleNav {
750 public:
751 typedef FrameNavExpectationsRendererSingleNav parent;
752
FrameNavExpectationsRendererTestSingleNavHarness(int nav)753 explicit FrameNavExpectationsRendererTestSingleNavHarness(int nav)
754 : parent(nav) {}
755
~FrameNavExpectationsRendererTestSingleNavHarness()756 ~FrameNavExpectationsRendererTestSingleNavHarness() override {
757 EXPECT_TRUE(got_finalize_);
758 }
759
Finalize()760 bool Finalize() override {
761 EXPECT_FALSE(got_finalize_);
762 got_finalize_.yes();
763 return parent::Finalize();
764 }
765
766 private:
767 TrackCallback got_finalize_;
768 };
769
770 class FrameNavExpectationsFactoryBrowserTestSingleNavHarness
771 : public FrameNavExpectationsFactoryBrowser {
772 public:
FrameNavExpectationsFactoryBrowserTestSingleNavHarness()773 FrameNavExpectationsFactoryBrowserTestSingleNavHarness() {}
774
~FrameNavExpectationsFactoryBrowserTestSingleNavHarness()775 ~FrameNavExpectationsFactoryBrowserTestSingleNavHarness() override {
776 EXPECT_TRUE(got_finalize_);
777 }
778
GetID() const779 FrameNavFactoryId GetID() const override { return FNF_ID_SINGLE_NAV_HARNESS; }
780
HasMoreNavigations() const781 bool HasMoreNavigations() const override {
782 EXPECT_FALSE(got_get_browser_navigation_count_);
783 got_get_browser_navigation_count_.yes();
784 return false;
785 }
786
Finalize()787 bool Finalize() override {
788 EXPECT_FALSE(got_finalize_);
789 got_finalize_.yes();
790
791 V_DECLARE();
792 V_EXPECT_TRUE(got_get_browser_navigation_count_);
793 V_EXPECT_TRUE(got_create_);
794 V_RETURN();
795 }
796
797 protected:
Create(int nav)798 scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
799 EXPECT_FALSE(got_create_);
800 got_create_.yes();
801 return scoped_ptr<FrameNavExpectationsBrowser>(
802 new FrameNavExpectationsBrowserTestSingleNavHarness(nav));
803 }
804
805 private:
806 mutable TrackCallback got_get_browser_navigation_count_;
807 TrackCallback got_create_;
808 TrackCallback got_finalize_;
809 };
810
811 class FrameNavExpectationsFactoryRendererTestSingleNavHarness
812 : public FrameNavExpectationsFactoryRenderer {
813 public:
FrameNavExpectationsFactoryRendererTestSingleNavHarness()814 FrameNavExpectationsFactoryRendererTestSingleNavHarness() {}
815
GetID() const816 FrameNavFactoryId GetID() const override { return FNF_ID_SINGLE_NAV_HARNESS; }
817
818 protected:
Create(int nav)819 scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
820 return scoped_ptr<FrameNavExpectationsRenderer>(
821 new FrameNavExpectationsRendererTestSingleNavHarness(nav));
822 }
823 };
824
825 } // namespace
826
827 // Test that the single nav harness works.
828 FRAME_TEST(SingleNavHarness, FNF_ID_SINGLE_NAV_HARNESS)
829
830 namespace {
831
VerifySingleBrowserFrame(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const std::string & expected_url)832 bool VerifySingleBrowserFrame(CefRefPtr<CefBrowser> browser,
833 CefRefPtr<CefFrame> frame,
834 const std::string& expected_url) {
835 V_DECLARE();
836 V_EXPECT_TRUE(frame.get());
837 V_EXPECT_TRUE(frame->IsValid());
838 const int64 frame_id = frame->GetIdentifier();
839 V_EXPECT_TRUE(frame_id > 0) << frame_id;
840 V_EXPECT_TRUE(frame->IsValid());
841 V_EXPECT_TRUE(frame->IsMain());
842 V_EXPECT_TRUE(frame->IsFocused());
843 V_EXPECT_FALSE(frame->GetParent().get());
844 V_EXPECT_TRUE(frame->GetName().empty());
845 V_EXPECT_TRUE(browser->GetIdentifier() ==
846 frame->GetBrowser()->GetIdentifier());
847
848 const std::string& frame_url = frame->GetURL();
849 V_EXPECT_TRUE(frame_url == expected_url)
850 << "frame_url = " << frame_url << ", expected_url = " << expected_url;
851
852 V_RETURN();
853 }
854
VerifySingleBrowserFrames(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const std::string & expected_url)855 bool VerifySingleBrowserFrames(CefRefPtr<CefBrowser> browser,
856 CefRefPtr<CefFrame> frame,
857 const std::string& expected_url) {
858 V_DECLARE();
859 V_EXPECT_TRUE(browser.get());
860
861 // |frame| may be nullptr for callbacks that don't specify one.
862 if (frame.get()) {
863 V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, frame, expected_url));
864 }
865
866 CefRefPtr<CefFrame> main_frame = browser->GetMainFrame();
867 V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, main_frame, expected_url));
868
869 CefRefPtr<CefFrame> focused_frame = browser->GetFocusedFrame();
870 V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, focused_frame, expected_url));
871
872 size_t frame_count = browser->GetFrameCount();
873 V_EXPECT_TRUE(frame_count == 1U);
874
875 std::vector<int64> identifiers;
876 browser->GetFrameIdentifiers(identifiers);
877 V_EXPECT_TRUE(identifiers.size() == 1U);
878 if (identifiers.size() == 1U) {
879 V_EXPECT_TRUE(identifiers[0] == main_frame->GetIdentifier());
880 V_EXPECT_TRUE(identifiers[0] == focused_frame->GetIdentifier());
881 }
882
883 // Names may be empty for callbacks that execute while the frame is loading.
884 std::vector<CefString> names;
885 browser->GetFrameNames(names);
886 V_EXPECT_TRUE(names.size() <= 1U);
887 if (names.size() == 1U) {
888 V_EXPECT_TRUE(names[0].ToString() == main_frame->GetName().ToString());
889 V_EXPECT_TRUE(names[0].ToString() == focused_frame->GetName().ToString());
890 }
891
892 V_RETURN();
893 }
894
895 // Test that single navigation works.
896 class FrameNavExpectationsBrowserTestSingleNav
897 : public FrameNavExpectationsBrowserSingleNav {
898 public:
899 typedef FrameNavExpectationsBrowserSingleNav parent;
900
FrameNavExpectationsBrowserTestSingleNav(int nav)901 explicit FrameNavExpectationsBrowserTestSingleNav(int nav) : parent(nav) {}
902
GetMainURL()903 std::string GetMainURL() override { return kFrameNavOrigin0; }
904
GetContentForURL(const std::string & url)905 std::string GetContentForURL(const std::string& url) override {
906 return "<html><body>Nav</body></html>";
907 }
908
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)909 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
910 bool isLoading) override {
911 V_DECLARE();
912 V_EXPECT_TRUE(VerifySingleBrowserFrames(
913 browser, nullptr, isLoading ? std::string() : kFrameNavOrigin0));
914 V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
915 V_RETURN();
916 }
917
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)918 bool OnLoadStart(CefRefPtr<CefBrowser> browser,
919 CefRefPtr<CefFrame> frame) override {
920 V_DECLARE();
921 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, kFrameNavOrigin0));
922 V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
923 V_RETURN();
924 }
925
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)926 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
927 CefRefPtr<CefFrame> frame) override {
928 V_DECLARE();
929 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, kFrameNavOrigin0));
930 V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
931 V_RETURN();
932 }
933
OnAfterCreated(CefRefPtr<CefBrowser> browser)934 bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
935 V_DECLARE();
936 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, std::string()));
937 V_EXPECT_TRUE(parent::OnAfterCreated(browser));
938 V_RETURN();
939 }
940
OnBeforeBrowse(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const std::string & url)941 bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
942 CefRefPtr<CefFrame> frame,
943 const std::string& url) override {
944 V_DECLARE();
945 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, std::string()));
946 V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
947 V_RETURN();
948 }
949
GetResourceHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)950 bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
951 CefRefPtr<CefFrame> frame) override {
952 V_DECLARE();
953 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, std::string()));
954 V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
955 V_RETURN();
956 }
957
OnRendererComplete(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int renderer_nav,bool renderer_result)958 bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
959 CefRefPtr<CefFrame> frame,
960 int renderer_nav,
961 bool renderer_result) override {
962 return parent::OnRendererComplete(browser, frame, renderer_nav,
963 renderer_result);
964 }
965
Finalize()966 bool Finalize() override { return parent::Finalize(); }
967 };
968
969 class FrameNavExpectationsRendererTestSingleNav
970 : public FrameNavExpectationsRendererSingleNav {
971 public:
972 typedef FrameNavExpectationsRendererSingleNav parent;
973
FrameNavExpectationsRendererTestSingleNav(int nav)974 explicit FrameNavExpectationsRendererTestSingleNav(int nav) : parent(nav) {}
975
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)976 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
977 bool isLoading) override {
978 V_DECLARE();
979 // A frame should always exist in the renderer process.
980 V_EXPECT_TRUE(
981 VerifySingleBrowserFrames(browser, nullptr, kFrameNavOrigin0));
982 V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
983 V_RETURN();
984 }
985
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)986 bool OnLoadStart(CefRefPtr<CefBrowser> browser,
987 CefRefPtr<CefFrame> frame) override {
988 V_DECLARE();
989 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, kFrameNavOrigin0));
990 V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
991 V_RETURN();
992 }
993
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)994 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
995 CefRefPtr<CefFrame> frame) override {
996 V_DECLARE();
997 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, kFrameNavOrigin0));
998 V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
999 V_RETURN();
1000 }
1001
Finalize()1002 bool Finalize() override { return parent::Finalize(); }
1003 };
1004
1005 class FrameNavExpectationsFactoryBrowserTestSingleNav
1006 : public FrameNavExpectationsFactoryBrowser {
1007 public:
FrameNavExpectationsFactoryBrowserTestSingleNav()1008 FrameNavExpectationsFactoryBrowserTestSingleNav() {}
1009
GetID() const1010 FrameNavFactoryId GetID() const override { return FNF_ID_SINGLE_NAV; }
1011
HasMoreNavigations() const1012 bool HasMoreNavigations() const override { return false; }
1013
Finalize()1014 bool Finalize() override { return true; }
1015
1016 protected:
Create(int nav)1017 scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
1018 return scoped_ptr<FrameNavExpectationsBrowser>(
1019 new FrameNavExpectationsBrowserTestSingleNav(nav));
1020 }
1021 };
1022
1023 class FrameNavExpectationsFactoryRendererTestSingleNav
1024 : public FrameNavExpectationsFactoryRenderer {
1025 public:
FrameNavExpectationsFactoryRendererTestSingleNav()1026 FrameNavExpectationsFactoryRendererTestSingleNav() {}
1027
GetID() const1028 FrameNavFactoryId GetID() const override { return FNF_ID_SINGLE_NAV; }
1029
1030 protected:
Create(int nav)1031 scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
1032 return scoped_ptr<FrameNavExpectationsRenderer>(
1033 new FrameNavExpectationsRendererTestSingleNav(nav));
1034 }
1035 };
1036
1037 } // namespace
1038
1039 // Test that single navigation works.
1040 FRAME_TEST(SingleNav, FNF_ID_SINGLE_NAV)
1041
1042 namespace {
1043
1044 // Browser process expectations for a multiple navigations.
1045 class FrameNavExpectationsBrowserMultiNav : public FrameNavExpectationsBrowser {
1046 public:
FrameNavExpectationsBrowserMultiNav(int nav)1047 explicit FrameNavExpectationsBrowserMultiNav(int nav)
1048 : FrameNavExpectationsBrowser(nav) {}
1049
~FrameNavExpectationsBrowserMultiNav()1050 ~FrameNavExpectationsBrowserMultiNav() override {
1051 EXPECT_TRUE(got_finalize_);
1052 }
1053
1054 // Returns true if all navigation is done.
1055 virtual bool IsNavigationDone() const = 0;
1056
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)1057 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
1058 bool isLoading) override {
1059 if (!isLoading)
1060 SignalCompleteIfDone(browser, browser->GetMainFrame());
1061 return true;
1062 }
1063
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1064 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
1065 CefRefPtr<CefFrame> frame) override {
1066 SignalCompleteIfDone(browser, frame);
1067 return true;
1068 }
1069
OnRendererComplete(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int renderer_nav,bool renderer_result)1070 bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
1071 CefRefPtr<CefFrame> frame,
1072 int renderer_nav,
1073 bool renderer_result) override {
1074 EXPECT_TRUE(renderer_result);
1075 SignalCompleteIfDone(browser, frame);
1076 return true;
1077 }
1078
Finalize()1079 bool Finalize() override {
1080 V_DECLARE();
1081 V_EXPECT_FALSE(got_finalize_);
1082
1083 got_finalize_.yes();
1084
1085 V_RETURN();
1086 }
1087
1088 private:
SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1089 void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
1090 CefRefPtr<CefFrame> frame) {
1091 if (IsNavigationDone())
1092 SignalComplete(browser, frame);
1093 }
1094
1095 TrackCallback got_finalize_;
1096 };
1097
1098 // Renderer process expectations for a multiple navigations.
1099 class FrameNavExpectationsRendererMultiNav
1100 : public FrameNavExpectationsRenderer {
1101 public:
FrameNavExpectationsRendererMultiNav(int nav)1102 explicit FrameNavExpectationsRendererMultiNav(int nav)
1103 : FrameNavExpectationsRenderer(nav) {}
1104
~FrameNavExpectationsRendererMultiNav()1105 ~FrameNavExpectationsRendererMultiNav() override {
1106 EXPECT_TRUE(got_finalize_);
1107 }
1108
1109 // Returns true if all navigation is done.
1110 virtual bool IsNavigationDone() const = 0;
1111
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)1112 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
1113 bool isLoading) override {
1114 if (!isLoading)
1115 SignalCompleteIfDone(browser, browser->GetMainFrame());
1116 return true;
1117 }
1118
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1119 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
1120 CefRefPtr<CefFrame> frame) override {
1121 SignalCompleteIfDone(browser, frame);
1122 return true;
1123 }
1124
Finalize()1125 bool Finalize() override {
1126 V_DECLARE();
1127 V_EXPECT_FALSE(got_finalize_);
1128
1129 got_finalize_.yes();
1130
1131 V_RETURN();
1132 }
1133
1134 private:
SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1135 void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
1136 CefRefPtr<CefFrame> frame) {
1137 if (IsNavigationDone())
1138 SignalComplete(browser, frame);
1139 }
1140
1141 TrackCallback got_finalize_;
1142 };
1143
1144 // Create a URL containing the nav number.
GetMultiNavURL(const std::string & origin,int nav)1145 std::string GetMultiNavURL(const std::string& origin, int nav) {
1146 std::stringstream ss;
1147 ss << origin << "nav" << nav << ".html";
1148 return ss.str();
1149 }
1150
1151 // Extract the nav number from the URL.
GetNavFromMultiNavURL(const std::string & url)1152 int GetNavFromMultiNavURL(const std::string& url) {
1153 const size_t start = url.find("/nav");
1154 const size_t end = url.find(".html", start);
1155 EXPECT_TRUE(start < end && start > 0U);
1156 const std::string& nav = url.substr(start + 4, end - start - 4);
1157 return atoi(nav.c_str());
1158 }
1159
1160 // Extract the origin from the URL.
GetOriginFromMultiNavURL(const std::string & url)1161 std::string GetOriginFromMultiNavURL(const std::string& url) {
1162 const size_t pos = url.rfind("/");
1163 EXPECT_TRUE(pos > 0U);
1164 return url.substr(0, pos + 1);
1165 }
1166
1167 // Test that the multi nav harness works.
1168 class FrameNavExpectationsBrowserTestMultiNavHarness
1169 : public FrameNavExpectationsBrowserMultiNav {
1170 public:
1171 typedef FrameNavExpectationsBrowserMultiNav parent;
1172
FrameNavExpectationsBrowserTestMultiNavHarness(int nav)1173 explicit FrameNavExpectationsBrowserTestMultiNavHarness(int nav)
1174 : parent(nav), navigation_done_count_(0) {}
1175
~FrameNavExpectationsBrowserTestMultiNavHarness()1176 ~FrameNavExpectationsBrowserTestMultiNavHarness() override {
1177 EXPECT_TRUE(got_finalize_);
1178 }
1179
GetMainURL()1180 std::string GetMainURL() override {
1181 EXPECT_FALSE(got_get_main_url_);
1182 got_get_main_url_.yes();
1183 return GetMultiNavURL(kFrameNavOrigin0, nav());
1184 }
1185
GetContentForURL(const std::string & url)1186 std::string GetContentForURL(const std::string& url) override {
1187 EXPECT_FALSE(got_get_content_for_url_);
1188 got_get_content_for_url_.yes();
1189 EXPECT_STREQ(GetMultiNavURL(kFrameNavOrigin0, nav()).c_str(), url.c_str());
1190 return "<html><body>Nav</body></html>";
1191 }
1192
IsNavigationDone() const1193 bool IsNavigationDone() const override {
1194 navigation_done_count_++;
1195 return got_load_state_change_done_ && got_load_end_ &&
1196 got_renderer_complete_;
1197 }
1198
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)1199 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
1200 bool isLoading) override {
1201 if (!isLoading) {
1202 EXPECT_FALSE(got_load_state_change_done_);
1203 got_load_state_change_done_.yes();
1204 }
1205 return parent::OnLoadingStateChange(browser, isLoading);
1206 }
1207
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1208 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
1209 CefRefPtr<CefFrame> frame) override {
1210 EXPECT_FALSE(got_load_end_);
1211 got_load_end_.yes();
1212 return parent::OnLoadEnd(browser, frame);
1213 }
1214
OnAfterCreated(CefRefPtr<CefBrowser> browser)1215 bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
1216 EXPECT_FALSE(got_on_after_created_);
1217 got_on_after_created_.yes();
1218 return parent::OnAfterCreated(browser);
1219 }
1220
OnRendererComplete(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int renderer_nav,bool renderer_result)1221 bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
1222 CefRefPtr<CefFrame> frame,
1223 int renderer_nav,
1224 bool renderer_result) override {
1225 EXPECT_FALSE(got_renderer_complete_);
1226 got_renderer_complete_.yes();
1227 EXPECT_EQ(nav(), renderer_nav);
1228 return parent::OnRendererComplete(browser, frame, renderer_nav,
1229 renderer_result);
1230 }
1231
Finalize()1232 bool Finalize() override {
1233 EXPECT_FALSE(got_finalize_);
1234 got_finalize_.yes();
1235
1236 V_DECLARE();
1237 V_EXPECT_TRUE(got_get_main_url_);
1238 V_EXPECT_TRUE(got_get_content_for_url_);
1239 V_EXPECT_TRUE(got_load_state_change_done_);
1240 V_EXPECT_TRUE(got_load_end_);
1241 if (nav() == 0) {
1242 V_EXPECT_TRUE(got_on_after_created_);
1243 } else {
1244 V_EXPECT_FALSE(got_on_after_created_);
1245 }
1246 V_EXPECT_TRUE(got_renderer_complete_);
1247 V_EXPECT_TRUE(navigation_done_count_ == 3);
1248 V_EXPECT_TRUE(parent::Finalize());
1249 V_RETURN();
1250 }
1251
1252 private:
1253 TrackCallback got_get_main_url_;
1254 TrackCallback got_get_content_for_url_;
1255 TrackCallback got_load_state_change_done_;
1256 TrackCallback got_load_end_;
1257 TrackCallback got_on_after_created_;
1258 TrackCallback got_renderer_complete_;
1259 mutable int navigation_done_count_;
1260 TrackCallback got_finalize_;
1261 };
1262
1263 class FrameNavExpectationsRendererTestMultiNavHarness
1264 : public FrameNavExpectationsRendererMultiNav {
1265 public:
1266 typedef FrameNavExpectationsRendererMultiNav parent;
1267
FrameNavExpectationsRendererTestMultiNavHarness(int nav)1268 explicit FrameNavExpectationsRendererTestMultiNavHarness(int nav)
1269 : parent(nav), navigation_done_count_(0) {}
1270
~FrameNavExpectationsRendererTestMultiNavHarness()1271 ~FrameNavExpectationsRendererTestMultiNavHarness() override {
1272 EXPECT_TRUE(got_finalize_);
1273 }
1274
IsNavigationDone() const1275 bool IsNavigationDone() const override {
1276 navigation_done_count_++;
1277 return got_load_state_change_done_ && got_load_end_;
1278 }
1279
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)1280 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
1281 bool isLoading) override {
1282 if (!isLoading) {
1283 EXPECT_FALSE(got_load_state_change_done_);
1284 got_load_state_change_done_.yes();
1285 }
1286 return parent::OnLoadingStateChange(browser, isLoading);
1287 }
1288
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1289 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
1290 CefRefPtr<CefFrame> frame) override {
1291 EXPECT_FALSE(got_load_end_);
1292 got_load_end_.yes();
1293 return parent::OnLoadEnd(browser, frame);
1294 }
1295
Finalize()1296 bool Finalize() override {
1297 EXPECT_FALSE(got_finalize_);
1298 got_finalize_.yes();
1299
1300 V_DECLARE();
1301 V_EXPECT_TRUE(got_load_state_change_done_);
1302 V_EXPECT_TRUE(got_load_end_);
1303 V_EXPECT_TRUE(navigation_done_count_ == 2);
1304 V_EXPECT_TRUE(parent::Finalize());
1305 V_RETURN();
1306 }
1307
1308 private:
1309 TrackCallback got_load_state_change_done_;
1310 TrackCallback got_load_end_;
1311 mutable int navigation_done_count_;
1312 TrackCallback got_finalize_;
1313 };
1314
1315 class FrameNavExpectationsFactoryBrowserTestMultiNavHarness
1316 : public FrameNavExpectationsFactoryBrowser {
1317 public:
FrameNavExpectationsFactoryBrowserTestMultiNavHarness()1318 FrameNavExpectationsFactoryBrowserTestMultiNavHarness()
1319 : get_browser_navigation_count_(0), create_count_(0) {}
1320
~FrameNavExpectationsFactoryBrowserTestMultiNavHarness()1321 ~FrameNavExpectationsFactoryBrowserTestMultiNavHarness() override {
1322 EXPECT_TRUE(got_finalize_);
1323 }
1324
GetID() const1325 FrameNavFactoryId GetID() const override { return FNF_ID_MULTI_NAV_HARNESS; }
1326
HasMoreNavigations() const1327 bool HasMoreNavigations() const override {
1328 get_browser_navigation_count_++;
1329 return (get_browser_navigation_count_ < kMaxMultiNavNavigations);
1330 }
1331
Finalize()1332 bool Finalize() override {
1333 EXPECT_FALSE(got_finalize_);
1334 got_finalize_.yes();
1335
1336 V_DECLARE();
1337 V_EXPECT_TRUE(get_browser_navigation_count_ == kMaxMultiNavNavigations);
1338 V_EXPECT_TRUE(create_count_ == kMaxMultiNavNavigations);
1339 V_RETURN();
1340 }
1341
1342 protected:
Create(int nav)1343 scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
1344 create_count_++;
1345 return scoped_ptr<FrameNavExpectationsBrowser>(
1346 new FrameNavExpectationsBrowserTestMultiNavHarness(nav));
1347 }
1348
1349 private:
1350 mutable int get_browser_navigation_count_;
1351 int create_count_;
1352 TrackCallback got_finalize_;
1353 };
1354
1355 class FrameNavExpectationsFactoryRendererTestMultiNavHarness
1356 : public FrameNavExpectationsFactoryRenderer {
1357 public:
FrameNavExpectationsFactoryRendererTestMultiNavHarness()1358 FrameNavExpectationsFactoryRendererTestMultiNavHarness() {}
1359
GetID() const1360 FrameNavFactoryId GetID() const override { return FNF_ID_MULTI_NAV_HARNESS; }
1361
1362 protected:
Create(int nav)1363 scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
1364 return scoped_ptr<FrameNavExpectationsRenderer>(
1365 new FrameNavExpectationsRendererTestMultiNavHarness(nav));
1366 }
1367 };
1368
1369 } // namespace
1370
1371 // Test that the multiple nav harness works.
1372 FRAME_TEST(MultiNavHarness, FNF_ID_MULTI_NAV_HARNESS)
1373
1374 namespace {
1375
1376 // Test that multiple navigation works.
1377 class FrameNavExpectationsBrowserTestMultiNav
1378 : public FrameNavExpectationsBrowserMultiNav {
1379 public:
1380 typedef FrameNavExpectationsBrowserMultiNav parent;
1381
FrameNavExpectationsBrowserTestMultiNav(int nav)1382 explicit FrameNavExpectationsBrowserTestMultiNav(int nav) : parent(nav) {}
1383
GetMainURL()1384 std::string GetMainURL() override {
1385 return GetMultiNavURL(kFrameNavOrigin0, nav());
1386 }
1387
GetContentForURL(const std::string & url)1388 std::string GetContentForURL(const std::string& url) override {
1389 return "<html><body>Nav</body></html>";
1390 }
1391
IsNavigationDone() const1392 bool IsNavigationDone() const override {
1393 return got_load_state_change_done_ && got_load_end_ &&
1394 got_renderer_complete_;
1395 }
1396
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)1397 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
1398 bool isLoading) override {
1399 if (!isLoading)
1400 got_load_state_change_done_.yes();
1401 V_DECLARE();
1402 if (isLoading && nav() == 0) {
1403 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, std::string()));
1404 } else if (isLoading) {
1405 // Expect the URL from the previous load.
1406 V_EXPECT_TRUE(
1407 VerifySingleBrowserFrames(browser, nullptr, GetPreviousMainURL()));
1408 } else {
1409 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, GetMainURL()));
1410 }
1411 V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
1412 V_RETURN();
1413 }
1414
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1415 bool OnLoadStart(CefRefPtr<CefBrowser> browser,
1416 CefRefPtr<CefFrame> frame) override {
1417 V_DECLARE();
1418 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, GetMainURL()));
1419 V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
1420 V_RETURN();
1421 }
1422
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1423 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
1424 CefRefPtr<CefFrame> frame) override {
1425 got_load_end_.yes();
1426 V_DECLARE();
1427 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, GetMainURL()));
1428 V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
1429 V_RETURN();
1430 }
1431
OnAfterCreated(CefRefPtr<CefBrowser> browser)1432 bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
1433 V_DECLARE();
1434 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, std::string()));
1435 V_EXPECT_TRUE(parent::OnAfterCreated(browser));
1436 V_RETURN();
1437 }
1438
OnBeforeBrowse(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const std::string & url)1439 bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
1440 CefRefPtr<CefFrame> frame,
1441 const std::string& url) override {
1442 V_DECLARE();
1443 std::string expected_url;
1444 if (nav() > 0)
1445 expected_url = GetPreviousMainURL();
1446 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, expected_url));
1447 V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
1448 V_RETURN();
1449 }
1450
GetResourceHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1451 bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
1452 CefRefPtr<CefFrame> frame) override {
1453 V_DECLARE();
1454 std::string expected_url;
1455 if (nav() > 0)
1456 expected_url = GetPreviousMainURL();
1457 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, expected_url));
1458 V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
1459 V_RETURN();
1460 }
1461
OnRendererComplete(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int renderer_nav,bool renderer_result)1462 bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
1463 CefRefPtr<CefFrame> frame,
1464 int renderer_nav,
1465 bool renderer_result) override {
1466 got_renderer_complete_.yes();
1467 V_DECLARE();
1468 V_EXPECT_TRUE(nav() == renderer_nav);
1469 V_EXPECT_TRUE(parent::OnRendererComplete(browser, frame, renderer_nav,
1470 renderer_result));
1471 V_RETURN();
1472 }
1473
Finalize()1474 bool Finalize() override {
1475 V_DECLARE();
1476 V_EXPECT_TRUE(got_load_state_change_done_);
1477 V_EXPECT_TRUE(got_load_end_);
1478 V_EXPECT_TRUE(got_renderer_complete_);
1479 V_EXPECT_TRUE(parent::Finalize());
1480 V_RETURN();
1481 }
1482
1483 private:
1484 // Helper for VerifySingleBrowserFrames.
GetPreviousMainURL()1485 std::string GetPreviousMainURL() {
1486 EXPECT_GT(nav(), 0);
1487 return GetMultiNavURL(kFrameNavOrigin0, nav() - 1);
1488 }
1489
1490 TrackCallback got_load_state_change_done_;
1491 TrackCallback got_load_end_;
1492 TrackCallback got_renderer_complete_;
1493 };
1494
1495 class FrameNavExpectationsRendererTestMultiNav
1496 : public FrameNavExpectationsRendererMultiNav {
1497 public:
1498 typedef FrameNavExpectationsRendererMultiNav parent;
1499
FrameNavExpectationsRendererTestMultiNav(int nav)1500 explicit FrameNavExpectationsRendererTestMultiNav(int nav) : parent(nav) {}
1501
IsNavigationDone() const1502 bool IsNavigationDone() const override {
1503 return got_load_state_change_done_ && got_load_end_;
1504 }
1505
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)1506 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
1507 bool isLoading) override {
1508 if (!isLoading)
1509 got_load_state_change_done_.yes();
1510 V_DECLARE();
1511 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, nullptr, GetMainURL()));
1512 V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
1513 V_RETURN();
1514 }
1515
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1516 bool OnLoadStart(CefRefPtr<CefBrowser> browser,
1517 CefRefPtr<CefFrame> frame) override {
1518 V_DECLARE();
1519 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, GetMainURL()));
1520 V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
1521 V_RETURN();
1522 }
1523
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1524 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
1525 CefRefPtr<CefFrame> frame) override {
1526 got_load_end_.yes();
1527 V_DECLARE();
1528 V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, GetMainURL()));
1529 V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
1530 V_RETURN();
1531 }
1532
Finalize()1533 bool Finalize() override {
1534 V_DECLARE();
1535 V_EXPECT_TRUE(got_load_state_change_done_);
1536 V_EXPECT_TRUE(got_load_end_);
1537 V_EXPECT_TRUE(parent::Finalize());
1538 V_RETURN();
1539 }
1540
1541 private:
1542 // Helpers for calling VerifySingleBrowserFrames.
GetMainURL() const1543 std::string GetMainURL() const {
1544 return GetMultiNavURL(kFrameNavOrigin0, nav());
1545 }
GetPreviousMainURL()1546 std::string GetPreviousMainURL() {
1547 EXPECT_GT(nav(), 0);
1548 return GetMultiNavURL(kFrameNavOrigin0, nav() - 1);
1549 }
1550
1551 TrackCallback got_load_state_change_done_;
1552 TrackCallback got_load_end_;
1553 };
1554
1555 class FrameNavExpectationsFactoryBrowserTestMultiNav
1556 : public FrameNavExpectationsFactoryBrowser {
1557 public:
FrameNavExpectationsFactoryBrowserTestMultiNav()1558 FrameNavExpectationsFactoryBrowserTestMultiNav() : nav_count_(0) {}
1559
GetID() const1560 FrameNavFactoryId GetID() const override { return FNF_ID_MULTI_NAV; }
1561
HasMoreNavigations() const1562 bool HasMoreNavigations() const override {
1563 return (nav_count_ < kMaxMultiNavNavigations);
1564 }
1565
Finalize()1566 bool Finalize() override {
1567 V_DECLARE();
1568 V_EXPECT_TRUE(nav_count_ == kMaxMultiNavNavigations);
1569 V_RETURN();
1570 }
1571
1572 protected:
Create(int nav)1573 scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
1574 nav_count_++;
1575 return scoped_ptr<FrameNavExpectationsBrowser>(
1576 new FrameNavExpectationsBrowserTestMultiNav(nav));
1577 }
1578
1579 private:
1580 int nav_count_;
1581 };
1582
1583 class FrameNavExpectationsFactoryRendererTestMultiNav
1584 : public FrameNavExpectationsFactoryRenderer {
1585 public:
FrameNavExpectationsFactoryRendererTestMultiNav()1586 FrameNavExpectationsFactoryRendererTestMultiNav() {}
1587
GetID() const1588 FrameNavFactoryId GetID() const override { return FNF_ID_MULTI_NAV; }
1589
1590 protected:
Create(int nav)1591 scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
1592 return scoped_ptr<FrameNavExpectationsRenderer>(
1593 new FrameNavExpectationsRendererTestMultiNav(nav));
1594 }
1595 };
1596
1597 } // namespace
1598
1599 // Test that multiple navigation works.
1600 FRAME_TEST(MultiNav, FNF_ID_MULTI_NAV)
1601
1602 namespace {
1603
1604 const char kFrame0Name[] = "";
1605 const char kFrame1Name[] = "nav2";
1606 const char kFrame2Name[] = "<!--framePath //nav2/<!--frame0-->-->";
1607 const char kFrame3Name[] = "nav3";
1608
VerifyBrowserIframe(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const std::string & origin,int frame_number)1609 bool VerifyBrowserIframe(CefRefPtr<CefBrowser> browser,
1610 CefRefPtr<CefFrame> frame,
1611 const std::string& origin,
1612 int frame_number) {
1613 V_DECLARE();
1614
1615 // frame0 contains frame1 contains frame2, contains frame3.
1616 CefRefPtr<CefFrame> frame0, frame1, frame2, frame3;
1617 CefRefPtr<CefFrame> frame0b, frame1b, frame2b, frame3b;
1618 int64 frame0id, frame1id, frame2id, frame3id;
1619 std::string frame0url, frame1url, frame2url, frame3url;
1620
1621 // Verify the GetFrameNames result.
1622 std::set<std::string> expected_names = {kFrame0Name, kFrame1Name, kFrame2Name,
1623 kFrame3Name};
1624
1625 std::vector<CefString> names;
1626 browser->GetFrameNames(names);
1627 V_EXPECT_TRUE(names.size() == expected_names.size())
1628 << "expected: " << expected_names.size() << " actual: " << names.size();
1629
1630 for (const auto& name : names) {
1631 const std::string& nameStr = name;
1632 auto it = expected_names.find(nameStr);
1633 V_EXPECT_FALSE(it == expected_names.end())
1634 << "Unexpected name: \"" << nameStr << "\"";
1635 if (it != expected_names.end())
1636 expected_names.erase(it);
1637 }
1638
1639 for (const auto& name : expected_names) {
1640 V_EXPECT_FALSE(true) << "Missing name: \"" << name << "\"";
1641 }
1642
1643 // Find frames by name.
1644 frame0 = browser->GetFrame(kFrame0Name);
1645 V_EXPECT_TRUE(frame0.get());
1646 frame1 = browser->GetFrame(kFrame1Name);
1647 V_EXPECT_TRUE(frame1.get());
1648 frame2 = browser->GetFrame(kFrame2Name);
1649 V_EXPECT_TRUE(frame2.get());
1650 frame3 = browser->GetFrame(kFrame3Name);
1651 V_EXPECT_TRUE(frame3.get());
1652
1653 if (!frame0 || !frame1 || !frame2 || !frame3) {
1654 V_RETURN();
1655 }
1656
1657 // Verify that the name matches.
1658 V_EXPECT_TRUE(frame0->GetName().ToString() == kFrame0Name)
1659 << "expected: " << kFrame0Name
1660 << " actual: " << frame0->GetName().ToString();
1661 V_EXPECT_TRUE(frame1->GetName().ToString() == kFrame1Name)
1662 << "expected: " << kFrame1Name
1663 << " actual: " << frame1->GetName().ToString();
1664 V_EXPECT_TRUE(frame2->GetName().ToString() == kFrame2Name)
1665 << "expected: " << kFrame2Name
1666 << " actual: " << frame2->GetName().ToString();
1667 V_EXPECT_TRUE(frame3->GetName().ToString() == kFrame3Name)
1668 << "expected: " << kFrame3Name
1669 << " actual: " << frame3->GetName().ToString();
1670
1671 // Verify that the URL matches.
1672 frame0url = GetMultiNavURL(origin, 0);
1673 V_EXPECT_TRUE(frame0->GetURL() == frame0url)
1674 << "expected: " << frame0url
1675 << " actual: " << frame0->GetURL().ToString();
1676 frame1url = GetMultiNavURL(origin, 1);
1677 V_EXPECT_TRUE(frame1->GetURL() == frame1url)
1678 << "expected: " << frame1url
1679 << " actual: " << frame1->GetURL().ToString();
1680 frame2url = GetMultiNavURL(origin, 2);
1681 V_EXPECT_TRUE(frame2->GetURL() == frame2url)
1682 << "expected: " << frame2url
1683 << " actual: " << frame2->GetURL().ToString();
1684 frame3url = GetMultiNavURL(origin, 3);
1685 V_EXPECT_TRUE(frame3->GetURL() == frame3url)
1686 << "expected: " << frame3url
1687 << " actual: " << frame3->GetURL().ToString();
1688
1689 // Verify that the frame id is valid.
1690 frame0id = frame0->GetIdentifier();
1691 V_EXPECT_TRUE(frame0id > 0) << "actual: " << frame0id;
1692 frame1id = frame1->GetIdentifier();
1693 V_EXPECT_TRUE(frame1id > 0) << "actual: " << frame1id;
1694 frame2id = frame2->GetIdentifier();
1695 V_EXPECT_TRUE(frame2id > 0) << "actual: " << frame2id;
1696 frame3id = frame3->GetIdentifier();
1697 V_EXPECT_TRUE(frame3id > 0) << "actual: " << frame3id;
1698
1699 // Verify that the current frame has the correct id.
1700 if (frame_number == 0) {
1701 V_EXPECT_TRUE(frame->GetIdentifier() == frame0id)
1702 << "expected: " << frame0id << " actual: " << frame->GetIdentifier();
1703 } else if (frame_number == 1) {
1704 V_EXPECT_TRUE(frame->GetIdentifier() == frame1id)
1705 << "expected: " << frame1id << " actual: " << frame->GetIdentifier();
1706 } else if (frame_number == 2) {
1707 V_EXPECT_TRUE(frame->GetIdentifier() == frame2id)
1708 << "expected: " << frame2id << " actual: " << frame->GetIdentifier();
1709 } else if (frame_number == 3) {
1710 V_EXPECT_TRUE(frame->GetIdentifier() == frame3id)
1711 << "expected: " << frame3id << " actual: " << frame->GetIdentifier();
1712 }
1713
1714 // Find frames by id.
1715 frame0b = browser->GetFrame(frame0->GetIdentifier());
1716 V_EXPECT_TRUE(frame0b.get());
1717 frame1b = browser->GetFrame(frame1->GetIdentifier());
1718 V_EXPECT_TRUE(frame1b.get());
1719 frame2b = browser->GetFrame(frame2->GetIdentifier());
1720 V_EXPECT_TRUE(frame2b.get());
1721 frame3b = browser->GetFrame(frame3->GetIdentifier());
1722 V_EXPECT_TRUE(frame3b.get());
1723
1724 if (!frame0b || !frame1b || !frame2b || !frame3b) {
1725 V_RETURN();
1726 }
1727
1728 // Verify that the id matches.
1729 V_EXPECT_TRUE(frame0b->GetIdentifier() == frame0id)
1730 << "expected: " << frame0id << " actual: " << frame0b->GetIdentifier();
1731 V_EXPECT_TRUE(frame1b->GetIdentifier() == frame1id)
1732 << "expected: " << frame1id << " actual: " << frame1b->GetIdentifier();
1733 V_EXPECT_TRUE(frame2b->GetIdentifier() == frame2id)
1734 << "expected: " << frame2id << " actual: " << frame2b->GetIdentifier();
1735 V_EXPECT_TRUE(frame3b->GetIdentifier() == frame3id)
1736 << "expected: " << frame3id << " actual: " << frame3b->GetIdentifier();
1737
1738 size_t frame_count = browser->GetFrameCount();
1739 V_EXPECT_TRUE(frame_count == 4U) << " actual: " << frame_count;
1740
1741 // Verify the GetFrameIdentifiers result.
1742 std::set<int64> expected_idents = {frame0id, frame1id, frame2id, frame3id};
1743
1744 std::vector<int64> idents;
1745 browser->GetFrameIdentifiers(idents);
1746 V_EXPECT_TRUE(idents.size() == expected_idents.size())
1747 << "expected: " << expected_idents.size() << " actual: " << idents.size();
1748
1749 for (const auto& ident : idents) {
1750 auto it = expected_idents.find(ident);
1751 V_EXPECT_FALSE(it == expected_idents.end()) << "Unexpected id: " << ident;
1752 if (it != expected_idents.end())
1753 expected_idents.erase(it);
1754 }
1755
1756 for (const auto& ident : expected_idents) {
1757 V_EXPECT_FALSE(true) << "Missing id: " << ident;
1758 }
1759
1760 // Verify parent hierarchy.
1761 V_EXPECT_FALSE(frame0->GetParent().get());
1762 V_EXPECT_TRUE(frame1->GetParent()->GetIdentifier() == frame0id)
1763 << "expected: " << frame0id
1764 << " actual: " << frame1->GetParent()->GetIdentifier();
1765 V_EXPECT_TRUE(frame2->GetParent()->GetIdentifier() == frame1id)
1766 << "expected: " << frame1id
1767 << " actual: " << frame2->GetParent()->GetIdentifier();
1768 V_EXPECT_TRUE(frame3->GetParent()->GetIdentifier() == frame2id)
1769 << "expected: " << frame2id
1770 << " actual: " << frame3->GetParent()->GetIdentifier();
1771
1772 V_RETURN();
1773 }
1774
1775 // Test that nested iframes work.
1776 class FrameNavExpectationsBrowserTestNestedIframes
1777 : public FrameNavExpectationsBrowserMultiNav {
1778 public:
1779 typedef FrameNavExpectationsBrowserMultiNav parent;
1780
FrameNavExpectationsBrowserTestNestedIframes(int nav,bool same_origin)1781 FrameNavExpectationsBrowserTestNestedIframes(int nav, bool same_origin)
1782 : parent(nav), same_origin_(same_origin) {
1783 // In the browser process we can rely on the |nav| value to determine the
1784 // origin.
1785 if (same_origin) {
1786 origin_ = kFrameNavOrigin0;
1787 } else {
1788 switch (nav) {
1789 case 0:
1790 origin_ = kFrameNavOrigin0;
1791 break;
1792 case 1:
1793 origin_ = kFrameNavOrigin1;
1794 break;
1795 case 2:
1796 origin_ = kFrameNavOrigin2;
1797 break;
1798 case 3:
1799 origin_ = kFrameNavOrigin3;
1800 break;
1801 default:
1802 EXPECT_TRUE(false); // Not reached.
1803 break;
1804 }
1805 }
1806 }
1807
GetMainURL()1808 std::string GetMainURL() override {
1809 // Load the first (main) frame.
1810 return GetMultiNavURL(origin_, 0);
1811 }
1812
GetContentForURL(const std::string & url)1813 std::string GetContentForURL(const std::string& url) override {
1814 const int frame_number = GetNavFromMultiNavURL(url);
1815 switch (frame_number) {
1816 case 0:
1817 // Frame 0. Contains a named iframe.
1818 return "<html><body>Nav1<iframe src=\"" + GetMultiNavURL(origin_, 1) +
1819 "\" name=\"nav2\"></body></html>";
1820 case 1:
1821 // Frame 1. Contains an unnamed iframe.
1822 return "<html><body>Nav2<iframe src=\"" + GetMultiNavURL(origin_, 2) +
1823 "\"></body></html>";
1824 case 2: {
1825 // Frame 2. Contains an named iframe created via javascript.
1826 std::stringstream ss;
1827 ss << "<html><script>"
1828 << " function createFrame() {"
1829 << " var f = document.createElement('iframe');"
1830 << " f.name = 'nav3';"
1831 << " f.src = '" << GetMultiNavURL(origin_, 3) << "';"
1832 << " document.body.appendChild(f);"
1833 << " }</script><body onload=\"createFrame()\">Nav3</body></html>";
1834 return ss.str();
1835 }
1836 case 3:
1837 // Frame 3.
1838 return "<html><body>Nav4</body></html>";
1839 default:
1840 EXPECT_TRUE(false); // Not reached.
1841 return "";
1842 }
1843 }
1844
IsNavigationDone() const1845 bool IsNavigationDone() const override {
1846 return got_load_state_change_done_ && got_renderer_complete_ &&
1847 got_load_end_[0] && got_load_end_[1] && got_load_end_[2] &&
1848 got_load_end_[3];
1849 }
1850
OnBeforeBrowse(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const std::string & url)1851 bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
1852 CefRefPtr<CefFrame> frame,
1853 const std::string& url) override {
1854 V_DECLARE();
1855 V_EXPECT_TRUE(frame.get());
1856 const int frame_number = GetNavFromMultiNavURL(url);
1857 if (frame_number == 0) {
1858 // Main frame.
1859 V_EXPECT_TRUE(frame->IsMain());
1860 } else {
1861 // Sub frame.
1862 V_EXPECT_FALSE(frame->IsMain());
1863 }
1864 V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
1865 V_RETURN();
1866 }
1867
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)1868 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
1869 bool isLoading) override {
1870 V_DECLARE();
1871 V_EXPECT_FALSE(got_load_state_change_done_);
1872
1873 if (!isLoading) {
1874 got_load_state_change_done_.yes();
1875 }
1876
1877 V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
1878 V_RETURN();
1879 }
1880
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1881 bool OnLoadStart(CefRefPtr<CefBrowser> browser,
1882 CefRefPtr<CefFrame> frame) override {
1883 const int frame_number = GetNavFromMultiNavURL(frame->GetURL());
1884
1885 V_DECLARE();
1886 V_EXPECT_FALSE(got_load_start_[frame_number]);
1887 V_EXPECT_FALSE(got_load_end_[frame_number]);
1888
1889 // Notification should be received for parent frame before child frame.
1890 if (frame_number == 0) {
1891 V_EXPECT_FALSE(got_load_start_[1]);
1892 V_EXPECT_FALSE(got_load_start_[2]);
1893 V_EXPECT_FALSE(got_load_start_[3]);
1894 } else if (frame_number == 1) {
1895 V_EXPECT_TRUE(got_load_start_[0]);
1896 V_EXPECT_FALSE(got_load_start_[2]);
1897 V_EXPECT_FALSE(got_load_start_[3]);
1898 } else if (frame_number == 2) {
1899 V_EXPECT_TRUE(got_load_start_[0]);
1900 V_EXPECT_TRUE(got_load_start_[1]);
1901 V_EXPECT_FALSE(got_load_start_[3]);
1902 } else if (frame_number == 3) {
1903 V_EXPECT_TRUE(got_load_start_[0]);
1904 V_EXPECT_TRUE(got_load_start_[1]);
1905 V_EXPECT_TRUE(got_load_start_[2]);
1906 } else {
1907 V_EXPECT_TRUE(false); // Not reached.
1908 }
1909
1910 got_load_start_[frame_number].yes();
1911
1912 V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
1913 V_RETURN();
1914 }
1915
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)1916 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
1917 CefRefPtr<CefFrame> frame) override {
1918 const int frame_number = GetNavFromMultiNavURL(frame->GetURL());
1919
1920 V_DECLARE();
1921 V_EXPECT_TRUE(got_load_start_[frame_number]);
1922 V_EXPECT_FALSE(got_load_end_[frame_number]);
1923
1924 // Notification should be received for child frame before parent frame.
1925 if (frame_number == 0) {
1926 V_EXPECT_TRUE(got_load_end_[1]);
1927 V_EXPECT_TRUE(got_load_end_[2]);
1928 V_EXPECT_TRUE(got_load_end_[3]);
1929 } else if (frame_number == 1) {
1930 V_EXPECT_FALSE(got_load_end_[0]);
1931 V_EXPECT_TRUE(got_load_end_[2]);
1932 V_EXPECT_TRUE(got_load_end_[3]);
1933 } else if (frame_number == 2) {
1934 V_EXPECT_FALSE(got_load_end_[0]);
1935 V_EXPECT_FALSE(got_load_end_[1]);
1936 V_EXPECT_TRUE(got_load_end_[3]);
1937 } else if (frame_number == 3) {
1938 V_EXPECT_FALSE(got_load_end_[0]);
1939 V_EXPECT_FALSE(got_load_end_[1]);
1940 V_EXPECT_FALSE(got_load_end_[2]);
1941 } else {
1942 V_EXPECT_TRUE(false); // Not reached.
1943 }
1944
1945 V_EXPECT_TRUE(VerifyBrowserIframe(browser, frame, origin_, frame_number))
1946 << "frame_number = " << frame_number;
1947
1948 got_load_end_[frame_number].yes();
1949
1950 V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
1951 V_RETURN();
1952 }
1953
OnRendererComplete(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int renderer_nav,bool renderer_result)1954 bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
1955 CefRefPtr<CefFrame> frame,
1956 int renderer_nav,
1957 bool renderer_result) override {
1958 V_DECLARE();
1959 V_EXPECT_FALSE(got_renderer_complete_);
1960 if (same_origin_) {
1961 V_EXPECT_TRUE(renderer_nav == nav());
1962 } else {
1963 // Because each navigation is in a new renderer process.
1964 V_EXPECT_TRUE(renderer_nav == 0);
1965 }
1966
1967 got_renderer_complete_.yes();
1968
1969 V_EXPECT_TRUE(parent::OnRendererComplete(browser, frame, renderer_nav,
1970 renderer_result));
1971 V_RETURN();
1972 }
1973
Finalize()1974 bool Finalize() override {
1975 V_DECLARE();
1976 V_EXPECT_TRUE(got_load_state_change_done_);
1977 V_EXPECT_TRUE(got_load_start_[0]);
1978 V_EXPECT_TRUE(got_load_start_[1]);
1979 V_EXPECT_TRUE(got_load_start_[2]);
1980 V_EXPECT_TRUE(got_load_start_[3]);
1981 V_EXPECT_TRUE(got_load_end_[0]);
1982 V_EXPECT_TRUE(got_load_end_[1]);
1983 V_EXPECT_TRUE(got_load_end_[2]);
1984 V_EXPECT_TRUE(got_load_end_[3]);
1985 V_EXPECT_TRUE(got_renderer_complete_);
1986 V_EXPECT_TRUE(parent::Finalize());
1987 V_RETURN();
1988 }
1989
1990 private:
1991 bool same_origin_;
1992 std::string origin_;
1993
1994 TrackCallback got_load_state_change_done_;
1995 TrackCallback got_load_start_[4];
1996 TrackCallback got_load_end_[4];
1997 TrackCallback got_renderer_complete_;
1998 };
1999
2000 class FrameNavExpectationsRendererTestNestedIframes
2001 : public FrameNavExpectationsRendererMultiNav {
2002 public:
2003 typedef FrameNavExpectationsRendererMultiNav parent;
2004
FrameNavExpectationsRendererTestNestedIframes(int nav,bool same_origin)2005 FrameNavExpectationsRendererTestNestedIframes(int nav, bool same_origin)
2006 : parent(nav) {
2007 if (same_origin)
2008 origin_ = kFrameNavOrigin0;
2009 }
2010
IsNavigationDone() const2011 bool IsNavigationDone() const override {
2012 return got_load_state_change_done_ && got_load_end_[0] &&
2013 got_load_end_[1] && got_load_end_[2] && got_load_end_[3];
2014 }
2015
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading)2016 bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
2017 bool isLoading) override {
2018 V_DECLARE();
2019 V_EXPECT_FALSE(got_load_state_change_done_);
2020
2021 if (!isLoading) {
2022 got_load_state_change_done_.yes();
2023 }
2024
2025 V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
2026 V_RETURN();
2027 }
2028
OnLoadStart(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)2029 bool OnLoadStart(CefRefPtr<CefBrowser> browser,
2030 CefRefPtr<CefFrame> frame) override {
2031 if (origin_.empty()) {
2032 // When navigating different origins we can't rely on the nav() value
2033 // because each navigation creates a new renderer process. Get the origin
2034 // by parsing the URL instead.
2035 origin_ = GetOriginFromMultiNavURL(browser->GetMainFrame()->GetURL());
2036 }
2037
2038 const int frame_number = GetNavFromMultiNavURL(frame->GetURL());
2039
2040 V_DECLARE();
2041 V_EXPECT_FALSE(got_load_start_[frame_number]);
2042 V_EXPECT_FALSE(got_load_end_[frame_number]);
2043
2044 // Notification should be received for parent frame before child frame.
2045 if (frame_number == 0) {
2046 V_EXPECT_FALSE(got_load_start_[1]);
2047 V_EXPECT_FALSE(got_load_start_[2]);
2048 V_EXPECT_FALSE(got_load_start_[3]);
2049 } else if (frame_number == 1) {
2050 V_EXPECT_TRUE(got_load_start_[0]);
2051 V_EXPECT_FALSE(got_load_start_[2]);
2052 V_EXPECT_FALSE(got_load_start_[3]);
2053 } else if (frame_number == 2) {
2054 V_EXPECT_TRUE(got_load_start_[0]);
2055 V_EXPECT_TRUE(got_load_start_[1]);
2056 V_EXPECT_FALSE(got_load_start_[3]);
2057 } else if (frame_number == 3) {
2058 V_EXPECT_TRUE(got_load_start_[0]);
2059 V_EXPECT_TRUE(got_load_start_[1]);
2060 V_EXPECT_TRUE(got_load_start_[2]);
2061 }
2062
2063 got_load_start_[frame_number].yes();
2064
2065 V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
2066 V_RETURN();
2067 }
2068
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)2069 bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
2070 CefRefPtr<CefFrame> frame) override {
2071 const int frame_number = GetNavFromMultiNavURL(frame->GetURL());
2072
2073 V_DECLARE();
2074 V_EXPECT_TRUE(got_load_start_[frame_number]);
2075 V_EXPECT_FALSE(got_load_end_[frame_number]);
2076
2077 // Notification should be received for child frame before parent frame.
2078 if (frame_number == 0) {
2079 V_EXPECT_TRUE(got_load_end_[1]);
2080 V_EXPECT_TRUE(got_load_end_[2]);
2081 V_EXPECT_TRUE(got_load_end_[3]);
2082 } else if (frame_number == 1) {
2083 V_EXPECT_FALSE(got_load_end_[0]);
2084 V_EXPECT_TRUE(got_load_end_[2]);
2085 V_EXPECT_TRUE(got_load_end_[3]);
2086 } else if (frame_number == 2) {
2087 V_EXPECT_FALSE(got_load_end_[0]);
2088 V_EXPECT_FALSE(got_load_end_[1]);
2089 V_EXPECT_TRUE(got_load_end_[3]);
2090 } else if (frame_number == 3) {
2091 V_EXPECT_FALSE(got_load_end_[0]);
2092 V_EXPECT_FALSE(got_load_end_[1]);
2093 V_EXPECT_FALSE(got_load_end_[2]);
2094 }
2095
2096 V_EXPECT_TRUE(VerifyBrowserIframe(browser, frame, origin_, frame_number))
2097 << "frame_number = " << frame_number;
2098
2099 got_load_end_[frame_number].yes();
2100
2101 V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
2102 V_RETURN();
2103 }
2104
Finalize()2105 bool Finalize() override {
2106 V_DECLARE();
2107 V_EXPECT_TRUE(got_load_state_change_done_);
2108 V_EXPECT_TRUE(got_load_start_[0]);
2109 V_EXPECT_TRUE(got_load_start_[1]);
2110 V_EXPECT_TRUE(got_load_start_[2]);
2111 V_EXPECT_TRUE(got_load_start_[3]);
2112 V_EXPECT_TRUE(got_load_end_[0]);
2113 V_EXPECT_TRUE(got_load_end_[1]);
2114 V_EXPECT_TRUE(got_load_end_[2]);
2115 V_EXPECT_TRUE(got_load_end_[3]);
2116 V_EXPECT_TRUE(parent::Finalize());
2117 V_RETURN();
2118 }
2119
2120 private:
2121 std::string origin_;
2122
2123 TrackCallback got_load_state_change_done_;
2124 TrackCallback got_load_start_[4];
2125 TrackCallback got_load_end_[4];
2126 };
2127
2128 class FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin
2129 : public FrameNavExpectationsFactoryBrowser {
2130 public:
FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin()2131 FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin()
2132 : create_count_(0) {}
2133
GetID() const2134 FrameNavFactoryId GetID() const override {
2135 return FNF_ID_NESTED_IFRAMES_SAME_ORIGIN;
2136 }
2137
HasMoreNavigations() const2138 bool HasMoreNavigations() const override {
2139 return (create_count_ < kMaxMultiNavNavigations);
2140 }
2141
Finalize()2142 bool Finalize() override {
2143 V_DECLARE();
2144 V_EXPECT_TRUE(create_count_ == kMaxMultiNavNavigations);
2145 V_RETURN();
2146 }
2147
2148 protected:
Create(int nav)2149 scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
2150 create_count_++;
2151 return scoped_ptr<FrameNavExpectationsBrowser>(
2152 new FrameNavExpectationsBrowserTestNestedIframes(nav, true));
2153 }
2154
2155 private:
2156 int create_count_;
2157 };
2158
2159 class FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin
2160 : public FrameNavExpectationsFactoryRenderer {
2161 public:
FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin()2162 FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin() {}
2163
GetID() const2164 FrameNavFactoryId GetID() const override {
2165 return FNF_ID_NESTED_IFRAMES_SAME_ORIGIN;
2166 }
2167
2168 protected:
Create(int nav)2169 scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
2170 return scoped_ptr<FrameNavExpectationsRenderer>(
2171 new FrameNavExpectationsRendererTestNestedIframes(nav, true));
2172 }
2173 };
2174
2175 } // namespace
2176
2177 // Test that nested iframes work.
2178 FRAME_TEST(NestedIframesSameOrigin, FNF_ID_NESTED_IFRAMES_SAME_ORIGIN)
2179
2180 namespace {
2181
2182 class FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin
2183 : public FrameNavExpectationsFactoryBrowser {
2184 public:
FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin()2185 FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin()
2186 : create_count_(0) {}
2187
GetID() const2188 FrameNavFactoryId GetID() const override {
2189 return FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN;
2190 }
2191
HasMoreNavigations() const2192 bool HasMoreNavigations() const override {
2193 return (create_count_ < kMaxMultiNavNavigations);
2194 }
2195
Finalize()2196 bool Finalize() override {
2197 V_DECLARE();
2198 V_EXPECT_TRUE(create_count_ == kMaxMultiNavNavigations);
2199 V_RETURN();
2200 }
2201
2202 protected:
Create(int nav)2203 scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
2204 create_count_++;
2205 return scoped_ptr<FrameNavExpectationsBrowser>(
2206 new FrameNavExpectationsBrowserTestNestedIframes(nav, false));
2207 }
2208
2209 private:
2210 int create_count_;
2211 };
2212
2213 class FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin
2214 : public FrameNavExpectationsFactoryRenderer {
2215 public:
FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin()2216 FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin() {}
2217
GetID() const2218 FrameNavFactoryId GetID() const override {
2219 return FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN;
2220 }
2221
2222 protected:
Create(int nav)2223 scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
2224 return scoped_ptr<FrameNavExpectationsRenderer>(
2225 new FrameNavExpectationsRendererTestNestedIframes(nav, false));
2226 }
2227 };
2228
2229 } // namespace
2230
2231 // Test that nested iframes work.
2232 FRAME_TEST(NestedIframesDiffOrigin, FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN)
2233
2234 namespace {
2235
2236 // Returns a new factory in the browser or renderer process. All factory types
2237 // must be listed here.
2238
2239 // static
2240 scoped_ptr<FrameNavExpectationsFactoryBrowser>
FromID(FrameNavFactoryId id)2241 FrameNavExpectationsFactoryBrowser::FromID(FrameNavFactoryId id) {
2242 scoped_ptr<FrameNavExpectationsFactoryBrowser> factory;
2243 switch (id) {
2244 case FNF_ID_SINGLE_NAV_HARNESS:
2245 factory.reset(new FrameNavExpectationsFactoryBrowserTestSingleNavHarness);
2246 break;
2247 case FNF_ID_SINGLE_NAV:
2248 factory.reset(new FrameNavExpectationsFactoryBrowserTestSingleNav);
2249 break;
2250 case FNF_ID_MULTI_NAV_HARNESS:
2251 factory.reset(new FrameNavExpectationsFactoryBrowserTestMultiNavHarness);
2252 break;
2253 case FNF_ID_MULTI_NAV:
2254 factory.reset(new FrameNavExpectationsFactoryBrowserTestMultiNav);
2255 break;
2256 case FNF_ID_NESTED_IFRAMES_SAME_ORIGIN:
2257 factory.reset(
2258 new FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin);
2259 break;
2260 case FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN:
2261 factory.reset(
2262 new FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin);
2263 break;
2264 default:
2265 break;
2266 }
2267 EXPECT_TRUE(factory);
2268 EXPECT_EQ(id, factory->GetID());
2269 return factory.Pass();
2270 }
2271
2272 // static
2273 scoped_ptr<FrameNavExpectationsFactoryRenderer>
FromID(FrameNavFactoryId id)2274 FrameNavExpectationsFactoryRenderer::FromID(FrameNavFactoryId id) {
2275 scoped_ptr<FrameNavExpectationsFactoryRenderer> factory;
2276 switch (id) {
2277 case FNF_ID_SINGLE_NAV_HARNESS:
2278 factory.reset(
2279 new FrameNavExpectationsFactoryRendererTestSingleNavHarness);
2280 break;
2281 case FNF_ID_SINGLE_NAV:
2282 factory.reset(new FrameNavExpectationsFactoryRendererTestSingleNav);
2283 break;
2284 case FNF_ID_MULTI_NAV_HARNESS:
2285 factory.reset(new FrameNavExpectationsFactoryRendererTestMultiNavHarness);
2286 break;
2287 case FNF_ID_MULTI_NAV:
2288 factory.reset(new FrameNavExpectationsFactoryRendererTestMultiNav);
2289 break;
2290 case FNF_ID_NESTED_IFRAMES_SAME_ORIGIN:
2291 factory.reset(
2292 new FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin);
2293 break;
2294 case FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN:
2295 factory.reset(
2296 new FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin);
2297 break;
2298 default:
2299 break;
2300 }
2301 EXPECT_TRUE(factory);
2302 EXPECT_EQ(id, factory->GetID());
2303 return factory.Pass();
2304 }
2305
2306 } // namespace
2307
2308 // Entry point for creating frame renderer test objects.
2309 // Called from client_app_delegates.cc.
CreateFrameRendererTests(ClientAppRenderer::DelegateSet & delegates)2310 void CreateFrameRendererTests(ClientAppRenderer::DelegateSet& delegates) {
2311 delegates.insert(new FrameNavRendererTest);
2312 }
2313