OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <deque> | 5 #include <deque> |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/path_service.h" | 8 #include "base/path_service.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/test/test_timeouts.h" | 10 #include "base/test/test_timeouts.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 | 95 |
96 // PrerenderContents that stops the UI message loop on DidStopLoading(). | 96 // PrerenderContents that stops the UI message loop on DidStopLoading(). |
97 class TestPrerenderContents : public PrerenderContents { | 97 class TestPrerenderContents : public PrerenderContents { |
98 public: | 98 public: |
99 TestPrerenderContents( | 99 TestPrerenderContents( |
100 PrerenderManager* prerender_manager, | 100 PrerenderManager* prerender_manager, |
101 PrerenderTracker* prerender_tracker, | 101 PrerenderTracker* prerender_tracker, |
102 Profile* profile, | 102 Profile* profile, |
103 const GURL& url, | 103 const GURL& url, |
104 const GURL& referrer, | 104 const GURL& referrer, |
105 int expected_number_of_loads, | 105 int number_of_loads, |
106 FinalStatus expected_final_status) | 106 FinalStatus expected_final_status) |
107 : PrerenderContents(prerender_manager, prerender_tracker, profile, | 107 : PrerenderContents(prerender_manager, prerender_tracker, profile, |
108 url, referrer, ORIGIN_LINK_REL_PRERENDER, | 108 url, referrer, ORIGIN_LINK_REL_PRERENDER, |
109 PrerenderManager::kNoExperiment), | 109 PrerenderManager::kNoExperiment), |
110 number_of_loads_(0), | 110 number_of_loads_(0), |
111 expected_number_of_loads_(expected_number_of_loads), | 111 expected_number_of_loads_(number_of_loads), |
112 expected_final_status_(expected_final_status), | 112 expected_final_status_(expected_final_status), |
113 new_render_view_host_(NULL), | 113 new_render_view_host_(NULL), |
114 was_hidden_(false), | 114 was_hidden_(false), |
115 was_shown_(false), | 115 was_shown_(false), |
116 should_be_shown_(expected_final_status == FINAL_STATUS_USED), | 116 should_be_shown_(expected_final_status == FINAL_STATUS_USED), |
117 quit_message_loop_on_destruction_(true) { | 117 quit_message_loop_on_destruction_(true) { |
118 if (expected_number_of_loads == 0) | |
119 MessageLoopForUI::current()->Quit(); | |
120 } | 118 } |
121 | 119 |
122 virtual ~TestPrerenderContents() { | 120 virtual ~TestPrerenderContents() { |
123 EXPECT_EQ(expected_final_status_, final_status()) << | 121 EXPECT_EQ(expected_final_status_, final_status()) << |
124 " when testing URL " << prerender_url().path() << | 122 " when testing URL " << prerender_url().path() << |
125 " (Expected: " << NameFromFinalStatus(expected_final_status_) << | 123 " (Expected: " << NameFromFinalStatus(expected_final_status_) << |
126 ", Actual: " << NameFromFinalStatus(final_status()) << ")"; | 124 ", Actual: " << NameFromFinalStatus(final_status()) << ")"; |
127 // Prerendering RenderViewHosts should be hidden before the first | 125 // Prerendering RenderViewHosts should be hidden before the first |
128 // navigation, so this should be happen for every PrerenderContents for | 126 // navigation, so this should be happen for every PrerenderContents for |
129 // which a RenderViewHost is created, regardless of whether or not it's | 127 // which a RenderViewHost is created, regardless of whether or not it's |
130 // used. | 128 // used. |
131 if (new_render_view_host_) | 129 if (new_render_view_host_) { |
132 EXPECT_TRUE(was_hidden_); | 130 EXPECT_TRUE(was_hidden_); |
| 131 } |
133 | 132 |
134 // A used PrerenderContents will only be destroyed when we swap out | 133 // A used PrerenderContents will only be destroyed when we swap out |
135 // TabContents, at the end of a navigation caused by a call to | 134 // TabContents, at the end of a navigation caused by a call to |
136 // NavigateToURLImpl(). | 135 // NavigateToURLImpl(). |
137 if (final_status() == FINAL_STATUS_USED) | 136 if (final_status() == FINAL_STATUS_USED) |
138 EXPECT_TRUE(new_render_view_host_); | 137 EXPECT_TRUE(new_render_view_host_); |
139 | 138 |
140 EXPECT_EQ(should_be_shown_, was_shown_); | 139 EXPECT_EQ(should_be_shown_, was_shown_); |
141 | 140 |
142 // When the PrerenderContents is destroyed, quit the UI message loop. | 141 // When the PrerenderContents is destroyed, quit the UI message loop. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 // even though it is used. | 178 // even though it is used. |
180 void set_should_be_shown(bool value) { should_be_shown_ = value; } | 179 void set_should_be_shown(bool value) { should_be_shown_ = value; } |
181 | 180 |
182 // Some of the ui_test_utils calls that we use assume that no one will quit | 181 // Some of the ui_test_utils calls that we use assume that no one will quit |
183 // the message loop that they run internally. So we dont quit the message | 182 // the message loop that they run internally. So we dont quit the message |
184 // loop in the destructor so as not to interfere. | 183 // loop in the destructor so as not to interfere. |
185 void set_quit_message_loop_on_destruction(bool value) { | 184 void set_quit_message_loop_on_destruction(bool value) { |
186 quit_message_loop_on_destruction_ = value; | 185 quit_message_loop_on_destruction_ = value; |
187 } | 186 } |
188 | 187 |
189 int number_of_loads() { return number_of_loads_; } | |
190 | |
191 private: | 188 private: |
192 virtual void OnRenderViewHostCreated( | 189 virtual void OnRenderViewHostCreated( |
193 RenderViewHost* new_render_view_host) OVERRIDE { | 190 RenderViewHost* new_render_view_host) OVERRIDE { |
194 // Used to make sure the RenderViewHost is hidden and, if used, | 191 // Used to make sure the RenderViewHost is hidden and, if used, |
195 // subsequently shown. | 192 // subsequently shown. |
196 notification_registrar().Add( | 193 notification_registrar().Add( |
197 this, | 194 this, |
198 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, | 195 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, |
199 Source<RenderWidgetHost>(new_render_view_host)); | 196 Source<RenderWidgetHost>(new_render_view_host)); |
200 | 197 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 | 238 |
242 bool quit_message_loop_on_destruction_; | 239 bool quit_message_loop_on_destruction_; |
243 }; | 240 }; |
244 | 241 |
245 // PrerenderManager that uses TestPrerenderContents. | 242 // PrerenderManager that uses TestPrerenderContents. |
246 class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory { | 243 class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory { |
247 public: | 244 public: |
248 WaitForLoadPrerenderContentsFactory( | 245 WaitForLoadPrerenderContentsFactory( |
249 int number_of_loads, | 246 int number_of_loads, |
250 const std::deque<FinalStatus>& expected_final_status_queue) | 247 const std::deque<FinalStatus>& expected_final_status_queue) |
251 : number_of_loads_(number_of_loads), | 248 : number_of_loads_(number_of_loads) { |
252 expected_final_status_queue_(expected_final_status_queue) { | 249 expected_final_status_queue_.resize(expected_final_status_queue.size()); |
| 250 std::copy(expected_final_status_queue.begin(), |
| 251 expected_final_status_queue.end(), |
| 252 expected_final_status_queue_.begin()); |
253 VLOG(1) << "Factory created with queue length " << | 253 VLOG(1) << "Factory created with queue length " << |
254 expected_final_status_queue_.size(); | 254 expected_final_status_queue_.size(); |
255 } | 255 } |
256 | 256 |
257 virtual PrerenderContents* CreatePrerenderContents( | 257 virtual PrerenderContents* CreatePrerenderContents( |
258 PrerenderManager* prerender_manager, | 258 PrerenderManager* prerender_manager, |
259 PrerenderTracker* prerender_tracker, | 259 PrerenderTracker* prerender_tracker, |
260 Profile* profile, | 260 Profile* profile, |
261 const GURL& url, | 261 const GURL& url, |
262 const GURL& referrer, | 262 const GURL& referrer, |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED); | 608 browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED); |
609 | 609 |
610 ui_test_utils::RunMessageLoop(); | 610 ui_test_utils::RunMessageLoop(); |
611 | 611 |
612 TestPrerenderContents* prerender_contents = GetPrerenderContents(); | 612 TestPrerenderContents* prerender_contents = GetPrerenderContents(); |
613 | 613 |
614 if (ShouldRenderPrerenderedPageCorrectly(expected_final_status)) { | 614 if (ShouldRenderPrerenderedPageCorrectly(expected_final_status)) { |
615 ASSERT_TRUE(prerender_contents != NULL); | 615 ASSERT_TRUE(prerender_contents != NULL); |
616 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); | 616 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); |
617 | 617 |
618 if (call_javascript_ && total_navigations > 0) { | 618 if (call_javascript_) { |
619 // Check if page behaves as expected while in prerendered state. | 619 // Check if page behaves as expected while in prerendered state. |
620 bool prerender_test_result = false; | 620 bool prerender_test_result = false; |
621 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( | 621 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( |
622 prerender_contents->render_view_host_mutable(), L"", | 622 prerender_contents->render_view_host_mutable(), L"", |
623 L"window.domAutomationController.send(DidPrerenderPass())", | 623 L"window.domAutomationController.send(DidPrerenderPass())", |
624 &prerender_test_result)); | 624 &prerender_test_result)); |
625 EXPECT_TRUE(prerender_test_result); | 625 EXPECT_TRUE(prerender_test_result); |
626 } | 626 } |
627 } else { | 627 } else { |
628 // In the failure case, we should have removed |dest_url_| from the | 628 // In the failure case, we should have removed dest_url_ from the |
629 // prerender_manager. | 629 // prerender_manager. |
630 EXPECT_TRUE(prerender_contents == NULL); | 630 EXPECT_TRUE(prerender_contents == NULL); |
631 } | 631 } |
632 } | 632 } |
633 | 633 |
634 void NavigateToURLImpl(const GURL& dest_url, | 634 void NavigateToURLImpl(const GURL& dest_url, |
635 WindowOpenDisposition disposition) const { | 635 WindowOpenDisposition disposition) const { |
636 // Make sure in navigating we have a URL to use in the PrerenderManager. | 636 // Make sure in navigating we have a URL to use in the PrerenderManager. |
637 ASSERT_TRUE(GetPrerenderContents() != NULL); | 637 ASSERT_TRUE(GetPrerenderContents() != NULL); |
638 | 638 |
639 // If opening the page in a background tab, it won't be shown when swapped | 639 // If opening the page in a background tab, it won't be shown when swapped |
640 // in. | 640 // in. |
641 if (disposition == NEW_BACKGROUND_TAB) | 641 if (disposition == NEW_BACKGROUND_TAB) |
642 GetPrerenderContents()->set_should_be_shown(false); | 642 GetPrerenderContents()->set_should_be_shown(false); |
643 | 643 |
644 // In the case of zero loads, need to wait for the page load to complete | |
645 // before running any Javascript. | |
646 scoped_ptr<ui_test_utils::WindowedNotificationObserver> page_load_observer; | |
647 TabContents* tab_contents = | |
648 GetPrerenderContents()->prerender_contents()->tab_contents(); | |
649 if (GetPrerenderContents()->number_of_loads() == 0) { | |
650 page_load_observer.reset( | |
651 new ui_test_utils::WindowedNotificationObserver( | |
652 content::NOTIFICATION_LOAD_STOP, | |
653 Source<NavigationController>(&tab_contents->controller()))); | |
654 } | |
655 | |
656 // ui_test_utils::NavigateToURL waits until DidStopLoading is called on | 644 // ui_test_utils::NavigateToURL waits until DidStopLoading is called on |
657 // the current tab. As that tab is going to end up deleted, and may never | 645 // the current tab. As that tab is going to end up deleted, and may never |
658 // finish loading before that happens, exit the message loop on the deletion | 646 // finish loading before that happens, exit the message loop on the deletion |
659 // of the used prerender contents instead. | 647 // of the used prerender contents instead. |
660 // | 648 // |
661 // As PrerenderTestURL waits until the prerendered page has completely | 649 // As PrerenderTestURL waits until the prerendered page has completely |
662 // loaded, there is no race between loading |dest_url| and swapping the | 650 // loaded, there is no race between loading |dest_url| and swapping the |
663 // prerendered TabContents into the tab. | 651 // prerendered TabContents into the tab. |
664 ui_test_utils::NavigateToURLWithDisposition( | 652 ui_test_utils::NavigateToURLWithDisposition( |
665 browser(), dest_url, disposition, ui_test_utils::BROWSER_TEST_NONE); | 653 browser(), dest_url, disposition, ui_test_utils::BROWSER_TEST_NONE); |
666 ui_test_utils::RunMessageLoop(); | 654 ui_test_utils::RunMessageLoop(); |
667 | 655 |
668 // Make sure the PrerenderContents found earlier was used or removed. | 656 // Make sure the PrerenderContents found earlier was used or removed. |
669 EXPECT_TRUE(GetPrerenderContents() == NULL); | 657 EXPECT_TRUE(GetPrerenderContents() == NULL); |
670 | 658 |
671 if (call_javascript_) { | 659 if (call_javascript_) { |
672 if (page_load_observer.get()) | 660 // Check if page behaved as expected when actually displayed. |
673 page_load_observer->Wait(); | 661 |
| 662 // Locate the navigated TabContents. |
| 663 TabContents* tab_contents = NULL; |
| 664 switch (disposition) { |
| 665 case CURRENT_TAB: |
| 666 case NEW_FOREGROUND_TAB: |
| 667 tab_contents = browser()->GetSelectedTabContents(); |
| 668 break; |
| 669 case NEW_BACKGROUND_TAB: |
| 670 tab_contents = |
| 671 browser()->GetTabContentsAt(browser()->active_index() + 1); |
| 672 break; |
| 673 default: |
| 674 ASSERT_TRUE(false) << "Unsupported creation disposition"; |
| 675 } |
| 676 ASSERT_TRUE(tab_contents); |
674 | 677 |
675 bool display_test_result = false; | 678 bool display_test_result = false; |
676 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( | 679 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( |
677 tab_contents->render_view_host(), L"", | 680 tab_contents->render_view_host(), L"", |
678 L"window.domAutomationController.send(DidDisplayPass())", | 681 L"window.domAutomationController.send(DidDisplayPass())", |
679 &display_test_result)); | 682 &display_test_result)); |
680 EXPECT_TRUE(display_test_result); | 683 EXPECT_TRUE(display_test_result); |
681 } | 684 } |
682 } | 685 } |
683 | 686 |
(...skipping 16 matching lines...) Expand all Loading... |
700 } | 703 } |
701 | 704 |
702 // Checks that the visibility API works. | 705 // Checks that the visibility API works. |
703 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) { | 706 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) { |
704 PrerenderTestURL("files/prerender/prerender_visibility.html", | 707 PrerenderTestURL("files/prerender/prerender_visibility.html", |
705 FINAL_STATUS_USED, | 708 FINAL_STATUS_USED, |
706 1); | 709 1); |
707 NavigateToDestURL(); | 710 NavigateToDestURL(); |
708 } | 711 } |
709 | 712 |
710 // Checks that the visibility API works when the prerender is quickly opened | |
711 // in a new tab before it stops loading. | |
712 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityQuickSwitch) { | |
713 PrerenderTestURL("files/prerender/prerender_visibility_quick.html", | |
714 FINAL_STATUS_USED, 0); | |
715 NavigateToDestURL(); | |
716 } | |
717 | |
718 // Checks that the visibility API works when opening a page in a new hidden | 713 // Checks that the visibility API works when opening a page in a new hidden |
719 // tab. | 714 // tab. |
720 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityBackgroundTab) { | 715 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityBackgroundTab) { |
721 PrerenderTestURL("files/prerender/prerender_visibility_hidden.html", | 716 PrerenderTestURL("files/prerender/prerender_visibility_hidden.html", |
722 FINAL_STATUS_USED, | 717 FINAL_STATUS_USED, |
723 1); | 718 1); |
724 NavigateToDestURLWithDisposition(NEW_BACKGROUND_TAB); | 719 NavigateToDestURLWithDisposition(NEW_BACKGROUND_TAB); |
725 } | 720 } |
726 | 721 |
727 // Checks that the visibility API works when opening a page in a new hidden | |
728 // tab, which is switched to before it stops loading. | |
729 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, | |
730 PrerenderVisibilityBackgroundTabQuickSwitch) { | |
731 PrerenderTestURL("files/prerender/prerender_visibility_hidden_quick.html", | |
732 FINAL_STATUS_USED, 0); | |
733 NavigateToDestURLWithDisposition(NEW_BACKGROUND_TAB); | |
734 } | |
735 | |
736 // Checks that the visibility API works when opening a page in a new foreground | 722 // Checks that the visibility API works when opening a page in a new foreground |
737 // tab. | 723 // tab. |
738 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityForegroundTab) { | 724 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibilityForegroundTab) { |
739 PrerenderTestURL("files/prerender/prerender_visibility.html", | 725 PrerenderTestURL("files/prerender/prerender_visibility.html", |
740 FINAL_STATUS_USED, | 726 FINAL_STATUS_USED, |
741 1); | 727 1); |
742 NavigateToDestURLWithDisposition(NEW_FOREGROUND_TAB); | 728 NavigateToDestURLWithDisposition(NEW_FOREGROUND_TAB); |
743 } | 729 } |
744 | 730 |
745 // Checks that the visibility API works when the prerender is quickly opened | |
746 // in a new tab foreground before it stops loading. | |
747 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, | |
748 PrerenderVisibilityForegroundTabQuickSwitch) { | |
749 PrerenderTestURL("files/prerender/prerender_visibility_quick.html", | |
750 FINAL_STATUS_USED, 0); | |
751 NavigateToDestURL(); | |
752 } | |
753 | |
754 // Checks that the prerendering of a page is canceled correctly when a | 731 // Checks that the prerendering of a page is canceled correctly when a |
755 // Javascript alert is called. | 732 // Javascript alert is called. |
756 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) { | 733 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) { |
757 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", | 734 PrerenderTestURL("files/prerender/prerender_alert_before_onload.html", |
758 FINAL_STATUS_JAVASCRIPT_ALERT, | 735 FINAL_STATUS_JAVASCRIPT_ALERT, |
759 1); | 736 1); |
760 } | 737 } |
761 | 738 |
762 // Checks that the prerendering of a page is canceled correctly when a | 739 // Checks that the prerendering of a page is canceled correctly when a |
763 // Javascript alert is called. | 740 // Javascript alert is called. |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1698 bool original_prerender_page = false; | 1675 bool original_prerender_page = false; |
1699 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( | 1676 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( |
1700 browser()->GetSelectedTabContents()->render_view_host(), L"", | 1677 browser()->GetSelectedTabContents()->render_view_host(), L"", |
1701 L"window.domAutomationController.send(IsOriginalPrerenderPage())", | 1678 L"window.domAutomationController.send(IsOriginalPrerenderPage())", |
1702 &original_prerender_page)); | 1679 &original_prerender_page)); |
1703 EXPECT_TRUE(original_prerender_page); | 1680 EXPECT_TRUE(original_prerender_page); |
1704 } | 1681 } |
1705 } | 1682 } |
1706 | 1683 |
1707 } // namespace prerender | 1684 } // namespace prerender |
OLD | NEW |