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

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: Fix up tests. Necessary rebase to obtain browsertest util behavior change. 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
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 GURL main_url(embedded_test_server()->GetURL(
74 "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
75
76 NavigateToURL(shell(), main_url);
77
78 EXPECT_EQ(
79 " Site A\n"
80 " |--Site A\n"
81 " +--Site A\n"
82 " |--Site A\n"
83 " +--Site A\n"
84 " +--Site A\n"
85 "Where A = http://a.com/",
86 DepictFrameTree(root()));
87 }
88
89 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, CrossSiteDeeplyNested) {
90 GURL main_url(embedded_test_server()->GetURL(
91 "a.com", "/cross_site_iframe_factory.html?a(b(c(d(b))))"));
92
93 NavigateToURL(shell(), main_url);
94
95 EXPECT_EQ(
96 " Site A ------------ proxies for B\n"
97 " +--Site B ------- proxies for A\n"
98 " +--Site B -- proxies for A\n"
99 " +--Site B -- proxies for A\n"
100 " +--Site B -- proxies for A\n"
101 "Where A = http://a.com/\n"
102 " B = default subframe process",
103 DepictFrameTree(root()));
104 }
105
106 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, ReturnToTopSite) {
107 GURL main_url(embedded_test_server()->GetURL(
108 "a.com", "/cross_site_iframe_factory.html?a(b(a(c)))"));
109
110 NavigateToURL(shell(), main_url);
111
112 EXPECT_EQ(
113 " Site A ------------ proxies for B\n"
114 " +--Site B ------- proxies for A\n"
115 " +--Site A -- proxies for B\n"
116 " +--Site B -- proxies for A\n"
117 "Where A = http://a.com/\n"
118 " B = default subframe process",
119 DepictFrameTree(root()));
120 }
121
122 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateSubframeToTopSite) {
123 GURL main_url(embedded_test_server()->GetURL(
124 "a.com", "/cross_site_iframe_factory.html?a(b(c(d)))"));
125
126 NavigateToURL(shell(), main_url);
127
128 EXPECT_EQ(
129 " Site A ------------ proxies for B\n"
130 " +--Site B ------- proxies for A\n"
131 " +--Site B -- proxies for A\n"
132 " +--Site B -- proxies for A\n"
133 "Where A = http://a.com/\n"
134 " B = default subframe process",
135 DepictFrameTree(root()));
136
137 GURL ada_url(embedded_test_server()->GetURL(
138 "a.com", "/cross_site_iframe_factory.html?a(d(a))"));
139 RendererInitiatedNavigateToURL(root()->child_at(0)->child_at(0), ada_url);
140
141 EXPECT_EQ(
142 " Site A ------------ proxies for B\n"
143 " +--Site B ------- proxies for A\n"
144 " +--Site A -- proxies for B\n"
145 " +--Site B -- proxies for A\n"
146 " +--Site A -- proxies for B\n"
147 "Where A = http://a.com/\n"
148 " B = default subframe process",
149 DepictFrameTree(root()));
150 }
151
152 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateToSubframeSite) {
153 GURL ab_url(embedded_test_server()->GetURL(
154 "a.com", "/cross_site_iframe_factory.html?a(b)"));
155 GURL ba_url(embedded_test_server()->GetURL(
156 "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
157
158 NavigateToURL(shell(), ab_url);
159
160 EXPECT_EQ(
161 " Site A ------------ proxies for B\n"
162 " +--Site B ------- proxies for A\n"
163 "Where A = http://a.com/\n"
164 " B = default subframe process",
165 DepictFrameTree(root()));
166
167 NavigateToURL(shell(), ba_url);
168
169 EXPECT_EQ(
170 " Site C ------------ proxies for B\n"
171 " |--Site B ------- proxies for C\n"
172 " +--Site B ------- proxies for C\n"
173 "Where B = default subframe process\n"
174 " C = http://b.com/",
175 DepictFrameTree(root()));
176 }
177
178 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest,
179 NavigateToSubframeSiteWithPopup) {
180 // A(B) -> B(A), but while a separate B(A) popup exists.
181 GURL ab_url(embedded_test_server()->GetURL(
182 "a.com", "/cross_site_iframe_factory.html?a(b)"));
183
184 NavigateToURL(shell(), ab_url);
185
186 EXPECT_EQ(
187 " Site A ------------ proxies for B\n"
188 " +--Site B ------- proxies for A\n"
189 "Where A = http://a.com/\n"
190 " B = default subframe process",
191 DepictFrameTree(root()));
192
193 Shell* popup =
194 OpenPopup(root()->child_at(0), "/cross_site_iframe_factory.html?b(a)");
195 FrameTreeNode* popup_root =
196 static_cast<WebContentsImpl*>(popup->web_contents())
197 ->GetFrameTree()
198 ->root();
199
200 // This popup's main frame must stay in the default subframe siteinstance,
201 // since its opener (the b.com subframe) may synchronously script it. Note
202 // that the popup's subframe is same-site with window.top.opener.top, the
203 // a.com main frame of the tab. But --top-document-isolation does not
204 // currently place the popup subframe in the a.com process in this case.
205 EXPECT_EQ(
206 " Site B\n"
207 " +--Site B\n"
208 "Where B = default subframe process",
209 DepictFrameTree(popup_root));
210
211 GURL ba_url(embedded_test_server()->GetURL(
212 "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
213 NavigateToURL(shell(), ba_url);
214
215 // This navigation destroys the popup's opener, so we allow the main frame to
216 // commit in a top level process for b.com, in spite of the b.com popup in the
217 // default subframe process.
218 EXPECT_EQ(
219 " Site C ------------ proxies for B\n"
220 " |--Site B ------- proxies for C\n"
221 " +--Site B ------- proxies for C\n"
222 "Where B = default subframe process\n"
223 " C = http://b.com/",
224 DepictFrameTree(root()));
225 EXPECT_EQ(
226 " Site B\n"
227 " +--Site B\n"
228 "Where B = default subframe process",
229 DepictFrameTree(popup_root));
230
231 // Navigate the popup to a new site.
232 GURL c_url(embedded_test_server()->GetURL(
233 "c.com", "/cross_site_iframe_factory.html?c(c, c, c, c)"));
234 NavigateToURL(popup, c_url);
235 EXPECT_EQ(
236 " Site D ------------ proxies for B\n"
237 " |--Site D ------- proxies for B\n"
238 " |--Site D ------- proxies for B\n"
239 " |--Site D ------- proxies for B\n"
240 " +--Site D ------- proxies for B\n"
241 "Where B = default subframe process\n"
242 " D = http://c.com/",
243 DepictFrameTree(popup_root));
244 NavigateToURL(shell(), c_url);
245 EXPECT_EQ(
246 " Site D\n"
247 " |--Site D\n"
248 " |--Site D\n"
249 " |--Site D\n"
250 " +--Site D\n"
251 "Where D = http://c.com/",
252 DepictFrameTree(popup_root));
253 EXPECT_EQ(
254 " Site D\n"
255 " |--Site D\n"
256 " |--Site D\n"
257 " |--Site D\n"
258 " +--Site D\n"
259 "Where D = http://c.com/",
260 DepictFrameTree(root()));
261 }
262
263 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest,
264 NavigateToSubframeSiteWithPopup2) {
265 // A(B, C) -> C(A, B), but while a separate C(A) popup exists.
266 //
267 // This test is constructed so that c.com is the second site to commit in the
268 // default subframe SiteInstance, so the default subframe SiteInstance does
269 // not have a "c.com" as the value of GetSiteURL().
270 GURL abb_url(embedded_test_server()->GetURL(
271 "a.com", "/cross_site_iframe_factory.html?a(b, b)"));
272
273 NavigateToURL(shell(), abb_url);
274
275 EXPECT_EQ(
276 " Site A ------------ proxies for B\n"
277 " |--Site B ------- proxies for A\n"
278 " +--Site B ------- proxies for A\n"
279 "Where A = http://a.com/\n"
280 " B = default subframe process",
281 DepictFrameTree(root()));
282
283 // A(B, B) -> A(B, C)
284 GURL c_url(embedded_test_server()->GetURL(
285 "c.com", "/cross_site_iframe_factory.html?c"));
286 NavigateFrameToURL(root()->child_at(1), c_url);
287
288 EXPECT_EQ(
289 " Site A ------------ proxies for B\n"
290 " |--Site B ------- proxies for A\n"
291 " +--Site B ------- proxies for A\n"
292 "Where A = http://a.com/\n"
293 " B = default subframe process",
294 DepictFrameTree(root()));
295
296 // This test exercises what happens when the SiteURL of the default subframe
297 // siteinstance doesn't match the subframe site.
298 EXPECT_NE("c.com", root()
299 ->child_at(1)
300 ->current_frame_host()
301 ->GetSiteInstance()
302 ->GetSiteURL()
303 .host());
304
305 // Subframe C creates C(A) popup.
306 Shell* popup =
307 OpenPopup(root()->child_at(1), "/cross_site_iframe_factory.html?c(a)");
308
309 FrameTreeNode* popup_root =
310 static_cast<WebContentsImpl*>(popup->web_contents())
311 ->GetFrameTree()
312 ->root();
313
314 // The popup must stay with its opener, in the default subframe process.
315 EXPECT_EQ(
316 " Site B\n"
317 " +--Site B\n"
318 "Where B = default subframe process",
319 DepictFrameTree(popup_root));
320
321 GURL cab_url(embedded_test_server()->GetURL(
322 "c.com", "/cross_site_iframe_factory.html?c(a, b)"));
323 NavigateToURL(shell(), cab_url);
324
325 // This c.com navigation currently breaks out of the default subframe process,
326 // even though that process houses a c.com pop-up.
327 EXPECT_EQ(
328 " Site C ------------ proxies for B\n"
329 " |--Site B ------- proxies for C\n"
330 " +--Site B ------- proxies for C\n"
331 "Where B = default subframe process\n"
332 " C = http://c.com/",
333 DepictFrameTree(root()));
334
335 // c.com popup should remain where it was, in the subframe process.
336 EXPECT_EQ(
337 " Site B\n"
338 " +--Site B\n"
339 "Where B = default subframe process",
340 DepictFrameTree(popup_root));
341 EXPECT_EQ(nullptr, popup_root->opener());
342
343 // If we navigate the popup to a new site, it ought to transfer processes.
344 GURL d_url(embedded_test_server()->GetURL(
345 "d.com", "/cross_site_iframe_factory.html?d"));
346 NavigateToURL(popup, d_url);
347 EXPECT_EQ(
348 " Site D ------------ proxies for B\n"
349 "Where B = default subframe process\n"
350 " D = http://d.com/",
351 DepictFrameTree(popup_root));
352 NavigateToURL(shell(), d_url);
353 EXPECT_EQ(
354 " Site D\n"
355 "Where D = http://d.com/",
356 DepictFrameTree(popup_root));
357 EXPECT_EQ(
358 " Site D\n"
359 "Where D = http://d.com/",
360 DepictFrameTree(root()));
361 }
362
363 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, FramesForSitesInHistory) {
364 // First, do a series of navigations.
365 GURL a_url = embedded_test_server()->GetURL(
366 "a.com", "/cross_site_iframe_factory.html?a");
367 GURL b_url = embedded_test_server()->GetURL(
368 "b.com", "/cross_site_iframe_factory.html?b");
369 GURL c_url = embedded_test_server()->GetURL(
370 "c.com", "/cross_site_iframe_factory.html?c");
371 // Browser-initiated navigation to a.com.
Charlie Reis 2016/03/29 17:17:13 nit: Blank line before.
ncarter (slow) 2016/03/29 23:30:57 Done.
372 NavigateToURL(shell(), a_url);
373 EXPECT_EQ(
374 " Site A\n"
375 "Where A = http://a.com/",
376 DepictFrameTree(root()));
377
378 // Browser-initiated navigation to b.com.
379 NavigateToURL(shell(), b_url);
380 EXPECT_EQ(
381 " Site B\n"
382 "Where B = http://b.com/",
383 DepictFrameTree(root()));
384
385 // Renderer-initiated navigation back to a.com. This shouldn't swap processes.
386 RendererInitiatedNavigateToURL(root(), a_url);
387 EXPECT_EQ(
388 " Site B\n"
389 "Where B = http://b.com/",
390 DepictFrameTree(root()));
391
392 // Browser-initiated navigation to c.com.
393 NavigateToURL(shell(), c_url);
394 EXPECT_EQ(
395 " Site C\n"
396 "Where C = http://c.com/",
397 DepictFrameTree(root()));
398
399 // Now, navigate to a fourth site with iframes to the sites in the history.
400 NavigateToURL(shell(),
401 embedded_test_server()->GetURL(
402 "d.com", "/cross_site_iframe_factory.html?d(a,b,c)"));
403
404 EXPECT_EQ(
405 " Site D ------------ proxies for E\n"
406 " |--Site E ------- proxies for D\n"
407 " |--Site E ------- proxies for D\n"
408 " +--Site E ------- proxies for D\n"
409 "Where D = http://d.com/\n"
410 " E = default subframe process",
411 DepictFrameTree(root()));
412
413 // Now try going back.
414 GoBack();
415 EXPECT_EQ(
416 " Site C\n"
417 "Where C = http://c.com/",
418 DepictFrameTree(root()));
419 GoBack();
420 EXPECT_EQ(
421 " Site B\n"
422 "Where B = http://b.com/",
423 DepictFrameTree(root()));
424 GoBack();
425 EXPECT_EQ(
426 " Site B\n"
427 "Where B = http://b.com/",
428 DepictFrameTree(root()));
429 GoBack();
430 EXPECT_EQ(
431 " Site A\n"
432 "Where A = http://a.com/",
433 DepictFrameTree(root()));
434 }
435
436 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, CrossSiteAtLevelTwo) {
437 GURL main_url(embedded_test_server()->GetURL(
438 "a.com", "/cross_site_iframe_factory.html?a(a(b, a))"));
439
440 NavigateToURL(shell(), main_url);
441
442 EXPECT_EQ(
443 " Site A ------------ proxies for B\n"
444 " +--Site A ------- proxies for B\n"
445 " |--Site B -- proxies for A\n"
446 " +--Site A -- proxies for B\n"
447 "Where A = http://a.com/\n"
448 " B = default subframe process",
449 DepictFrameTree(root()));
450
451 GURL c_url(embedded_test_server()->GetURL(
452 "c.com", "/cross_site_iframe_factory.html?c"));
453 NavigateFrameToURL(root()->child_at(0)->child_at(1), c_url);
454
455 // This navigation should complete in the default subframe siteinstance.
456 EXPECT_EQ(
457 " Site A ------------ proxies for B\n"
458 " +--Site A ------- proxies for B\n"
459 " |--Site B -- proxies for A\n"
460 " +--Site B -- proxies for A\n"
461 "Where A = http://a.com/\n"
462 " B = default subframe process",
463 DepictFrameTree(root()));
464 }
465
466 IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, PopupAndRedirection) {
467 GURL main_url(embedded_test_server()->GetURL(
468 "page.com", "/cross_site_iframe_factory.html?page(adnetwork)"));
469
470 // User opens page on page.com which contains a subframe from adnetwork.com.
471 NavigateToURL(shell(), main_url);
472
473 EXPECT_EQ(
474 " Site A ------------ proxies for B\n"
475 " +--Site B ------- proxies for A\n"
476 "Where A = http://page.com/\n"
477 " B = default subframe process",
478 DepictFrameTree(root()));
479
480 GURL ad_url(embedded_test_server()->GetURL(
481 "ad.com", "/cross_site_iframe_factory.html?ad"));
482
483 // adnetwork.com retrieves an ad from advertiser (ad.com) and redirects the
484 // subframe to ad.com.
485 RendererInitiatedNavigateToURL(root()->child_at(0), ad_url);
486
487 // The subframe still uses the default subframe SiteInstance after navigation.
488 EXPECT_EQ(
489 " Site A ------------ proxies for B\n"
490 " +--Site B ------- proxies for A\n"
491 "Where A = http://page.com/\n"
492 " B = default subframe process",
493 DepictFrameTree(root()));
494
495 // User clicks the ad in the subframe, which opens a popup on the ad
496 // network's domain.
497 GURL popup_url(embedded_test_server()->GetURL(
498 "adnetwork.com", "/cross_site_iframe_factory.html?adnetwork"));
499 Shell* popup = OpenPopup(root()->child_at(0), popup_url.spec());
500
501 FrameTreeNode* popup_root =
502 static_cast<WebContentsImpl*>(popup->web_contents())
503 ->GetFrameTree()
504 ->root();
505
506 // It's ok for the popup to break out of the subframe process because it's
507 // currently cross-site from its opener frame.
508 EXPECT_EQ(
509 " Site C ------------ proxies for B\n"
510 "Where B = default subframe process\n"
511 " C = http://adnetwork.com/",
512 DepictFrameTree(popup_root));
513
514 EXPECT_EQ(
515 " Site A ------------ proxies for B C\n"
516 " +--Site B ------- proxies for A C\n"
517 "Where A = http://page.com/\n"
518 " B = default subframe process\n"
519 " C = http://adnetwork.com/",
520 DepictFrameTree(root()));
521
522 // The popup redirects itself to the advertiser's website (ad.com).
523 RendererInitiatedNavigateToURL(popup_root, ad_url);
524
525 // This must join its same-site opener, in the default subframe SiteInstance.
526 EXPECT_EQ(
527 " Site A ------------ proxies for B C\n"
528 " +--Site B ------- proxies for A C\n"
529 "Where A = http://page.com/\n"
530 " B = default subframe process\n"
531 " C = http://adnetwork.com/",
532 DepictFrameTree(root()));
533 EXPECT_EQ(
534 " Site C ------------ proxies for B\n"
535 "Where B = default subframe process\n"
536 " C = http://adnetwork.com/",
537 DepictFrameTree(popup_root));
538 }
539
540 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698