Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: content/browser/top_document_isolation_browsertest.cc

Issue 1797363002: "Top Document Isolation" mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Suppress tests under --site-per-process Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/site_instance_impl.cc ('k') | content/common/site_isolation_policy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string>
6
7 #include "base/command_line.h"
8 #include "content/browser/frame_host/frame_tree_node.h"
9 #include "content/browser/web_contents/web_contents_impl.h"
10 #include "content/public/common/content_switches.h"
11 #include "content/public/test/browser_test_utils.h"
12 #include "content/public/test/content_browser_test.h"
13 #include "content/public/test/content_browser_test_utils.h"
14 #include "content/public/test/test_navigation_observer.h"
15 #include "content/shell/browser/shell.h"
16 #include "content/test/content_browser_test_utils_internal.h"
17 #include "content/test/test_frame_navigation_observer.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "net/test/embedded_test_server/embedded_test_server.h"
20 #include "url/gurl.h"
21
22 namespace content {
23
24 class TopDocumentIsolationTest : public ContentBrowserTest {
25 public:
26 TopDocumentIsolationTest() {}
27
28 protected:
29 std::string DepictFrameTree(FrameTreeNode* node) {
30 return visualizer_.DepictFrameTree(node);
31 }
32
33 void SetUpCommandLine(base::CommandLine* command_line) override {
34 command_line->AppendSwitch(switches::kTopDocumentIsolation);
35 }
36
37 void SetUpOnMainThread() override {
38 host_resolver()->AddRule("*", "127.0.0.1");
39 ASSERT_TRUE(embedded_test_server()->Start());
40 SetupCrossSiteRedirector(embedded_test_server());
41 }
42
43 FrameTreeNode* root() {
44 return static_cast<WebContentsImpl*>(shell()->web_contents())
45 ->GetFrameTree()
46 ->root();
47 }
48
49 void GoBack() {
50 TestNavigationObserver back_load_observer(shell()->web_contents());
51 shell()->web_contents()->GetController().GoBack();
52 back_load_observer.Wait();
53 }
54
55 Shell* OpenPopup(FrameTreeNode* opener, const std::string& url) {
56 GURL gurl =
57 opener->current_frame_host()->GetLastCommittedURL().Resolve(url);
58 return content::OpenPopup(opener->current_frame_host(), gurl, "_blank");
59 }
60
61 void RendererInitiatedNavigateToURL(FrameTreeNode* node, const GURL& url) {
62 TestFrameNavigationObserver nav_observer(node);
63 ASSERT_TRUE(ExecuteScript(node->current_frame_host(),
64 "window.location.href='" + url.spec() + "'"));
65 nav_observer.Wait();
66 }
67
68 private:
69 FrameTreeVisualizer visualizer_;
70 };
71
72 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, SameSiteDeeplyNested) {
73 if (content::AreAllSitesIsolatedForTesting())
74 return; // Top Document Isolation is disabled in this mode.
75
76 GURL main_url(embedded_test_server()->GetURL(
77 "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
78
79 NavigateToURL(shell(), main_url);
80
81 EXPECT_EQ(
82 " Site A\n"
83 " |--Site A\n"
84 " +--Site A\n"
85 " |--Site A\n"
86 " +--Site A\n"
87 " +--Site A\n"
88 "Where A = http://a.com/",
89 DepictFrameTree(root()));
90 }
91
92 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, CrossSiteDeeplyNested) {
93 if (content::AreAllSitesIsolatedForTesting())
94 return; // Top Document Isolation is disabled in this mode.
95
96 GURL main_url(embedded_test_server()->GetURL(
97 "a.com", "/cross_site_iframe_factory.html?a(b(c(d(b))))"));
98
99 NavigateToURL(shell(), main_url);
100
101 EXPECT_EQ(
102 " Site A ------------ proxies for B\n"
103 " +--Site B ------- proxies for A\n"
104 " +--Site B -- proxies for A\n"
105 " +--Site B -- proxies for A\n"
106 " +--Site B -- proxies for A\n"
107 "Where A = http://a.com/\n"
108 " B = default subframe process",
109 DepictFrameTree(root()));
110 }
111
112 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, ReturnToTopSite) {
113 if (content::AreAllSitesIsolatedForTesting())
114 return; // Top Document Isolation is disabled in this mode.
115
116 GURL main_url(embedded_test_server()->GetURL(
117 "a.com", "/cross_site_iframe_factory.html?a(b(a(c)))"));
118
119 NavigateToURL(shell(), main_url);
120
121 EXPECT_EQ(
122 " Site A ------------ proxies for B\n"
123 " +--Site B ------- proxies for A\n"
124 " +--Site A -- proxies for B\n"
125 " +--Site B -- proxies for A\n"
126 "Where A = http://a.com/\n"
127 " B = default subframe process",
128 DepictFrameTree(root()));
129 }
130
131 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateSubframeToTopSite) {
132 if (content::AreAllSitesIsolatedForTesting())
133 return; // Top Document Isolation is disabled in this mode.
134
135 GURL main_url(embedded_test_server()->GetURL(
136 "a.com", "/cross_site_iframe_factory.html?a(b(c(d)))"));
137
138 NavigateToURL(shell(), main_url);
139
140 EXPECT_EQ(
141 " Site A ------------ proxies for B\n"
142 " +--Site B ------- proxies for A\n"
143 " +--Site B -- proxies for A\n"
144 " +--Site B -- proxies for A\n"
145 "Where A = http://a.com/\n"
146 " B = default subframe process",
147 DepictFrameTree(root()));
148
149 GURL ada_url(embedded_test_server()->GetURL(
150 "a.com", "/cross_site_iframe_factory.html?a(d(a))"));
151 RendererInitiatedNavigateToURL(root()->child_at(0)->child_at(0), ada_url);
152
153 EXPECT_EQ(
154 " Site A ------------ proxies for B\n"
155 " +--Site B ------- proxies for A\n"
156 " +--Site A -- proxies for B\n"
157 " +--Site B -- proxies for A\n"
158 " +--Site A -- proxies for B\n"
159 "Where A = http://a.com/\n"
160 " B = default subframe process",
161 DepictFrameTree(root()));
162 }
163
164 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateToSubframeSite) {
165 if (content::AreAllSitesIsolatedForTesting())
166 return; // Top Document Isolation is disabled in this mode.
167
168 GURL ab_url(embedded_test_server()->GetURL(
169 "a.com", "/cross_site_iframe_factory.html?a(b)"));
170 GURL ba_url(embedded_test_server()->GetURL(
171 "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
172
173 NavigateToURL(shell(), ab_url);
174
175 EXPECT_EQ(
176 " Site A ------------ proxies for B\n"
177 " +--Site B ------- proxies for A\n"
178 "Where A = http://a.com/\n"
179 " B = default subframe process",
180 DepictFrameTree(root()));
181
182 NavigateToURL(shell(), ba_url);
183
184 EXPECT_EQ(
185 " Site C ------------ proxies for B\n"
186 " |--Site B ------- proxies for C\n"
187 " +--Site B ------- proxies for C\n"
188 "Where B = default subframe process\n"
189 " C = http://b.com/",
190 DepictFrameTree(root()));
191 }
192
193 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest,
194 NavigateToSubframeSiteWithPopup) {
195 if (content::AreAllSitesIsolatedForTesting())
196 return; // Top Document Isolation is disabled in this mode.
197
198 // A(B) -> B(A), but while a separate B(A) popup exists.
199 GURL ab_url(embedded_test_server()->GetURL(
200 "a.com", "/cross_site_iframe_factory.html?a(b)"));
201
202 NavigateToURL(shell(), ab_url);
203
204 EXPECT_EQ(
205 " Site A ------------ proxies for B\n"
206 " +--Site B ------- proxies for A\n"
207 "Where A = http://a.com/\n"
208 " B = default subframe process",
209 DepictFrameTree(root()));
210
211 Shell* popup =
212 OpenPopup(root()->child_at(0), "/cross_site_iframe_factory.html?b(a)");
213 FrameTreeNode* popup_root =
214 static_cast<WebContentsImpl*>(popup->web_contents())
215 ->GetFrameTree()
216 ->root();
217
218 // This popup's main frame must stay in the default subframe siteinstance,
219 // since its opener (the b.com subframe) may synchronously script it. Note
220 // that the popup's subframe is same-site with window.top.opener.top, the
221 // a.com main frame of the tab. But --top-document-isolation does not
222 // currently place the popup subframe in the a.com process in this case.
223 EXPECT_EQ(
224 " Site B\n"
225 " +--Site B\n"
226 "Where B = default subframe process",
227 DepictFrameTree(popup_root));
228
229 GURL ba_url(embedded_test_server()->GetURL(
230 "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
231 NavigateToURL(shell(), ba_url);
232
233 // This navigation destroys the popup's opener, so we allow the main frame to
234 // commit in a top level process for b.com, in spite of the b.com popup in the
235 // default subframe process.
236 EXPECT_EQ(
237 " Site C ------------ proxies for B\n"
238 " |--Site B ------- proxies for C\n"
239 " +--Site B ------- proxies for C\n"
240 "Where B = default subframe process\n"
241 " C = http://b.com/",
242 DepictFrameTree(root()));
243 EXPECT_EQ(
244 " Site B\n"
245 " +--Site B\n"
246 "Where B = default subframe process",
247 DepictFrameTree(popup_root));
248
249 // Navigate the popup to a new site.
250 GURL c_url(embedded_test_server()->GetURL(
251 "c.com", "/cross_site_iframe_factory.html?c(c, c, c, c)"));
252 NavigateToURL(popup, c_url);
253 EXPECT_EQ(
254 " Site D ------------ proxies for B\n"
255 " |--Site D ------- proxies for B\n"
256 " |--Site D ------- proxies for B\n"
257 " |--Site D ------- proxies for B\n"
258 " +--Site D ------- proxies for B\n"
259 "Where B = default subframe process\n"
260 " D = http://c.com/",
261 DepictFrameTree(popup_root));
262 NavigateToURL(shell(), c_url);
263 EXPECT_EQ(
264 " Site D\n"
265 " |--Site D\n"
266 " |--Site D\n"
267 " |--Site D\n"
268 " +--Site D\n"
269 "Where D = http://c.com/",
270 DepictFrameTree(popup_root));
271 EXPECT_EQ(
272 " Site D\n"
273 " |--Site D\n"
274 " |--Site D\n"
275 " |--Site D\n"
276 " +--Site D\n"
277 "Where D = http://c.com/",
278 DepictFrameTree(root()));
279 }
280
281 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest,
282 NavigateToSubframeSiteWithPopup2) {
283 if (content::AreAllSitesIsolatedForTesting())
284 return; // Top Document Isolation is disabled in this mode.
285
286 // A(B, C) -> C(A, B), but while a separate C(A) popup exists.
287 //
288 // This test is constructed so that c.com is the second site to commit in the
289 // default subframe SiteInstance, so the default subframe SiteInstance does
290 // not have a "c.com" as the value of GetSiteURL().
291 GURL abb_url(embedded_test_server()->GetURL(
292 "a.com", "/cross_site_iframe_factory.html?a(b, b)"));
293
294 NavigateToURL(shell(), abb_url);
295
296 EXPECT_EQ(
297 " Site A ------------ proxies for B\n"
298 " |--Site B ------- proxies for A\n"
299 " +--Site B ------- proxies for A\n"
300 "Where A = http://a.com/\n"
301 " B = default subframe process",
302 DepictFrameTree(root()));
303
304 // A(B, B) -> A(B, C)
305 GURL c_url(embedded_test_server()->GetURL(
306 "c.com", "/cross_site_iframe_factory.html?c"));
307 NavigateFrameToURL(root()->child_at(1), c_url);
308
309 EXPECT_EQ(
310 " Site A ------------ proxies for B\n"
311 " |--Site B ------- proxies for A\n"
312 " +--Site B ------- proxies for A\n"
313 "Where A = http://a.com/\n"
314 " B = default subframe process",
315 DepictFrameTree(root()));
316
317 // This test exercises what happens when the SiteURL of the default subframe
318 // siteinstance doesn't match the subframe site.
319 EXPECT_NE("c.com", root()
320 ->child_at(1)
321 ->current_frame_host()
322 ->GetSiteInstance()
323 ->GetSiteURL()
324 .host());
325
326 // Subframe C creates C(A) popup.
327 Shell* popup =
328 OpenPopup(root()->child_at(1), "/cross_site_iframe_factory.html?c(a)");
329
330 FrameTreeNode* popup_root =
331 static_cast<WebContentsImpl*>(popup->web_contents())
332 ->GetFrameTree()
333 ->root();
334
335 // The popup must stay with its opener, in the default subframe process.
336 EXPECT_EQ(
337 " Site B\n"
338 " +--Site B\n"
339 "Where B = default subframe process",
340 DepictFrameTree(popup_root));
341
342 GURL cab_url(embedded_test_server()->GetURL(
343 "c.com", "/cross_site_iframe_factory.html?c(a, b)"));
344 NavigateToURL(shell(), cab_url);
345
346 // This c.com navigation currently breaks out of the default subframe process,
347 // even though that process houses a c.com pop-up.
348 EXPECT_EQ(
349 " Site C ------------ proxies for B\n"
350 " |--Site B ------- proxies for C\n"
351 " +--Site B ------- proxies for C\n"
352 "Where B = default subframe process\n"
353 " C = http://c.com/",
354 DepictFrameTree(root()));
355
356 // c.com popup should remain where it was, in the subframe process.
357 EXPECT_EQ(
358 " Site B\n"
359 " +--Site B\n"
360 "Where B = default subframe process",
361 DepictFrameTree(popup_root));
362 EXPECT_EQ(nullptr, popup_root->opener());
363
364 // If we navigate the popup to a new site, it ought to transfer processes.
365 GURL d_url(embedded_test_server()->GetURL(
366 "d.com", "/cross_site_iframe_factory.html?d"));
367 NavigateToURL(popup, d_url);
368 EXPECT_EQ(
369 " Site D ------------ proxies for B\n"
370 "Where B = default subframe process\n"
371 " D = http://d.com/",
372 DepictFrameTree(popup_root));
373 NavigateToURL(shell(), d_url);
374 EXPECT_EQ(
375 " Site D\n"
376 "Where D = http://d.com/",
377 DepictFrameTree(popup_root));
378 EXPECT_EQ(
379 " Site D\n"
380 "Where D = http://d.com/",
381 DepictFrameTree(root()));
382 }
383
384 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, FramesForSitesInHistory) {
385 if (content::AreAllSitesIsolatedForTesting())
386 return; // Top Document Isolation is disabled in this mode.
387
388 // First, do a series of navigations.
389 GURL a_url = embedded_test_server()->GetURL(
390 "a.com", "/cross_site_iframe_factory.html?a");
391 GURL b_url = embedded_test_server()->GetURL(
392 "b.com", "/cross_site_iframe_factory.html?b");
393 GURL c_url = embedded_test_server()->GetURL(
394 "c.com", "/cross_site_iframe_factory.html?c");
395
396 // Browser-initiated navigation to a.com.
397 NavigateToURL(shell(), a_url);
398 EXPECT_EQ(
399 " Site A\n"
400 "Where A = http://a.com/",
401 DepictFrameTree(root()));
402
403 // Browser-initiated navigation to b.com.
404 NavigateToURL(shell(), b_url);
405 EXPECT_EQ(
406 " Site B\n"
407 "Where B = http://b.com/",
408 DepictFrameTree(root()));
409
410 // Renderer-initiated navigation back to a.com. This shouldn't swap processes.
411 RendererInitiatedNavigateToURL(root(), a_url);
412 EXPECT_EQ(
413 " Site B\n"
414 "Where B = http://b.com/",
415 DepictFrameTree(root()));
416
417 // Browser-initiated navigation to c.com.
418 NavigateToURL(shell(), c_url);
419 EXPECT_EQ(
420 " Site C\n"
421 "Where C = http://c.com/",
422 DepictFrameTree(root()));
423
424 // Now, navigate to a fourth site with iframes to the sites in the history.
425 NavigateToURL(shell(),
426 embedded_test_server()->GetURL(
427 "d.com", "/cross_site_iframe_factory.html?d(a,b,c)"));
428
429 EXPECT_EQ(
430 " Site D ------------ proxies for E\n"
431 " |--Site E ------- proxies for D\n"
432 " |--Site E ------- proxies for D\n"
433 " +--Site E ------- proxies for D\n"
434 "Where D = http://d.com/\n"
435 " E = default subframe process",
436 DepictFrameTree(root()));
437
438 // Now try going back.
439 GoBack();
440 EXPECT_EQ(
441 " Site C\n"
442 "Where C = http://c.com/",
443 DepictFrameTree(root()));
444 GoBack();
445 EXPECT_EQ(
446 " Site B\n"
447 "Where B = http://b.com/",
448 DepictFrameTree(root()));
449 GoBack();
450 EXPECT_EQ(
451 " Site B\n"
452 "Where B = http://b.com/",
453 DepictFrameTree(root()));
454 GoBack();
455 EXPECT_EQ(
456 " Site A\n"
457 "Where A = http://a.com/",
458 DepictFrameTree(root()));
459 }
460
461 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, CrossSiteAtLevelTwo) {
462 if (content::AreAllSitesIsolatedForTesting())
463 return; // Top Document Isolation is disabled in this mode.
464
465 GURL main_url(embedded_test_server()->GetURL(
466 "a.com", "/cross_site_iframe_factory.html?a(a(b, a))"));
467
468 NavigateToURL(shell(), main_url);
469
470 EXPECT_EQ(
471 " Site A ------------ proxies for B\n"
472 " +--Site A ------- proxies for B\n"
473 " |--Site B -- proxies for A\n"
474 " +--Site A -- proxies for B\n"
475 "Where A = http://a.com/\n"
476 " B = default subframe process",
477 DepictFrameTree(root()));
478
479 GURL c_url(embedded_test_server()->GetURL(
480 "c.com", "/cross_site_iframe_factory.html?c"));
481 NavigateFrameToURL(root()->child_at(0)->child_at(1), c_url);
482
483 // This navigation should complete in the default subframe siteinstance.
484 EXPECT_EQ(
485 " Site A ------------ proxies for B\n"
486 " +--Site A ------- proxies for B\n"
487 " |--Site B -- proxies for A\n"
488 " +--Site B -- proxies for A\n"
489 "Where A = http://a.com/\n"
490 " B = default subframe process",
491 DepictFrameTree(root()));
492 }
493
494 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, PopupAndRedirection) {
495 if (content::AreAllSitesIsolatedForTesting())
496 return; // Top Document Isolation is disabled in this mode.
497
498 GURL main_url(embedded_test_server()->GetURL(
499 "page.com", "/cross_site_iframe_factory.html?page(adnetwork)"));
500
501 // User opens page on page.com which contains a subframe from adnetwork.com.
502 NavigateToURL(shell(), main_url);
503
504 EXPECT_EQ(
505 " Site A ------------ proxies for B\n"
506 " +--Site B ------- proxies for A\n"
507 "Where A = http://page.com/\n"
508 " B = default subframe process",
509 DepictFrameTree(root()));
510
511 GURL ad_url(embedded_test_server()->GetURL(
512 "ad.com", "/cross_site_iframe_factory.html?ad"));
513
514 // adnetwork.com retrieves an ad from advertiser (ad.com) and redirects the
515 // subframe to ad.com.
516 RendererInitiatedNavigateToURL(root()->child_at(0), ad_url);
517
518 // The subframe still uses the default subframe SiteInstance after navigation.
519 EXPECT_EQ(
520 " Site A ------------ proxies for B\n"
521 " +--Site B ------- proxies for A\n"
522 "Where A = http://page.com/\n"
523 " B = default subframe process",
524 DepictFrameTree(root()));
525
526 // User clicks the ad in the subframe, which opens a popup on the ad
527 // network's domain.
528 GURL popup_url(embedded_test_server()->GetURL(
529 "adnetwork.com", "/cross_site_iframe_factory.html?adnetwork"));
530 Shell* popup = OpenPopup(root()->child_at(0), popup_url.spec());
531
532 FrameTreeNode* popup_root =
533 static_cast<WebContentsImpl*>(popup->web_contents())
534 ->GetFrameTree()
535 ->root();
536
537 // It's ok for the popup to break out of the subframe process because it's
538 // currently cross-site from its opener frame.
539 EXPECT_EQ(
540 " Site C ------------ proxies for B\n"
541 "Where B = default subframe process\n"
542 " C = http://adnetwork.com/",
543 DepictFrameTree(popup_root));
544
545 EXPECT_EQ(
546 " Site A ------------ proxies for B C\n"
547 " +--Site B ------- proxies for A C\n"
548 "Where A = http://page.com/\n"
549 " B = default subframe process\n"
550 " C = http://adnetwork.com/",
551 DepictFrameTree(root()));
552
553 // The popup redirects itself to the advertiser's website (ad.com).
554 RendererInitiatedNavigateToURL(popup_root, ad_url);
555
556 // This must join its same-site opener, in the default subframe SiteInstance.
557 EXPECT_EQ(
558 " Site A ------------ proxies for B C\n"
559 " +--Site B ------- proxies for A C\n"
560 "Where A = http://page.com/\n"
561 " B = default subframe process\n"
562 " C = http://adnetwork.com/",
563 DepictFrameTree(root()));
564 EXPECT_EQ(
565 " Site C ------------ proxies for B\n"
566 "Where B = default subframe process\n"
567 " C = http://adnetwork.com/",
568 DepictFrameTree(popup_root));
569 }
570
571 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/site_instance_impl.cc ('k') | content/common/site_isolation_policy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698