A random collection of useful things to know when writing browser tests.
If the test needs to use the return value of the script, use EvalJs()
:
// Works with numerical types... EXPECT_EQ(0, EvalJs(shell(), "1 * 0"); // ... string types ... EXPECT_EQ("BODY", EvalJs(shell(), "document.body.tagName"); // and booleans too. Note the explicit use of EXPECT_EQ() instead of // EXPECT_TRUE() or EXPECT_FALSE(); this is intentional, and the latter // will not compile. EXPECT_EQ(false, EvalJs(shell(), "2 + 2 == 5"));
Like many other test helpers (e.g. the navigation helpers), the first argument accepts RenderFrameHost
, WebContents
, and other types.
// Executes in the main frame. EXPECT_EQ(true, EvalJs(shell()->GetWebContents(), "window.top == window")); // Also executes in the main frame. EXPECT_EQ(true, EvalJs(shell(), "window.top == window")); // Executes in the first child frame of the main frame. EXPECT_EQ( false, EvalJs(ChildFrameAt(shell()->GetWebContents()->GetMainFrame(), 0), "window.top == window"));
Otherwise, simply use ExecJs()
:
EXPECT_TRUE(ExecJs("console.log('Hello world!')"));
Note that these helpers block until the script completes. For async execution, use ExecuteScriptAsync()
.
Finally, JsReplace()
provides a convenient way to build strings for script execution:
EXPECT_EQ("00", EvalJs(JsReplace("$1 + $2", 0, "0")));
For cross-origin navigations, it is to simplest to configure all hostnames to resolve to 127.0.0.1
in tests, using a snippet like this:
void SetUpOnMainThread() override { host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(embedded_test_server()->Start()); }
After that, EmbeddedTestServer::GetURL()
can be used to generate navigable URLs with the specific origin:
const GURL& url_a = embedded_test_server()->GetURL("a.com", "/title1.html"); const GURL& url_b = embedded_test_server()->GetURL("b.com", "/empty.html");
Most test resources are located in //content/test/data
, e.g. navigating to GetURL("a.com", "/title1.html")
will serve //content/test/data/title1.html
as the content.
Note: using arbitrary hostnames requires the host resolver to be correctly configured.
NavigateToURL()
begins and waits for the navigation to complete, as if the navigation was browser-initiated, e.g. from the omnibox:
GURL url(embedded_test_server()->GetURL("a.com", "/title1.html")); EXPECT_TRUE(NavigateToURL(shell(), url));
Note: NavigateToURL() allows subframes to be targetted, but outside of history navigations, subframe navigations are generally renderer-initiated.
Note: using arbitrary hostnames requires the host resolver to be correctly configured.
NavigateToURLFromRenderer()
begins and waits for the navigation to complete, as if the navigation was renderer-initiated, e.g. by setting window.location
:
// Navigates the main frame. GURL url_1(embedded_test_server()->GetURL("a.com", "/title1.html")); EXPECT_TRUE(NavigateToURLFromRenderer(shell()->GetWebContents(), url_1)); // Navigates the main frame too. GURL url_2(embedded_test_server()->GetURL("b.com", "/page_with_iframe.html")); EXPECT_TRUE(NavigateToURLFromRenderer(shell()->GetWebContents(), url_2)); // Navigates the first child frame. GURL url_3(embedded_test_server()->GetURL("a.com", "/empty.html")); EXPECT_TRUE( NavigateToURLFromRenderer( ChildFrameAt(shell()->GetWebContents()->GetMainFrame(), 0), url_3));
Note: using arbitrary hostnames requires the host resolver to be correctly configured.
cross_site_iframe_factory.html
is a helper that makes it easy to generate a page with an arbitrary frame tree by navigating to a URL. The query string to the URL allows configuration of the frame tree, the origin of each frame, and a number of other options:
GURL url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(b(a),c,example.com)")); EXPECT_TRUE(NavigateToURL(shell(), url));
Will generate a page with:
Main frame with origin `a.com` ├─ Child frame #1 with origin `b.com` │ └─ Grandchild frame with origin `a.com` ├─ Child frame #2 with origin `c.com` └─ Child frame #3 with origin `example.com`
<iframe>
with a specific originNote: using arbitrary hostnames requires the host resolver to be correctly configured.
Sometimes, a test page may need to embed a cross-origin URL. This is problematic for pages that contain only static HTML, as the embedded test server runs on a randomly selected port. Instead, static HTML can use the cross-site redirector to generate a cross-origin frame:
<!-- static_iframe.html --> <html> <body> <iframe src="/cross-site/b.com/title1.html"> </body> </iframe>
Important: the cross-site redirector is not enabled by default. Override SetUpOnMainThread()
to configure it like this:
void SetUpOnMainThread() override { ... SetupCrossSiteRedirector(embedded_test_server()); ... }
Navigates to a page that takes 60 seconds to load.
GURL url(embedded_test_server()->GetURL("/slow?60"); EXPECT_TRUE(NavigateToURL(shell(), url));
The embedded test server also registers other default handlers that may be useful.