| Index: content/browser/top_document_isolation_browsertest.cc
|
| diff --git a/content/browser/top_document_isolation_browsertest.cc b/content/browser/top_document_isolation_browsertest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..dd4541f23185caed04f5107cef2316f837af94ba
|
| --- /dev/null
|
| +++ b/content/browser/top_document_isolation_browsertest.cc
|
| @@ -0,0 +1,571 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/command_line.h"
|
| +#include "content/browser/frame_host/frame_tree_node.h"
|
| +#include "content/browser/web_contents/web_contents_impl.h"
|
| +#include "content/public/common/content_switches.h"
|
| +#include "content/public/test/browser_test_utils.h"
|
| +#include "content/public/test/content_browser_test.h"
|
| +#include "content/public/test/content_browser_test_utils.h"
|
| +#include "content/public/test/test_navigation_observer.h"
|
| +#include "content/shell/browser/shell.h"
|
| +#include "content/test/content_browser_test_utils_internal.h"
|
| +#include "content/test/test_frame_navigation_observer.h"
|
| +#include "net/dns/mock_host_resolver.h"
|
| +#include "net/test/embedded_test_server/embedded_test_server.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace content {
|
| +
|
| +class TopDocumentIsolationTest : public ContentBrowserTest {
|
| + public:
|
| + TopDocumentIsolationTest() {}
|
| +
|
| + protected:
|
| + std::string DepictFrameTree(FrameTreeNode* node) {
|
| + return visualizer_.DepictFrameTree(node);
|
| + }
|
| +
|
| + void SetUpCommandLine(base::CommandLine* command_line) override {
|
| + command_line->AppendSwitch(switches::kTopDocumentIsolation);
|
| + }
|
| +
|
| + void SetUpOnMainThread() override {
|
| + host_resolver()->AddRule("*", "127.0.0.1");
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| + SetupCrossSiteRedirector(embedded_test_server());
|
| + }
|
| +
|
| + FrameTreeNode* root() {
|
| + return static_cast<WebContentsImpl*>(shell()->web_contents())
|
| + ->GetFrameTree()
|
| + ->root();
|
| + }
|
| +
|
| + void GoBack() {
|
| + TestNavigationObserver back_load_observer(shell()->web_contents());
|
| + shell()->web_contents()->GetController().GoBack();
|
| + back_load_observer.Wait();
|
| + }
|
| +
|
| + Shell* OpenPopup(FrameTreeNode* opener, const std::string& url) {
|
| + GURL gurl =
|
| + opener->current_frame_host()->GetLastCommittedURL().Resolve(url);
|
| + return content::OpenPopup(opener->current_frame_host(), gurl, "_blank");
|
| + }
|
| +
|
| + void RendererInitiatedNavigateToURL(FrameTreeNode* node, const GURL& url) {
|
| + TestFrameNavigationObserver nav_observer(node);
|
| + ASSERT_TRUE(ExecuteScript(node->current_frame_host(),
|
| + "window.location.href='" + url.spec() + "'"));
|
| + nav_observer.Wait();
|
| + }
|
| +
|
| + private:
|
| + FrameTreeVisualizer visualizer_;
|
| +};
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, SameSiteDeeplyNested) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + GURL main_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
|
| +
|
| + NavigateToURL(shell(), main_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A\n"
|
| + " |--Site A\n"
|
| + " +--Site A\n"
|
| + " |--Site A\n"
|
| + " +--Site A\n"
|
| + " +--Site A\n"
|
| + "Where A = http://a.com/",
|
| + DepictFrameTree(root()));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, CrossSiteDeeplyNested) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + GURL main_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(b(c(d(b))))"));
|
| +
|
| + NavigateToURL(shell(), main_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + " +--Site B -- proxies for A\n"
|
| + " +--Site B -- proxies for A\n"
|
| + " +--Site B -- proxies for A\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, ReturnToTopSite) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + GURL main_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(b(a(c)))"));
|
| +
|
| + NavigateToURL(shell(), main_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + " +--Site A -- proxies for B\n"
|
| + " +--Site B -- proxies for A\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateSubframeToTopSite) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + GURL main_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(b(c(d)))"));
|
| +
|
| + NavigateToURL(shell(), main_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + " +--Site B -- proxies for A\n"
|
| + " +--Site B -- proxies for A\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +
|
| + GURL ada_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(d(a))"));
|
| + RendererInitiatedNavigateToURL(root()->child_at(0)->child_at(0), ada_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + " +--Site A -- proxies for B\n"
|
| + " +--Site B -- proxies for A\n"
|
| + " +--Site A -- proxies for B\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateToSubframeSite) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + GURL ab_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(b)"));
|
| + GURL ba_url(embedded_test_server()->GetURL(
|
| + "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
|
| +
|
| + NavigateToURL(shell(), ab_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +
|
| + NavigateToURL(shell(), ba_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site C ------------ proxies for B\n"
|
| + " |--Site B ------- proxies for C\n"
|
| + " +--Site B ------- proxies for C\n"
|
| + "Where B = default subframe process\n"
|
| + " C = http://b.com/",
|
| + DepictFrameTree(root()));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest,
|
| + NavigateToSubframeSiteWithPopup) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + // A(B) -> B(A), but while a separate B(A) popup exists.
|
| + GURL ab_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(b)"));
|
| +
|
| + NavigateToURL(shell(), ab_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +
|
| + Shell* popup =
|
| + OpenPopup(root()->child_at(0), "/cross_site_iframe_factory.html?b(a)");
|
| + FrameTreeNode* popup_root =
|
| + static_cast<WebContentsImpl*>(popup->web_contents())
|
| + ->GetFrameTree()
|
| + ->root();
|
| +
|
| + // This popup's main frame must stay in the default subframe siteinstance,
|
| + // since its opener (the b.com subframe) may synchronously script it. Note
|
| + // that the popup's subframe is same-site with window.top.opener.top, the
|
| + // a.com main frame of the tab. But --top-document-isolation does not
|
| + // currently place the popup subframe in the a.com process in this case.
|
| + EXPECT_EQ(
|
| + " Site B\n"
|
| + " +--Site B\n"
|
| + "Where B = default subframe process",
|
| + DepictFrameTree(popup_root));
|
| +
|
| + GURL ba_url(embedded_test_server()->GetURL(
|
| + "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
|
| + NavigateToURL(shell(), ba_url);
|
| +
|
| + // This navigation destroys the popup's opener, so we allow the main frame to
|
| + // commit in a top level process for b.com, in spite of the b.com popup in the
|
| + // default subframe process.
|
| + EXPECT_EQ(
|
| + " Site C ------------ proxies for B\n"
|
| + " |--Site B ------- proxies for C\n"
|
| + " +--Site B ------- proxies for C\n"
|
| + "Where B = default subframe process\n"
|
| + " C = http://b.com/",
|
| + DepictFrameTree(root()));
|
| + EXPECT_EQ(
|
| + " Site B\n"
|
| + " +--Site B\n"
|
| + "Where B = default subframe process",
|
| + DepictFrameTree(popup_root));
|
| +
|
| + // Navigate the popup to a new site.
|
| + GURL c_url(embedded_test_server()->GetURL(
|
| + "c.com", "/cross_site_iframe_factory.html?c(c, c, c, c)"));
|
| + NavigateToURL(popup, c_url);
|
| + EXPECT_EQ(
|
| + " Site D ------------ proxies for B\n"
|
| + " |--Site D ------- proxies for B\n"
|
| + " |--Site D ------- proxies for B\n"
|
| + " |--Site D ------- proxies for B\n"
|
| + " +--Site D ------- proxies for B\n"
|
| + "Where B = default subframe process\n"
|
| + " D = http://c.com/",
|
| + DepictFrameTree(popup_root));
|
| + NavigateToURL(shell(), c_url);
|
| + EXPECT_EQ(
|
| + " Site D\n"
|
| + " |--Site D\n"
|
| + " |--Site D\n"
|
| + " |--Site D\n"
|
| + " +--Site D\n"
|
| + "Where D = http://c.com/",
|
| + DepictFrameTree(popup_root));
|
| + EXPECT_EQ(
|
| + " Site D\n"
|
| + " |--Site D\n"
|
| + " |--Site D\n"
|
| + " |--Site D\n"
|
| + " +--Site D\n"
|
| + "Where D = http://c.com/",
|
| + DepictFrameTree(root()));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest,
|
| + NavigateToSubframeSiteWithPopup2) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + // A(B, C) -> C(A, B), but while a separate C(A) popup exists.
|
| + //
|
| + // This test is constructed so that c.com is the second site to commit in the
|
| + // default subframe SiteInstance, so the default subframe SiteInstance does
|
| + // not have a "c.com" as the value of GetSiteURL().
|
| + GURL abb_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(b, b)"));
|
| +
|
| + NavigateToURL(shell(), abb_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " |--Site B ------- proxies for A\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +
|
| + // A(B, B) -> A(B, C)
|
| + GURL c_url(embedded_test_server()->GetURL(
|
| + "c.com", "/cross_site_iframe_factory.html?c"));
|
| + NavigateFrameToURL(root()->child_at(1), c_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " |--Site B ------- proxies for A\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +
|
| + // This test exercises what happens when the SiteURL of the default subframe
|
| + // siteinstance doesn't match the subframe site.
|
| + EXPECT_NE("c.com", root()
|
| + ->child_at(1)
|
| + ->current_frame_host()
|
| + ->GetSiteInstance()
|
| + ->GetSiteURL()
|
| + .host());
|
| +
|
| + // Subframe C creates C(A) popup.
|
| + Shell* popup =
|
| + OpenPopup(root()->child_at(1), "/cross_site_iframe_factory.html?c(a)");
|
| +
|
| + FrameTreeNode* popup_root =
|
| + static_cast<WebContentsImpl*>(popup->web_contents())
|
| + ->GetFrameTree()
|
| + ->root();
|
| +
|
| + // The popup must stay with its opener, in the default subframe process.
|
| + EXPECT_EQ(
|
| + " Site B\n"
|
| + " +--Site B\n"
|
| + "Where B = default subframe process",
|
| + DepictFrameTree(popup_root));
|
| +
|
| + GURL cab_url(embedded_test_server()->GetURL(
|
| + "c.com", "/cross_site_iframe_factory.html?c(a, b)"));
|
| + NavigateToURL(shell(), cab_url);
|
| +
|
| + // This c.com navigation currently breaks out of the default subframe process,
|
| + // even though that process houses a c.com pop-up.
|
| + EXPECT_EQ(
|
| + " Site C ------------ proxies for B\n"
|
| + " |--Site B ------- proxies for C\n"
|
| + " +--Site B ------- proxies for C\n"
|
| + "Where B = default subframe process\n"
|
| + " C = http://c.com/",
|
| + DepictFrameTree(root()));
|
| +
|
| + // c.com popup should remain where it was, in the subframe process.
|
| + EXPECT_EQ(
|
| + " Site B\n"
|
| + " +--Site B\n"
|
| + "Where B = default subframe process",
|
| + DepictFrameTree(popup_root));
|
| + EXPECT_EQ(nullptr, popup_root->opener());
|
| +
|
| + // If we navigate the popup to a new site, it ought to transfer processes.
|
| + GURL d_url(embedded_test_server()->GetURL(
|
| + "d.com", "/cross_site_iframe_factory.html?d"));
|
| + NavigateToURL(popup, d_url);
|
| + EXPECT_EQ(
|
| + " Site D ------------ proxies for B\n"
|
| + "Where B = default subframe process\n"
|
| + " D = http://d.com/",
|
| + DepictFrameTree(popup_root));
|
| + NavigateToURL(shell(), d_url);
|
| + EXPECT_EQ(
|
| + " Site D\n"
|
| + "Where D = http://d.com/",
|
| + DepictFrameTree(popup_root));
|
| + EXPECT_EQ(
|
| + " Site D\n"
|
| + "Where D = http://d.com/",
|
| + DepictFrameTree(root()));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, FramesForSitesInHistory) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + // First, do a series of navigations.
|
| + GURL a_url = embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a");
|
| + GURL b_url = embedded_test_server()->GetURL(
|
| + "b.com", "/cross_site_iframe_factory.html?b");
|
| + GURL c_url = embedded_test_server()->GetURL(
|
| + "c.com", "/cross_site_iframe_factory.html?c");
|
| +
|
| + // Browser-initiated navigation to a.com.
|
| + NavigateToURL(shell(), a_url);
|
| + EXPECT_EQ(
|
| + " Site A\n"
|
| + "Where A = http://a.com/",
|
| + DepictFrameTree(root()));
|
| +
|
| + // Browser-initiated navigation to b.com.
|
| + NavigateToURL(shell(), b_url);
|
| + EXPECT_EQ(
|
| + " Site B\n"
|
| + "Where B = http://b.com/",
|
| + DepictFrameTree(root()));
|
| +
|
| + // Renderer-initiated navigation back to a.com. This shouldn't swap processes.
|
| + RendererInitiatedNavigateToURL(root(), a_url);
|
| + EXPECT_EQ(
|
| + " Site B\n"
|
| + "Where B = http://b.com/",
|
| + DepictFrameTree(root()));
|
| +
|
| + // Browser-initiated navigation to c.com.
|
| + NavigateToURL(shell(), c_url);
|
| + EXPECT_EQ(
|
| + " Site C\n"
|
| + "Where C = http://c.com/",
|
| + DepictFrameTree(root()));
|
| +
|
| + // Now, navigate to a fourth site with iframes to the sites in the history.
|
| + NavigateToURL(shell(),
|
| + embedded_test_server()->GetURL(
|
| + "d.com", "/cross_site_iframe_factory.html?d(a,b,c)"));
|
| +
|
| + EXPECT_EQ(
|
| + " Site D ------------ proxies for E\n"
|
| + " |--Site E ------- proxies for D\n"
|
| + " |--Site E ------- proxies for D\n"
|
| + " +--Site E ------- proxies for D\n"
|
| + "Where D = http://d.com/\n"
|
| + " E = default subframe process",
|
| + DepictFrameTree(root()));
|
| +
|
| + // Now try going back.
|
| + GoBack();
|
| + EXPECT_EQ(
|
| + " Site C\n"
|
| + "Where C = http://c.com/",
|
| + DepictFrameTree(root()));
|
| + GoBack();
|
| + EXPECT_EQ(
|
| + " Site B\n"
|
| + "Where B = http://b.com/",
|
| + DepictFrameTree(root()));
|
| + GoBack();
|
| + EXPECT_EQ(
|
| + " Site B\n"
|
| + "Where B = http://b.com/",
|
| + DepictFrameTree(root()));
|
| + GoBack();
|
| + EXPECT_EQ(
|
| + " Site A\n"
|
| + "Where A = http://a.com/",
|
| + DepictFrameTree(root()));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, CrossSiteAtLevelTwo) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + GURL main_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(a(b, a))"));
|
| +
|
| + NavigateToURL(shell(), main_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site A ------- proxies for B\n"
|
| + " |--Site B -- proxies for A\n"
|
| + " +--Site A -- proxies for B\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +
|
| + GURL c_url(embedded_test_server()->GetURL(
|
| + "c.com", "/cross_site_iframe_factory.html?c"));
|
| + NavigateFrameToURL(root()->child_at(0)->child_at(1), c_url);
|
| +
|
| + // This navigation should complete in the default subframe siteinstance.
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site A ------- proxies for B\n"
|
| + " |--Site B -- proxies for A\n"
|
| + " +--Site B -- proxies for A\n"
|
| + "Where A = http://a.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, PopupAndRedirection) {
|
| + if (content::AreAllSitesIsolatedForTesting())
|
| + return; // Top Document Isolation is disabled in this mode.
|
| +
|
| + GURL main_url(embedded_test_server()->GetURL(
|
| + "page.com", "/cross_site_iframe_factory.html?page(adnetwork)"));
|
| +
|
| + // User opens page on page.com which contains a subframe from adnetwork.com.
|
| + NavigateToURL(shell(), main_url);
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + "Where A = http://page.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +
|
| + GURL ad_url(embedded_test_server()->GetURL(
|
| + "ad.com", "/cross_site_iframe_factory.html?ad"));
|
| +
|
| + // adnetwork.com retrieves an ad from advertiser (ad.com) and redirects the
|
| + // subframe to ad.com.
|
| + RendererInitiatedNavigateToURL(root()->child_at(0), ad_url);
|
| +
|
| + // The subframe still uses the default subframe SiteInstance after navigation.
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B\n"
|
| + " +--Site B ------- proxies for A\n"
|
| + "Where A = http://page.com/\n"
|
| + " B = default subframe process",
|
| + DepictFrameTree(root()));
|
| +
|
| + // User clicks the ad in the subframe, which opens a popup on the ad
|
| + // network's domain.
|
| + GURL popup_url(embedded_test_server()->GetURL(
|
| + "adnetwork.com", "/cross_site_iframe_factory.html?adnetwork"));
|
| + Shell* popup = OpenPopup(root()->child_at(0), popup_url.spec());
|
| +
|
| + FrameTreeNode* popup_root =
|
| + static_cast<WebContentsImpl*>(popup->web_contents())
|
| + ->GetFrameTree()
|
| + ->root();
|
| +
|
| + // It's ok for the popup to break out of the subframe process because it's
|
| + // currently cross-site from its opener frame.
|
| + EXPECT_EQ(
|
| + " Site C ------------ proxies for B\n"
|
| + "Where B = default subframe process\n"
|
| + " C = http://adnetwork.com/",
|
| + DepictFrameTree(popup_root));
|
| +
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B C\n"
|
| + " +--Site B ------- proxies for A C\n"
|
| + "Where A = http://page.com/\n"
|
| + " B = default subframe process\n"
|
| + " C = http://adnetwork.com/",
|
| + DepictFrameTree(root()));
|
| +
|
| + // The popup redirects itself to the advertiser's website (ad.com).
|
| + RendererInitiatedNavigateToURL(popup_root, ad_url);
|
| +
|
| + // This must join its same-site opener, in the default subframe SiteInstance.
|
| + EXPECT_EQ(
|
| + " Site A ------------ proxies for B C\n"
|
| + " +--Site B ------- proxies for A C\n"
|
| + "Where A = http://page.com/\n"
|
| + " B = default subframe process\n"
|
| + " C = http://adnetwork.com/",
|
| + DepictFrameTree(root()));
|
| + EXPECT_EQ(
|
| + " Site C ------------ proxies for B\n"
|
| + "Where B = default subframe process\n"
|
| + " C = http://adnetwork.com/",
|
| + DepictFrameTree(popup_root));
|
| +}
|
| +
|
| +} // namespace content
|
|
|