Index: chrome/browser/prerender/prerender_browsertest.cc |
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc |
index 6e4c235b41595ffb6eb907f13d6a1879e6ce65bb..3718ace5cd6ed8013b05b32a6082ee77a8a8e632 100644 |
--- a/chrome/browser/prerender/prerender_browsertest.cc |
+++ b/chrome/browser/prerender/prerender_browsertest.cc |
@@ -43,6 +43,7 @@ |
#include "chrome/browser/ui/browser_navigator.h" |
#include "chrome/browser/ui/browser_window.h" |
#include "chrome/browser/ui/tabs/tab_strip_model.h" |
+#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" |
#include "chrome/common/chrome_paths.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/extensions/extension_constants.h" |
@@ -61,6 +62,7 @@ |
#include "content/public/browser/render_view_host.h" |
#include "content/public/browser/site_instance.h" |
#include "content/public/browser/web_contents.h" |
+#include "content/public/browser/web_contents_observer.h" |
#include "content/public/common/url_constants.h" |
#include "content/public/test/browser_test_utils.h" |
#include "content/public/test/test_navigation_observer.h" |
@@ -87,6 +89,7 @@ using content::Referrer; |
using content::RenderViewHost; |
using content::RenderWidgetHost; |
using content::WebContents; |
+using content::WebContentsObserver; |
// Prerender tests work as follows: |
// |
@@ -209,6 +212,49 @@ class ChannelDestructionWatcher { |
DISALLOW_COPY_AND_ASSIGN(ChannelDestructionWatcher); |
}; |
+// A simple observer to wait on either a load or a swap of a WebContents. |
+class NavigationOrSwapObserver : public WebContentsObserver, |
+ public TabStripModelObserver { |
+ public: |
+ // Waits for either a load or a swap of |tab_strip_model|'s active |
+ // WebContents. |
+ NavigationOrSwapObserver(TabStripModel* tab_strip_model, |
+ WebContents* web_contents) |
+ : WebContentsObserver(web_contents), |
+ tab_strip_model_(tab_strip_model) { |
+ CHECK_NE(TabStripModel::kNoTab, |
+ tab_strip_model->GetIndexOfWebContents(web_contents)); |
+ tab_strip_model_->AddObserver(this); |
+ } |
+ |
+ virtual ~NavigationOrSwapObserver() { |
+ tab_strip_model_->RemoveObserver(this); |
+ } |
+ |
+ void Wait() { |
+ loop_.Run(); |
+ } |
+ |
+ // WebContentsObserver implementation: |
+ virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE { |
+ loop_.Quit(); |
+ } |
+ |
+ // TabStripModelObserver implementation: |
+ virtual void TabReplacedAt(TabStripModel* tab_strip_model, |
+ WebContents* old_contents, |
+ WebContents* new_contents, |
+ int index) OVERRIDE { |
+ if (old_contents != web_contents()) |
+ return; |
+ loop_.Quit(); |
+ } |
+ |
+ private: |
+ TabStripModel* tab_strip_model_; |
+ base::RunLoop loop_; |
+}; |
+ |
// PrerenderContents that stops the UI message loop on DidStopLoading(). |
class TestPrerenderContents : public PrerenderContents { |
public: |
@@ -604,10 +650,10 @@ class RestorePrerenderMode { |
PrerenderManager::PrerenderManagerMode prev_mode_; |
}; |
-// URLRequestJob (and associated handler) which never starts. |
-class NeverStartURLRequestJob : public net::URLRequestJob { |
+// URLRequestJob (and associated handler) which hangs. |
+class HangingURLRequestJob : public net::URLRequestJob { |
public: |
- NeverStartURLRequestJob(net::URLRequest* request, |
+ HangingURLRequestJob(net::URLRequest* request, |
net::NetworkDelegate* network_delegate) |
: net::URLRequestJob(request, network_delegate) { |
} |
@@ -615,26 +661,40 @@ class NeverStartURLRequestJob : public net::URLRequestJob { |
virtual void Start() OVERRIDE {} |
private: |
- virtual ~NeverStartURLRequestJob() {} |
+ virtual ~HangingURLRequestJob() {} |
}; |
-class NeverStartProtocolHandler |
+class HangingFirstRequestProtocolHandler |
: public net::URLRequestJobFactory::ProtocolHandler { |
public: |
- NeverStartProtocolHandler() {} |
- virtual ~NeverStartProtocolHandler() {} |
+ explicit HangingFirstRequestProtocolHandler(const base::FilePath& file) |
+ : file_(file), |
+ first_run_(true) { |
+ } |
+ virtual ~HangingFirstRequestProtocolHandler() {} |
virtual net::URLRequestJob* MaybeCreateJob( |
net::URLRequest* request, |
net::NetworkDelegate* network_delegate) const OVERRIDE { |
- return new NeverStartURLRequestJob(request, network_delegate); |
+ if (first_run_) { |
+ first_run_ = false; |
+ return new HangingURLRequestJob(request, network_delegate); |
+ } |
+ return new content::URLRequestMockHTTPJob(request, network_delegate, file_); |
} |
+ |
+ private: |
+ base::FilePath file_; |
+ mutable bool first_run_; |
}; |
-void CreateNeverStartProtocolHandlerOnIO(const GURL& url) { |
+// Makes |url| never respond on the first load, and then with the contents of |
+// |file| afterwards. |
+void CreateHangingFirstRequestProtocolHandlerOnIO(const GURL& url, |
+ const base::FilePath& file) { |
CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> never_respond_handler( |
- new NeverStartProtocolHandler()); |
+ new HangingFirstRequestProtocolHandler(file)); |
net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( |
url, never_respond_handler.Pass()); |
} |
@@ -838,9 +898,6 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest { |
// due to session storage namespace mismatch. The merge is only kicked off |
// asynchronously. |
NavigateToDestURLWithDisposition(CURRENT_TAB, false); |
- // Run the message loop, waiting for the merge to complete, the swapin to |
- // be reattempted, and to eventually succeed. |
- content::RunMessageLoop(); |
} |
// Opens the url in a new tab, with no opener. |
@@ -1152,6 +1209,26 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest { |
GetPrerenderManager()->mutable_config().max_bytes = 1000 * 1024 * 1024; |
} |
+ bool DidPrerenderPass(WebContents* web_contents) const { |
+ bool prerender_test_result = false; |
+ if (!content::ExecuteScriptAndExtractBool( |
+ web_contents, |
+ "window.domAutomationController.send(DidPrerenderPass())", |
+ &prerender_test_result)) |
+ return false; |
+ return prerender_test_result; |
+ } |
+ |
+ bool DidDisplayPass(WebContents* web_contents) const { |
+ bool display_test_result = false; |
+ if (!content::ExecuteScriptAndExtractBool( |
+ web_contents, |
+ "window.domAutomationController.send(DidDisplayPass())", |
+ &display_test_result)) |
+ return false; |
+ return display_test_result; |
+ } |
+ |
protected: |
bool autostart_test_server_; |
@@ -1238,12 +1315,7 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest { |
prerender_contents->WaitForPrerenderToHaveReadyTitleIfRequired(); |
// Check if page behaves as expected while in prerendered state. |
- bool prerender_test_result = false; |
- ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
- prerender_contents->GetRenderViewHostMutable(), |
- "window.domAutomationController.send(DidPrerenderPass())", |
- &prerender_test_result)); |
- EXPECT_TRUE(prerender_test_result); |
+ EXPECT_TRUE(DidPrerenderPass(prerender_contents->prerender_contents())); |
} |
// Test that the referring page received events. |
@@ -1302,10 +1374,16 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest { |
} |
} |
- // Navigate to the prerendered URL, but don't run the message loop. Browser |
- // issued navigations to prerendered pages will synchronously swap in the |
- // prerendered page. |
+ // Navigate and wait for either the load to finish normally or for a swap to |
+ // occur. |
+ // TODO(davidben): The only handles CURRENT_TAB navigations, which is the |
+ // only case tested or prerendered right now. |
+ CHECK_EQ(CURRENT_TAB, params.disposition); |
+ NavigationOrSwapObserver swap_observer( |
+ current_browser()->tab_strip_model(), |
+ current_browser()->tab_strip_model()->GetActiveWebContents()); |
WebContents* target_web_contents = current_browser()->OpenURL(params); |
+ swap_observer.Wait(); |
if (web_contents && expect_swap_to_succeed) { |
EXPECT_EQ(web_contents, target_web_contents); |
@@ -1313,12 +1391,7 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest { |
if (page_load_observer.get()) |
page_load_observer->Wait(); |
- bool display_test_result = false; |
- ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
- web_contents, |
- "window.domAutomationController.send(DidDisplayPass())", |
- &display_test_result)); |
- EXPECT_TRUE(display_test_result); |
+ EXPECT_TRUE(DidDisplayPass(web_contents)); |
} |
} |
} |
@@ -1552,9 +1625,12 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, |
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap) { |
// Navigate to a page that triggers a prerender for a URL that never commits. |
const GURL kNoCommitUrl("http://never-respond.example.com"); |
+ base::FilePath file(FILE_PATH_LITERAL( |
+ "chrome/test/data/prerender/prerender_page.html")); |
BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
- base::Bind(&CreateNeverStartProtocolHandlerOnIO, kNoCommitUrl)); |
+ base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO, |
+ kNoCommitUrl, file)); |
DisableJavascriptCalls(); |
PrerenderTestURL(kNoCommitUrl, |
FINAL_STATUS_NAVIGATION_UNCOMMITTED, |
@@ -1568,9 +1644,12 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap) { |
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap2) { |
// Navigate to a page that then navigates to a URL that never commits. |
const GURL kNoCommitUrl("http://never-respond.example.com"); |
+ base::FilePath file(FILE_PATH_LITERAL( |
+ "chrome/test/data/prerender/prerender_page.html")); |
BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
- base::Bind(&CreateNeverStartProtocolHandlerOnIO, kNoCommitUrl)); |
+ base::Bind(&CreateHangingFirstRequestProtocolHandlerOnIO, |
+ kNoCommitUrl, file)); |
DisableJavascriptCalls(); |
PrerenderTestURL(CreateClientRedirect(kNoCommitUrl.spec()), |
FINAL_STATUS_APP_TERMINATING, 1); |
@@ -1652,12 +1731,7 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNaClPluginDisabled) { |
// loading. It would be great if we could avoid that. |
WebContents* web_contents = |
browser()->tab_strip_model()->GetActiveWebContents(); |
- bool display_test_result = false; |
- ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
- web_contents, |
- "window.domAutomationController.send(DidDisplayPass())", |
- &display_test_result)); |
- EXPECT_TRUE(display_test_result); |
+ EXPECT_TRUE(DidDisplayPass(web_contents)); |
} |
// Checks that plugins in an iframe are not loaded while a page is |