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