Commit b160d492 authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Chromium LUCI CQ

Prerender: Simplify browser tests for prerendering

This is a cleanup and doesn't change functionalities.

Before this change, each browser test case had its own html file that
triggers <link rel=prerender>. This was not scalable. After this change,
browser tests share the common html file that can dynamically add
<link rel=prerender> from C++.

In addition to that, this CL factors out common routines into helper
functions.

Bug: 1132746
Change-Id: I7aea316da481c86832314384f2d2d997c30deaea
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2567054
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832668}
parent 723fea5f
...@@ -66,6 +66,34 @@ class PrerenderBrowserTest : public ContentBrowserTest, ...@@ -66,6 +66,34 @@ class PrerenderBrowserTest : public ContentBrowserTest,
return *storage_partition->GetPrerenderHostRegistry(); return *storage_partition->GetPrerenderHostRegistry();
} }
// Adds <link rel=prerender> in the current main frame and waits until the
// completion of prerendering.
void AddPrerender(const GURL& prerendering_url) {
// Start watching new web contents to be created for prerendering.
content::TestNavigationObserver observer(prerendering_url);
observer.StartWatchingNewWebContents();
// Add the link tag that will prerender the URL.
EXPECT_TRUE(ExecJs(shell()->web_contents(),
JsReplace("add_prerender($1)", prerendering_url)));
observer.Wait();
}
// Navigates to the URL and waits until the completion of navigation.
//
// Navigations that could activate a prerendered page on the multiple
// WebContents architecture (not multiple-pages architecture known as MPArch)
// should use this function instead of the NavigateToURL() test helper. This
// is because the test helper accesses the predecessor WebContents to be
// destroyed during activation and results in crashes.
// See https://crbug.com/1154501 for the MPArch migration.
void NavigateWithLocation(const GURL& url) {
content::TestNavigationObserver observer(shell()->web_contents());
EXPECT_TRUE(
ExecJs(shell()->web_contents(), JsReplace("location = $1", url)));
observer.Wait();
EXPECT_EQ(shell()->web_contents()->GetURL(), url);
}
GURL GetUrl(const std::string& path) { GURL GetUrl(const std::string& path) {
return ssl_server_.GetURL("a.test", path); return ssl_server_.GetURL("a.test", path);
} }
...@@ -91,38 +119,26 @@ class PrerenderBrowserTest : public ContentBrowserTest, ...@@ -91,38 +119,26 @@ class PrerenderBrowserTest : public ContentBrowserTest,
INSTANTIATE_TEST_SUITE_P(All, PrerenderBrowserTest, testing::Bool()); INSTANTIATE_TEST_SUITE_P(All, PrerenderBrowserTest, testing::Bool());
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, LinkRelPrerender) { IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, LinkRelPrerender) {
const GURL kInitialUrl = GetUrl("/prerender/single_prerender.html"); const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
const GURL kPrerenderingUrl = GetUrl("/empty.html"); const GURL kPrerenderingUrl = GetUrl("/empty.html");
// Start watching new web contents to be created for prerendering. // Navigate to an initial page.
content::TestNavigationObserver navigation_observer(kPrerenderingUrl);
navigation_observer.StartWatchingNewWebContents();
// Navigate to a page that initiates prerendering for `kPrerenderingUrl`.
ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
ASSERT_EQ(shell()->web_contents()->GetURL(), kInitialUrl);
// Wait until the completion of prerendering. // Add <link rel=prerender> that will prerender `kPrerenderingUrl`.
navigation_observer.Wait(); ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
AddPrerender(kPrerenderingUrl);
// A request should be issued for `kPrerenderingUrl`.
EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1); EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
// PrerenderHost for `kPrerenderingUrl` should be registered in // A prerender host for the URL should be registered.
// PrerenderHostRegistry.
PrerenderHostRegistry& registry = GetPrerenderHostRegistry(); PrerenderHostRegistry& registry = GetPrerenderHostRegistry();
EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl), nullptr); EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl), nullptr);
// Activate the prerendered page. NavigateToURL() is not available here // Activate the prerendered page.
// because the helper accesses the predecessor WebContents but it is destroyed NavigateWithLocation(kPrerenderingUrl);
// during activation.
EXPECT_EQ(shell()->web_contents()->GetURL(), kInitialUrl); // The prerender host should be consumed.
content::TestNavigationObserver activation_observer(shell()->web_contents());
EXPECT_TRUE(ExecJs(shell()->web_contents(),
JsReplace("location = $1", kPrerenderingUrl)));
activation_observer.Wait();
EXPECT_EQ(shell()->web_contents()->GetURL(), kPrerenderingUrl);
// PrerenderHost for `kPrerenderingUrl` should be consumed.
EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl), nullptr); EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl), nullptr);
if (IsActivationDisabled()) { if (IsActivationDisabled()) {
...@@ -135,45 +151,33 @@ IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, LinkRelPrerender) { ...@@ -135,45 +151,33 @@ IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, LinkRelPrerender) {
} }
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, LinkRelPrerender_Multiple) { IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, LinkRelPrerender_Multiple) {
const GURL kInitialUrl = GetUrl("/prerender/multiple_prerenders.html"); const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
const GURL kPrerenderingUrl1 = GetUrl("/empty.html?1"); const GURL kPrerenderingUrl1 = GetUrl("/empty.html?1");
const GURL kPrerenderingUrl2 = GetUrl("/empty.html?2"); const GURL kPrerenderingUrl2 = GetUrl("/empty.html?2");
// Start watching new web contents to be created for prerendering. // Navigate to an initial page.
content::TestNavigationObserver navigation_observer1(kPrerenderingUrl1);
content::TestNavigationObserver navigation_observer2(kPrerenderingUrl2);
navigation_observer1.StartWatchingNewWebContents();
navigation_observer2.StartWatchingNewWebContents();
// Navigate to a page that initiates prerendering for `kPrerenderingUrl1` and
// `kPrerenderingUrl2`.
ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
ASSERT_EQ(shell()->web_contents()->GetURL(), kInitialUrl);
// Wait until the completion of prerendering. // Add <link rel=prerender> that will prerender `kPrerenderingUrl1` and
navigation_observer1.Wait(); // `kPrerenderingUrl2`.
navigation_observer2.Wait(); ASSERT_EQ(GetRequestCount(kPrerenderingUrl1), 0);
ASSERT_EQ(GetRequestCount(kPrerenderingUrl2), 0);
// Requests should be issued for `kPrerenderingUrl1` and `kPrerenderingUrl2`. AddPrerender(kPrerenderingUrl1);
AddPrerender(kPrerenderingUrl2);
EXPECT_EQ(GetRequestCount(kPrerenderingUrl1), 1); EXPECT_EQ(GetRequestCount(kPrerenderingUrl1), 1);
EXPECT_EQ(GetRequestCount(kPrerenderingUrl2), 1); EXPECT_EQ(GetRequestCount(kPrerenderingUrl2), 1);
// PrerenderHosts for `kPrerenderingUrl1` and `kPrerenderingUrl2` should be // Prerender hosts for `kPrerenderingUrl1` and `kPrerenderingUrl2` should be
// registered in PrerenderHostRegistry. // registered.
PrerenderHostRegistry& registry = GetPrerenderHostRegistry(); PrerenderHostRegistry& registry = GetPrerenderHostRegistry();
EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl1), nullptr); EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl1), nullptr);
EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl2), nullptr); EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl2), nullptr);
// Activate the prerendered page. NavigateToURL() is not available here // Activate the prerendered page.
// because the helper accesses the predecessor WebContents but it is destroyed NavigateWithLocation(kPrerenderingUrl2);
// during activation.
EXPECT_EQ(shell()->web_contents()->GetURL(), kInitialUrl); // The prerender hosts should be consumed or destroyed for activation.
content::TestNavigationObserver activation_observer(shell()->web_contents());
EXPECT_TRUE(ExecJs(shell()->web_contents(),
JsReplace("location = $1", kPrerenderingUrl2)));
activation_observer.Wait();
EXPECT_EQ(shell()->web_contents()->GetURL(), kPrerenderingUrl2);
// PrerenderHosts should be consumed or destroyed for activation.
EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl1), nullptr); EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl1), nullptr);
EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl2), nullptr); EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl2), nullptr);
...@@ -211,23 +215,17 @@ IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, LinkRelPrerender_Duplicate) { ...@@ -211,23 +215,17 @@ IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, LinkRelPrerender_Duplicate) {
EXPECT_EQ(GetRequestCount(kPrerenderingUrl1), 1); EXPECT_EQ(GetRequestCount(kPrerenderingUrl1), 1);
EXPECT_EQ(GetRequestCount(kPrerenderingUrl2), 1); EXPECT_EQ(GetRequestCount(kPrerenderingUrl2), 1);
// PrerenderHosts for `kPrerenderingUrl1` and `kPrerenderingUrl2` should be // Prerender hosts for `kPrerenderingUrl1` and `kPrerenderingUrl2` should be
// registered in PrerenderHostRegistry. // registered.
PrerenderHostRegistry& registry = GetPrerenderHostRegistry(); PrerenderHostRegistry& registry = GetPrerenderHostRegistry();
EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl1), nullptr); EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl1), nullptr);
EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl2), nullptr); EXPECT_NE(registry.FindHostByUrlForTesting(kPrerenderingUrl2), nullptr);
// Activate the prerendered page. NavigateToURL() is not available here // Activate the prerendered page.
// because the helper accesses the predecessor WebContents but it is destroyed NavigateWithLocation(kPrerenderingUrl1);
// during activation.
EXPECT_EQ(shell()->web_contents()->GetURL(), kInitialUrl);
content::TestNavigationObserver activation_observer(shell()->web_contents());
EXPECT_TRUE(ExecJs(shell()->web_contents(),
JsReplace("location = $1", kPrerenderingUrl1)));
activation_observer.Wait();
EXPECT_EQ(shell()->web_contents()->GetURL(), kPrerenderingUrl1); EXPECT_EQ(shell()->web_contents()->GetURL(), kPrerenderingUrl1);
// PrerenderHosts should be consumed or destroyed for activation. // The prerender hosts should be consumed or destroyed for activation.
EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl1), nullptr); EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl1), nullptr);
EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl2), nullptr); EXPECT_EQ(registry.FindHostByUrlForTesting(kPrerenderingUrl2), nullptr);
......
<!DOCTYPE html>
<html>
<head></head>
<body></body>
<script>
// Adds <link rel=prerender> for the URL.
function add_prerender(url) {
const link = document.createElement('link');
link.rel = 'prerender';
link.href = url;
document.head.appendChild(link);
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Multiple Prerenders Test</title>
<link rel="prerender" href="/empty.html?1">
<link rel="prerender" href="/empty.html?2">
</head>
<body></body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Single Prerender Test</title>
<link rel="prerender" href="/empty.html">
</head>
<body></body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment