[M85 Dev][EFL] Fix errors to generate ninja files
[platform/framework/web/chromium-efl.git] / chrome / browser / chrome_navigation_browsertest.cc
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 "base/command_line.h"
6 #include "base/feature_list.h"
7 #include "base/run_loop.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/test/metrics/histogram_tester.h"
10 #include "base/test/scoped_feature_list.h"
11 #include "base/test/test_timeouts.h"
12 #include "build/build_config.h"
13 #include "chrome/app/chrome_command_ids.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/extensions/chrome_test_extension_loader.h"
16 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
17 #include "chrome/browser/tab_contents/navigation_metrics_recorder.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_commands.h"
20 #include "chrome/browser/ui/browser_window.h"
21 #include "chrome/browser/ui/location_bar/location_bar.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/browser/ui/toolbar/back_forward_menu_model.h"
24 #include "chrome/common/chrome_features.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/common/url_constants.h"
28 #include "chrome/test/base/in_process_browser_test.h"
29 #include "chrome/test/base/ui_test_utils.h"
30 #include "components/network_session_configurator/common/network_switches.h"
31 #include "components/omnibox/browser/omnibox_view.h"
32 #include "components/prefs/pref_service.h"
33 #include "components/site_isolation/features.h"
34 #include "components/site_isolation/pref_names.h"
35 #include "components/ukm/test_ukm_recorder.h"
36 #include "components/url_formatter/url_formatter.h"
37 #include "components/variations/active_field_trials.h"
38 #include "components/variations/hashing.h"
39 #include "content/public/browser/context_menu_params.h"
40 #include "content/public/browser/download_manager_delegate.h"
41 #include "content/public/browser/navigation_entry.h"
42 #include "content/public/browser/navigation_handle.h"
43 #include "content/public/browser/notification_service.h"
44 #include "content/public/browser/reload_type.h"
45 #include "content/public/browser/render_frame_host.h"
46 #include "content/public/browser/render_process_host.h"
47 #include "content/public/browser/render_widget_host_view.h"
48 #include "content/public/browser/site_isolation_policy.h"
49 #include "content/public/browser/storage_partition.h"
50 #include "content/public/browser/web_contents_observer.h"
51 #include "content/public/common/content_features.h"
52 #include "content/public/common/content_switches.h"
53 #include "content/public/common/url_constants.h"
54 #include "content/public/test/browser_test.h"
55 #include "content/public/test/browser_test_utils.h"
56 #include "content/public/test/download_test_observer.h"
57 #include "content/public/test/navigation_handle_observer.h"
58 #include "content/public/test/test_navigation_observer.h"
59 #include "content/public/test/url_loader_interceptor.h"
60 #include "extensions/test/extension_test_message_listener.h"
61 #include "extensions/test/test_extension_dir.h"
62 #include "google_apis/gaia/gaia_switches.h"
63 #include "net/dns/mock_host_resolver.h"
64 #include "services/metrics/public/cpp/ukm_builders.h"
65 #include "services/network/public/cpp/features.h"
66 #include "testing/gmock/include/gmock/gmock.h"
67 #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h"
68
69 using ::testing::IsEmpty;
70 using ::testing::UnorderedElementsAre;
71
72 class ChromeNavigationBrowserTest : public InProcessBrowserTest {
73  public:
74   ChromeNavigationBrowserTest() {
75     scoped_feature_list_.InitAndEnableFeature(ukm::kUkmFeature);
76   }
77   ~ChromeNavigationBrowserTest() override {}
78
79   void SetUpCommandLine(base::CommandLine* command_line) override {
80     // Backgrounded renderer processes run at a lower priority, causing the
81     // tests to take more time to complete. Disable backgrounding so that the
82     // tests don't time out.
83     command_line->AppendSwitch(switches::kDisableRendererBackgrounding);
84
85     embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
86     ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
87   }
88
89   void SetUpOnMainThread() override {
90     host_resolver()->AddRule("*", "127.0.0.1");
91     embedded_test_server()->StartAcceptingConnections();
92   }
93
94   void PreRunTestOnMainThread() override {
95     InProcessBrowserTest::PreRunTestOnMainThread();
96     test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
97   }
98
99   ukm::TestAutoSetUkmRecorder* test_ukm_recorder() {
100     return test_ukm_recorder_.get();
101   }
102
103  private:
104   std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;
105   base::test::ScopedFeatureList scoped_feature_list_;
106
107   DISALLOW_COPY_AND_ASSIGN(ChromeNavigationBrowserTest);
108 };
109
110 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
111 // Fails on chromium.memory/Linux Chromium OS ASan LSan:
112 // https://crbug.com/897879
113 #define MAYBE_TransientEntryPreservedOnMultipleNavigationsDuringInterstitial \
114   DISABLED_TransientEntryPreservedOnMultipleNavigationsDuringInterstitial
115 #else
116 #define MAYBE_TransientEntryPreservedOnMultipleNavigationsDuringInterstitial \
117   TransientEntryPreservedOnMultipleNavigationsDuringInterstitial
118 #endif
119
120 // Tests that viewing frame source on a local file:// page with an iframe
121 // with a remote URL shows the correct tab title.
122 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, TestViewFrameSource) {
123   // The local page file:// URL.
124   GURL local_page_with_iframe_url = ui_test_utils::GetTestUrl(
125       base::FilePath(base::FilePath::kCurrentDirectory),
126       base::FilePath(FILE_PATH_LITERAL("iframe.html")));
127
128   // The non-file:// URL of the page to load in the iframe.
129   GURL iframe_target_url = embedded_test_server()->GetURL("/title1.html");
130   ui_test_utils::NavigateToURL(browser(), local_page_with_iframe_url);
131   content::WebContents* web_contents =
132       browser()->tab_strip_model()->GetActiveWebContents();
133
134   content::TestNavigationObserver observer(web_contents);
135   ASSERT_TRUE(content::ExecuteScript(
136       web_contents->GetMainFrame(),
137       base::StringPrintf("var iframe = document.getElementById('test');\n"
138                          "iframe.setAttribute('src', '%s');\n",
139                          iframe_target_url.spec().c_str())));
140   observer.Wait();
141
142   content::RenderFrameHost* frame =
143       content::ChildFrameAt(web_contents->GetMainFrame(), 0);
144   ASSERT_TRUE(frame);
145   ASSERT_NE(frame, web_contents->GetMainFrame());
146
147   content::ContextMenuParams params;
148   params.page_url = local_page_with_iframe_url;
149   params.frame_url = frame->GetLastCommittedURL();
150   TestRenderViewContextMenu menu(frame, params);
151   menu.Init();
152   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_VIEWFRAMESOURCE, 0);
153   ASSERT_EQ(browser()->tab_strip_model()->count(), 2);
154   content::WebContents* new_web_contents =
155       browser()->tab_strip_model()->GetWebContentsAt(1);
156   ASSERT_NE(new_web_contents, web_contents);
157   EXPECT_TRUE(WaitForLoadStop(new_web_contents));
158
159   GURL view_frame_source_url(content::kViewSourceScheme + std::string(":") +
160                              iframe_target_url.spec());
161   EXPECT_EQ(url_formatter::FormatUrl(view_frame_source_url),
162             new_web_contents->GetTitle());
163 }
164
165 // Base class for ctrl+click tests, which contains all the common functionality
166 // independent from which process the navigation happens in. Each subclass
167 // defines its own expectations depending on the conditions of the test.
168 class CtrlClickProcessTest : public ChromeNavigationBrowserTest {
169  protected:
170   virtual void VerifyProcessExpectations(
171       content::WebContents* main_contents,
172       content::WebContents* new_contents) = 0;
173
174   // Simulates ctrl-clicking an anchor with the given id in |main_contents|.
175   // Verifies that the new contents are in the correct process and separate
176   // BrowsingInstance from |main_contents|.  Returns contents of the newly
177   // opened tab.
178   content::WebContents* SimulateCtrlClick(content::WebContents* main_contents,
179                                           const char* id_of_anchor_to_click) {
180     // Ctrl-click the anchor/link in the page.
181     content::WebContents* new_contents = nullptr;
182     {
183       content::WebContentsAddedObserver new_tab_observer;
184 #if defined(OS_MACOSX)
185       const char* new_tab_click_script_template =
186           "simulateClick(\"%s\", { metaKey: true });";
187 #else
188       const char* new_tab_click_script_template =
189           "simulateClick(\"%s\", { ctrlKey: true });";
190 #endif
191       std::string new_tab_click_script = base::StringPrintf(
192           new_tab_click_script_template, id_of_anchor_to_click);
193       EXPECT_TRUE(ExecuteScript(main_contents, new_tab_click_script));
194
195       // Wait for a new tab to appear (the whole point of this test).
196       new_contents = new_tab_observer.GetWebContents();
197     }
198
199     // Verify that the new tab has the right contents and is in the tab strip.
200     EXPECT_TRUE(WaitForLoadStop(new_contents));
201     EXPECT_LT(1, browser()->tab_strip_model()->count());  // More than 1 tab?
202     EXPECT_NE(
203         TabStripModel::kNoTab,
204         browser()->tab_strip_model()->GetIndexOfWebContents(new_contents));
205     GURL expected_url(embedded_test_server()->GetURL("/title1.html"));
206     EXPECT_EQ(expected_url, new_contents->GetLastCommittedURL());
207
208     VerifyProcessExpectations(main_contents, new_contents);
209
210     {
211       // Double-check that main_contents has expected window.name set.
212       // This is a sanity check of test setup; this is not a product test.
213       std::string name_of_main_contents_window;
214       EXPECT_TRUE(ExecuteScriptAndExtractString(
215           main_contents, "window.domAutomationController.send(window.name)",
216           &name_of_main_contents_window));
217       EXPECT_EQ("main_contents", name_of_main_contents_window);
218
219       // Verify that the new contents doesn't have a window.opener set.
220       bool window_opener_cast_to_bool = true;
221       EXPECT_TRUE(ExecuteScriptAndExtractBool(
222           new_contents, "window.domAutomationController.send(!!window.opener)",
223           &window_opener_cast_to_bool));
224       EXPECT_FALSE(window_opener_cast_to_bool);
225
226       VerifyBrowsingInstanceExpectations(main_contents, new_contents);
227     }
228
229     return new_contents;
230   }
231
232   void TestCtrlClick(const char* id_of_anchor_to_click) {
233     // Navigate to the test page.
234     GURL main_url(embedded_test_server()->GetURL(
235         "/frame_tree/anchor_to_same_site_location.html"));
236     ui_test_utils::NavigateToURL(browser(), main_url);
237
238     // Verify that there is only 1 active tab (with the right contents
239     // committed).
240     EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
241     content::WebContents* main_contents =
242         browser()->tab_strip_model()->GetWebContentsAt(0);
243     EXPECT_EQ(main_url, main_contents->GetLastCommittedURL());
244
245     // Test what happens after ctrl-click.  SimulateCtrlClick will verify
246     // that |new_contents1| is in the correct process and separate
247     // BrowsingInstance from |main_contents|.
248     content::WebContents* new_contents1 =
249         SimulateCtrlClick(main_contents, id_of_anchor_to_click);
250
251     // Test that each subsequent ctrl-click also gets the correct process.
252     content::WebContents* new_contents2 =
253         SimulateCtrlClick(main_contents, id_of_anchor_to_click);
254     EXPECT_FALSE(new_contents1->GetSiteInstance()->IsRelatedSiteInstance(
255         new_contents2->GetSiteInstance()));
256     VerifyProcessExpectations(new_contents1, new_contents2);
257   }
258
259  private:
260   void VerifyBrowsingInstanceExpectations(content::WebContents* main_contents,
261                                           content::WebContents* new_contents) {
262     // Verify that the new contents cannot find the old contents via
263     // window.open. (i.e. window.open should open a new window, rather than
264     // returning a reference to main_contents / old window).
265     std::string location_of_opened_window;
266     EXPECT_TRUE(ExecuteScriptAndExtractString(
267         new_contents,
268         "w = window.open('', 'main_contents');"
269         "window.domAutomationController.send(w.location.href);",
270         &location_of_opened_window));
271     EXPECT_EQ(url::kAboutBlankURL, location_of_opened_window);
272   }
273 };
274
275 // Tests that verify that ctrl-click results 1) open up in a new renderer
276 // process (https://crbug.com/23815) and 2) are in a new BrowsingInstance (e.g.
277 // cannot find the opener's window by name - https://crbug.com/658386).
278 class CtrlClickShouldEndUpInNewProcessTest : public CtrlClickProcessTest {
279  protected:
280   void VerifyProcessExpectations(content::WebContents* main_contents,
281                                  content::WebContents* new_contents) override {
282     // Verify that the two WebContents are in a different process, SiteInstance
283     // and BrowsingInstance from the old contents.
284     EXPECT_NE(main_contents->GetMainFrame()->GetProcess(),
285               new_contents->GetMainFrame()->GetProcess());
286     EXPECT_NE(main_contents->GetMainFrame()->GetSiteInstance(),
287               new_contents->GetMainFrame()->GetSiteInstance());
288     EXPECT_FALSE(main_contents->GetSiteInstance()->IsRelatedSiteInstance(
289         new_contents->GetSiteInstance()));
290   }
291 };
292
293 IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInNewProcessTest, NoTarget) {
294   TestCtrlClick("test-anchor-no-target");
295 }
296
297 IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInNewProcessTest, BlankTarget) {
298   TestCtrlClick("test-anchor-with-blank-target");
299 }
300
301 IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInNewProcessTest, SubframeTarget) {
302   TestCtrlClick("test-anchor-with-subframe-target");
303 }
304
305 // Similar to the tests above, but verifies that the new WebContents ends up in
306 // the same process as the opener when it is exceeding the process limit.
307 // See https://crbug.com/774723.
308 class CtrlClickShouldEndUpInSameProcessTest : public CtrlClickProcessTest {
309  public:
310   void SetUpCommandLine(base::CommandLine* command_line) override {
311     CtrlClickProcessTest::SetUpCommandLine(command_line);
312     content::IsolateAllSitesForTesting(command_line);
313     content::RenderProcessHost::SetMaxRendererProcessCount(1);
314   }
315
316  protected:
317   void VerifyProcessExpectations(content::WebContents* contents1,
318                                  content::WebContents* contents2) override {
319     // Verify that the two WebContents are in the same process, though different
320     // SiteInstance and BrowsingInstance from the old contents.
321     EXPECT_EQ(contents1->GetMainFrame()->GetProcess(),
322               contents2->GetMainFrame()->GetProcess());
323     EXPECT_EQ(contents1->GetMainFrame()->GetSiteInstance()->GetSiteURL(),
324               contents2->GetMainFrame()->GetSiteInstance()->GetSiteURL());
325     EXPECT_FALSE(contents1->GetSiteInstance()->IsRelatedSiteInstance(
326         contents2->GetSiteInstance()));
327   }
328 };
329
330 IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInSameProcessTest, NoTarget) {
331   TestCtrlClick("test-anchor-no-target");
332 }
333
334 IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInSameProcessTest, BlankTarget) {
335   TestCtrlClick("test-anchor-with-blank-target");
336 }
337
338 IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInSameProcessTest, SubframeTarget) {
339   TestCtrlClick("test-anchor-with-subframe-target");
340 }
341
342 class ChromeNavigationPortMappedBrowserTest : public InProcessBrowserTest {
343  public:
344   ChromeNavigationPortMappedBrowserTest() {}
345   ~ChromeNavigationPortMappedBrowserTest() override {}
346
347   void SetUpCommandLine(base::CommandLine* command_line) override {
348     ASSERT_TRUE(embedded_test_server()->Start());
349
350     // Use the command line parameter for the host resolver, so URLs without
351     // explicit port numbers can be mapped under the hood to the port number
352     // the |embedded_test_server| uses. It is required to test with potentially
353     // malformed URLs.
354     std::string port =
355         base::NumberToString(embedded_test_server()->host_port_pair().port());
356     command_line->AppendSwitchASCII(
357         "host-resolver-rules",
358         "MAP * 127.0.0.1:" + port + ", EXCLUDE 127.0.0.1*");
359   }
360
361  private:
362   DISALLOW_COPY_AND_ASSIGN(ChromeNavigationPortMappedBrowserTest);
363 };
364
365 // Test to verify that spoofing a URL via a redirect from a slightly malformed
366 // URL doesn't work.  See also https://crbug.com/657720.
367 IN_PROC_BROWSER_TEST_F(ChromeNavigationPortMappedBrowserTest,
368                        ContextMenuNavigationToInvalidUrl) {
369   GURL initial_url = embedded_test_server()->GetURL("/title1.html");
370   GURL new_tab_url(
371       "www.foo.com::/server-redirect?http%3A%2F%2Fbar.com%2Ftitle2.html");
372
373   // Navigate to an initial page, to ensure we have a committed document
374   // from which to perform a context menu initiated navigation.
375   ui_test_utils::NavigateToURL(browser(), initial_url);
376   content::WebContents* web_contents =
377       browser()->tab_strip_model()->GetActiveWebContents();
378
379   // This corresponds to "Open link in new tab".
380   content::ContextMenuParams params;
381   params.is_editable = false;
382   params.media_type = blink::ContextMenuDataMediaType::kNone;
383   params.page_url = initial_url;
384   params.link_url = new_tab_url;
385
386   ui_test_utils::TabAddedWaiter tab_add(browser());
387
388   TestRenderViewContextMenu menu(web_contents->GetMainFrame(), params);
389   menu.Init();
390   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
391
392   // Wait for the new tab to be created and for loading to stop.
393   tab_add.Wait();
394   int index_of_new_tab = browser()->tab_strip_model()->count() - 1;
395   content::WebContents* new_web_contents =
396       browser()->tab_strip_model()->GetWebContentsAt(index_of_new_tab);
397   EXPECT_TRUE(WaitForLoadStop(new_web_contents));
398
399   // Verify that the final URL after the redirects gets committed.
400   EXPECT_EQ(GURL("http://bar.com/title2.html"),
401             new_web_contents->GetLastCommittedURL());
402 }
403
404 // Ensure that a failed navigation in a new tab will not leave an invalid
405 // visible URL, which may be formatted in an unsafe way in the omnibox.
406 // See https://crbug.com/850824.
407 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
408                        ClearInvalidPendingURLOnFail) {
409   GURL initial_url = embedded_test_server()->GetURL(
410       "/frame_tree/invalid_link_to_new_window.html");
411
412   // Navigate to a page with a link that opens an invalid URL in a new window.
413   ui_test_utils::NavigateToURL(browser(), initial_url);
414   content::WebContents* main_contents =
415       browser()->tab_strip_model()->GetActiveWebContents();
416
417   // Simulate a click on the link and wait for the new window.
418   content::WebContentsAddedObserver new_tab_observer;
419   EXPECT_TRUE(ExecuteScript(main_contents, "simulateClick()"));
420   content::WebContents* new_contents = new_tab_observer.GetWebContents();
421
422   // The load in the new window should fail.
423   EXPECT_FALSE(WaitForLoadStop(new_contents));
424
425   // Ensure that there is no pending entry or visible URL.
426   EXPECT_EQ(nullptr, new_contents->GetController().GetPendingEntry());
427   EXPECT_EQ(GURL(), new_contents->GetVisibleURL());
428 }
429
430 // A test performing two simultaneous navigations, to ensure code in chrome/,
431 // such as tab helpers, can handle those cases.
432 // This test starts a browser-initiated cross-process navigation, which is
433 // delayed. At the same time, the renderer does a synchronous navigation
434 // through pushState, which will create a separate navigation and associated
435 // NavigationHandle. Afterwards, the original cross-process navigation is
436 // resumed and confirmed to properly commit.
437 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
438                        SlowCrossProcessNavigationWithPushState) {
439   const GURL kURL1 = embedded_test_server()->GetURL("/title1.html");
440   const GURL kPushStateURL =
441       embedded_test_server()->GetURL("/title1.html#fragment");
442   const GURL kURL2 = embedded_test_server()->GetURL("/title2.html");
443
444   content::WebContents* web_contents =
445       browser()->tab_strip_model()->GetActiveWebContents();
446
447   // Navigate to the initial page.
448   ui_test_utils::NavigateToURL(browser(), kURL1);
449
450   // Start navigating to the second page.
451   content::TestNavigationManager manager(web_contents, kURL2);
452   content::NavigationHandleCommitObserver navigation_observer(web_contents,
453                                                               kURL2);
454   web_contents->GetController().LoadURL(
455       kURL2, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
456   EXPECT_TRUE(manager.WaitForRequestStart());
457
458   // The current page does a PushState.
459   content::NavigationHandleCommitObserver push_state_observer(web_contents,
460                                                               kPushStateURL);
461   std::string push_state =
462       "history.pushState({}, \"title 1\", \"" + kPushStateURL.spec() + "\");";
463   EXPECT_TRUE(ExecuteScript(web_contents, push_state));
464   content::NavigationEntry* last_committed =
465       web_contents->GetController().GetLastCommittedEntry();
466   EXPECT_TRUE(last_committed);
467   EXPECT_EQ(kPushStateURL, last_committed->GetURL());
468
469   EXPECT_TRUE(push_state_observer.has_committed());
470   EXPECT_TRUE(push_state_observer.was_same_document());
471   EXPECT_TRUE(push_state_observer.was_renderer_initiated());
472
473   // Let the navigation finish. It should commit successfully.
474   manager.WaitForNavigationFinished();
475   last_committed = web_contents->GetController().GetLastCommittedEntry();
476   EXPECT_TRUE(last_committed);
477   EXPECT_EQ(kURL2, last_committed->GetURL());
478
479   EXPECT_TRUE(navigation_observer.has_committed());
480   EXPECT_FALSE(navigation_observer.was_same_document());
481   EXPECT_FALSE(navigation_observer.was_renderer_initiated());
482 }
483
484 // Check that if a page has an iframe that loads an error page, that error page
485 // does not inherit the Content Security Policy from the parent frame.  See
486 // https://crbug.com/703801.  This test is in chrome/ because error page
487 // behavior is only fully defined in chrome/.
488 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
489                        ErrorPageDoesNotInheritCSP) {
490   GURL url(
491       embedded_test_server()->GetURL("/page_with_csp_and_error_iframe.html"));
492   content::WebContents* web_contents =
493       browser()->tab_strip_model()->GetActiveWebContents();
494
495   // Navigate to a page that disallows scripts via CSP and has an iframe that
496   // tries to load an invalid URL, which results in an error page.
497   GURL error_url("http://invalid.foo/");
498   content::NavigationHandleObserver observer(web_contents, error_url);
499   ui_test_utils::NavigateToURL(browser(), url);
500   EXPECT_TRUE(observer.has_committed());
501   EXPECT_TRUE(observer.is_error());
502
503   // The error page should not inherit the CSP directive that blocks all
504   // scripts from the parent frame, so this script should be allowed to
505   // execute.  Since ExecuteScript will execute the passed-in script regardless
506   // of CSP, use a javascript: URL which does go through the CSP checks.
507   content::RenderFrameHost* error_host =
508       ChildFrameAt(web_contents->GetMainFrame(), 0);
509   std::string location;
510   EXPECT_TRUE(ExecuteScriptAndExtractString(
511       error_host,
512       "location='javascript:domAutomationController.send(location.href)';",
513       &location));
514   EXPECT_EQ(location, content::kUnreachableWebDataURL);
515
516   // The error page should have a unique origin.
517   std::string origin;
518   EXPECT_TRUE(ExecuteScriptAndExtractString(
519       error_host, "domAutomationController.send(self.origin);", &origin));
520   EXPECT_EQ("null", origin);
521 }
522
523 // Test that web pages can't navigate to an error page URL, either directly or
524 // via a redirect, and that web pages can't embed error pages in iframes.
525 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
526                        NavigationToErrorURLIsDisallowed) {
527   content::WebContents* web_contents =
528       browser()->tab_strip_model()->GetActiveWebContents();
529   GURL url(embedded_test_server()->GetURL("/title1.html"));
530   ui_test_utils::NavigateToURL(browser(), url);
531   EXPECT_EQ(url, web_contents->GetLastCommittedURL());
532
533   // Try navigating to the error page URL and make sure it is canceled and the
534   // old URL remains the last committed one.
535   GURL error_url(content::kUnreachableWebDataURL);
536   EXPECT_TRUE(ExecuteScript(web_contents,
537                             "location.href = '" + error_url.spec() + "';"));
538   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
539   EXPECT_EQ(url, web_contents->GetLastCommittedURL());
540
541   // Also ensure that a page can't embed an iframe for an error page URL.
542   EXPECT_TRUE(ExecuteScript(web_contents,
543                             "var frame = document.createElement('iframe');\n"
544                             "frame.src = '" + error_url.spec() + "';\n"
545                             "document.body.appendChild(frame);"));
546   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
547   content::RenderFrameHost* subframe_host =
548       ChildFrameAt(web_contents->GetMainFrame(), 0);
549   // The new subframe should remain blank without a committed URL.
550   EXPECT_TRUE(subframe_host->GetLastCommittedURL().is_empty());
551
552   // Now try navigating to a URL that tries to redirect to the error page URL
553   // and make sure the navigation is ignored. Note that DidStopLoading will
554   // still fire, so TestNavigationObserver can be used to wait for it.
555   GURL redirect_to_error_url(
556       embedded_test_server()->GetURL("/server-redirect?" + error_url.spec()));
557   content::TestNavigationObserver observer(web_contents);
558   EXPECT_TRUE(ExecuteScript(
559       web_contents, "location.href = '" + redirect_to_error_url.spec() + "';"));
560   observer.Wait();
561   EXPECT_EQ(url, web_contents->GetLastCommittedURL());
562   EXPECT_EQ(
563       content::PAGE_TYPE_NORMAL,
564       web_contents->GetController().GetLastCommittedEntry()->GetPageType());
565   // Check the pending URL is not left in the address bar.
566   EXPECT_EQ(url, web_contents->GetVisibleURL());
567 }
568
569 // This test ensures that navigating to a page that returns an error code and
570 // an empty document still shows Chrome's helpful error page instead of the
571 // empty document.
572 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
573                        EmptyDocumentWithErrorCode) {
574   GURL url(embedded_test_server()->GetURL("/empty_with_404.html"));
575   content::WebContents* web_contents =
576       browser()->tab_strip_model()->GetActiveWebContents();
577
578   // Wait for the navigation to complete.  The empty document should trigger
579   // loading of the 404 error page, so check that the last committed entry was
580   // indeed for the error page.
581   content::TestNavigationObserver observer(web_contents);
582   EXPECT_TRUE(
583       ExecuteScript(web_contents, "location.href = '" + url.spec() + "';"));
584   observer.Wait();
585   EXPECT_FALSE(observer.last_navigation_succeeded());
586   EXPECT_EQ(url, web_contents->GetLastCommittedURL());
587   EXPECT_TRUE(
588       IsLastCommittedEntryOfPageType(web_contents, content::PAGE_TYPE_ERROR));
589
590   // Verify that the error page has correct content.  This needs to wait for
591   // the error page content to be populated asynchronously by scripts after
592   // DidFinishLoad.
593   while (true) {
594     std::string content;
595     EXPECT_TRUE(ExecuteScriptAndExtractString(
596         web_contents,
597         "domAutomationController.send("
598         "    document.body ? document.body.innerText : '');",
599         &content));
600     if (content.find("HTTP ERROR 404") != std::string::npos)
601       break;
602     base::RunLoop run_loop;
603     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
604         FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
605     run_loop.Run();
606   }
607 }
608
609 // Test for https://crbug.com/866549#c2. It verifies that about:blank does not
610 // commit in the error page process when it is redirected to.
611 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
612                        RedirectErrorPageReloadToAboutBlank) {
613   content::WebContents* web_contents =
614       browser()->tab_strip_model()->GetActiveWebContents();
615   GURL url(embedded_test_server()->GetURL("a.com", "/title1.html"));
616   std::unique_ptr<content::URLLoaderInterceptor> url_interceptor =
617       content::URLLoaderInterceptor::SetupRequestFailForURL(
618           url, net::ERR_DNS_TIMED_OUT);
619
620   // Start off with navigation to a.com, which results in an error page.
621   {
622     content::TestNavigationObserver observer(web_contents);
623     ui_test_utils::NavigateToURL(browser(), url);
624     EXPECT_FALSE(observer.last_navigation_succeeded());
625     EXPECT_EQ(url, observer.last_navigation_url());
626     EXPECT_EQ(GURL(content::kUnreachableWebDataURL),
627               web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL());
628   }
629
630   // Install an extension, which will redirect all navigations to a.com URLs to
631   // about:blank. In general, web servers cannot redirect to about:blank, but
632   // extensions with webRequest API permissions can.
633   extensions::TestExtensionDir test_extension_dir;
634   test_extension_dir.WriteManifest(
635       R"({
636            "name": "Redirect a.com to about:blank",
637            "manifest_version": 2,
638            "version": "0.1",
639            "permissions": ["webRequest", "webRequestBlocking", "*://a.com/*"],
640            "background": { "scripts": ["background.js"] }
641          })");
642   test_extension_dir.WriteFile(
643       FILE_PATH_LITERAL("background.js"),
644       R"(chrome.webRequest.onBeforeRequest.addListener(function(d) {
645           console.log("onBeforeRequest: ", d);
646           return {redirectUrl:"about:blank"};
647         }, {urls: ["*://a.com/*"]}, ["blocking"]);
648         chrome.test.sendMessage('ready');
649       )");
650
651   ExtensionTestMessageListener ready_listener("ready", false /* will_reply */);
652   extensions::ChromeTestExtensionLoader extension_loader(browser()->profile());
653   extension_loader.LoadExtension(test_extension_dir.UnpackedPath());
654
655   // Wait for the background page to load.
656   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
657
658   // Remove the interceptor to allow a reload to succeed, which the extension
659   // will intercept and redirect. The navigation should complete successfully
660   // and commit in a process that is different than the error page one.
661   url_interceptor.reset();
662   {
663     content::TestNavigationObserver observer(web_contents);
664     EXPECT_TRUE(ExecuteScript(web_contents, "location.reload();"));
665     observer.Wait();
666     EXPECT_TRUE(observer.last_navigation_succeeded());
667     EXPECT_EQ(GURL(url::kAboutBlankURL), observer.last_navigation_url());
668     EXPECT_NE(GURL(content::kUnreachableWebDataURL),
669               web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL());
670   }
671 }
672
673 // This test covers a navigation that:
674 // 1. is initiated by a cross-site initiator,
675 // 2. gets redirected via webRequest API to about:blank.
676 // This is a regression test for https://crbug.com/1026738.
677 IN_PROC_BROWSER_TEST_F(
678     ChromeNavigationBrowserTest,
679     NavigationInitiatedByCrossSiteSubframeRedirectedToAboutBlank) {
680   const GURL kOpenerUrl(
681       embedded_test_server()->GetURL("opener.com", "/title1.html"));
682   const GURL kInitialPopupUrl(embedded_test_server()->GetURL(
683       "initial-site.com",
684       "/frame_tree/page_with_two_frames_remote_and_local.html"));
685   const GURL kRedirectedUrl("https://redirected.com/no-such-path");
686
687   // 1. Install an extension, which will redirect all navigations to
688   //    redirected.com URLs to about:blank. In general, web servers cannot
689   //    redirect to about:blank, but extensions with declarativeWebRequest API
690   //    permissions can.
691   const char kManifest[] = R"(
692       {
693         "name": "Test for Bug1026738 - about:blank flavour",
694         "version": "0.1",
695         "manifest_version": 2,
696         "background": {
697           "scripts": ["background.js"]
698         },
699         "permissions": ["webRequest", "webRequestBlocking", "<all_urls>"]
700       }
701   )";
702   const char kRulesScript[] = R"(
703       chrome.webRequest.onBeforeRequest.addListener(function(d) {
704           console.log("onBeforeRequest: ", d);
705           return {redirectUrl: "about:blank"};
706         }, {urls: ["*://redirected.com/*"]}, ["blocking"]);
707       chrome.test.sendMessage('ready');
708   )";
709   extensions::TestExtensionDir ext_dir;
710   ext_dir.WriteManifest(kManifest);
711   ext_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kRulesScript);
712   ExtensionTestMessageListener ready_listener("ready", false /* will_reply */);
713   extensions::ChromeTestExtensionLoader extension_loader(browser()->profile());
714   scoped_refptr<const extensions::Extension> extension =
715       extension_loader.LoadExtension(ext_dir.UnpackedPath());
716   ASSERT_TRUE(extension);
717   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
718   content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
719       ->FlushNetworkInterfaceForTesting();
720
721   // 2. Open a popup containing a cross-site subframe.
722   ui_test_utils::NavigateToURL(browser(), kOpenerUrl);
723   content::RenderFrameHost* opener =
724       browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
725   EXPECT_EQ(kOpenerUrl, opener->GetLastCommittedURL());
726   EXPECT_EQ(url::Origin::Create(kOpenerUrl), opener->GetLastCommittedOrigin());
727   content::WebContents* popup = nullptr;
728   {
729     content::WebContentsAddedObserver popup_observer;
730     ASSERT_TRUE(content::ExecJs(
731         opener,
732         content::JsReplace("window.open($1, 'my-popup')", kInitialPopupUrl)));
733     popup = popup_observer.GetWebContents();
734     EXPECT_TRUE(WaitForLoadStop(popup));
735   }
736
737   // 3. Find the cross-site subframes in the popup.
738   content::RenderFrameHost* popup_root = popup->GetMainFrame();
739   content::RenderFrameHost* cross_site_subframe =
740       content::ChildFrameAt(popup_root, 0);
741   ASSERT_TRUE(cross_site_subframe);
742   EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(),
743             popup_root->GetLastCommittedOrigin());
744   EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(),
745             opener->GetLastCommittedOrigin());
746   if (content::AreAllSitesIsolatedForTesting()) {
747     EXPECT_NE(cross_site_subframe->GetSiteInstance(),
748               popup_root->GetSiteInstance());
749     EXPECT_NE(cross_site_subframe->GetSiteInstance(),
750               opener->GetSiteInstance());
751   }
752   scoped_refptr<content::SiteInstance> old_popup_site_instance =
753       popup_root->GetSiteInstance();
754   scoped_refptr<content::SiteInstance> old_subframe_site_instance =
755       cross_site_subframe->GetSiteInstance();
756
757   // 4. Initiate popup navigation from the cross-site subframe.
758   //    Note that the extension from step 1 above will redirect
759   //    this navigation to an about:blank URL.
760   //
761   // This step would have hit the CHECK from https://crbug.com/1026738.
762   content::TestNavigationObserver nav_observer(popup, 1);
763   ASSERT_TRUE(ExecJs(cross_site_subframe,
764                      content::JsReplace("top.location = $1", kRedirectedUrl)));
765   nav_observer.Wait();
766   EXPECT_EQ(url::kAboutBlankURL, popup->GetLastCommittedURL());
767
768   // 5. Verify that the about:blank URL is hosted in the same process
769   //    as the navigation initiator (and separate from the opener and the old
770   //    popup process).
771   if (content::AreAllSitesIsolatedForTesting()) {
772     EXPECT_NE(opener->GetSiteInstance(), popup->GetSiteInstance());
773     EXPECT_NE(old_popup_site_instance.get(), popup->GetSiteInstance());
774     EXPECT_EQ(old_subframe_site_instance.get(), popup->GetSiteInstance());
775     EXPECT_NE(url::kAboutBlankURL,
776               popup->GetSiteInstance()->GetSiteURL().scheme());
777     EXPECT_NE(url::kDataScheme,
778               popup->GetSiteInstance()->GetSiteURL().scheme());
779   } else {
780     EXPECT_EQ(opener->GetSiteInstance(), popup->GetSiteInstance());
781     EXPECT_EQ(old_popup_site_instance.get(), popup->GetSiteInstance());
782     EXPECT_EQ(old_subframe_site_instance.get(), popup->GetSiteInstance());
783     EXPECT_NE(url::kAboutBlankURL,
784               popup->GetSiteInstance()->GetSiteURL().scheme());
785     EXPECT_NE(url::kDataScheme,
786               popup->GetSiteInstance()->GetSiteURL().scheme());
787   }
788
789   // 6. Verify the origin of the about:blank URL in the popup.
790   //
791   // Blink calculates the origin of an about:blank frame based on the
792   // opener-or-parent (rather than based on the navigation initiator's origin
793   // as required by the spec).
794   // TODO(lukasza): https://crbug.com/585649: Once Blink is fixed, adjust test
795   // expectations below to make sure the initiator's origin has been committed.
796   // Consider also adding verification that the about:blank page can be scripted
797   // by other frames with the initiator's origin.
798   if (content::AreAllSitesIsolatedForTesting()) {
799     // If the opener is a blink::RemoteFrame, then Blink uses an opaque origin.
800     EXPECT_TRUE(popup->GetMainFrame()->GetLastCommittedOrigin().opaque());
801   } else {
802     EXPECT_EQ(url::Origin::Create(kOpenerUrl),
803               popup->GetMainFrame()->GetLastCommittedOrigin());
804   }
805 }
806
807 // This test covers a navigation that:
808 // 1. is initiated by a cross-site initiator,
809 // 2. gets redirected via webRequest API to a data: URL
810 // This covers a scenario similar to the one that led to crashes in
811 // https://crbug.com/1026738.
812 IN_PROC_BROWSER_TEST_F(
813     ChromeNavigationBrowserTest,
814     NavigationInitiatedByCrossSiteSubframeRedirectedToDataUrl) {
815   const GURL kOpenerUrl(
816       embedded_test_server()->GetURL("opener.com", "/title1.html"));
817   const GURL kInitialPopupUrl(embedded_test_server()->GetURL(
818       "initial-site.com",
819       "/frame_tree/page_with_two_frames_remote_and_local.html"));
820   const GURL kRedirectedUrl("https://redirected.com/no-such-path");
821   const GURL kRedirectTargetUrl(
822       "data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E");
823
824   // 1. Install an extension, which will redirect all navigations to
825   //    redirected.com URLs to a data: URL. In general, web servers cannot
826   //    redirect to data: URLs, but extensions with declarativeWebRequest API
827   //    permissions can.
828   const char kManifest[] = R"(
829       {
830         "name": "Test for Bug1026738 - data: URL flavour",
831         "version": "0.1",
832         "manifest_version": 2,
833         "background": {
834           "scripts": ["background.js"]
835         },
836         "permissions": ["webRequest", "webRequestBlocking", "<all_urls>"]
837       }
838   )";
839   const char kRulesScriptTemplate[] = R"(
840       chrome.webRequest.onBeforeRequest.addListener(function(d) {
841           console.log("onBeforeRequest: ", d);
842           return {redirectUrl: $1};
843         }, {urls: ["*://redirected.com/*"]}, ["blocking"]);
844       chrome.test.sendMessage('ready');
845   )";
846   extensions::TestExtensionDir ext_dir;
847   ext_dir.WriteManifest(kManifest);
848   ext_dir.WriteFile(
849       FILE_PATH_LITERAL("background.js"),
850       content::JsReplace(kRulesScriptTemplate, kRedirectTargetUrl));
851   ExtensionTestMessageListener ready_listener("ready", false /* will_reply */);
852   extensions::ChromeTestExtensionLoader extension_loader(browser()->profile());
853   scoped_refptr<const extensions::Extension> extension =
854       extension_loader.LoadExtension(ext_dir.UnpackedPath());
855   ASSERT_TRUE(extension);
856   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
857   content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
858       ->FlushNetworkInterfaceForTesting();
859
860   // 2. Open a popup containing a cross-site subframe.
861   ui_test_utils::NavigateToURL(browser(), kOpenerUrl);
862   content::RenderFrameHost* opener =
863       browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
864   EXPECT_EQ(kOpenerUrl, opener->GetLastCommittedURL());
865   EXPECT_EQ(url::Origin::Create(kOpenerUrl), opener->GetLastCommittedOrigin());
866   content::WebContents* popup = nullptr;
867   {
868     content::WebContentsAddedObserver popup_observer;
869     ASSERT_TRUE(content::ExecJs(
870         opener,
871         content::JsReplace("window.open($1, 'my-popup')", kInitialPopupUrl)));
872     popup = popup_observer.GetWebContents();
873     EXPECT_TRUE(WaitForLoadStop(popup));
874   }
875
876   // 3. Find the cross-site subframes in the popup.
877   EXPECT_EQ(3u, popup->GetAllFrames().size());
878   content::RenderFrameHost* popup_root = popup->GetMainFrame();
879   content::RenderFrameHost* cross_site_subframe = popup->GetAllFrames()[1];
880   EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(),
881             popup_root->GetLastCommittedOrigin());
882   EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(),
883             opener->GetLastCommittedOrigin());
884   if (content::AreAllSitesIsolatedForTesting()) {
885     EXPECT_NE(cross_site_subframe->GetSiteInstance(),
886               popup_root->GetSiteInstance());
887     EXPECT_NE(cross_site_subframe->GetSiteInstance(),
888               opener->GetSiteInstance());
889   }
890   scoped_refptr<content::SiteInstance> old_popup_site_instance =
891       popup_root->GetSiteInstance();
892
893   // 4. Initiate popup navigation from the cross-site subframe.
894   //    Note that the extension from step 1 above will redirect
895   //    this navigation to a data: URL.
896   //
897   // This step might hit the CHECK in GetOriginForURLLoaderFactory once we start
898   // enforcing opaque origins with no precursor in CanAccessDataForOrigin.
899   content::TestNavigationObserver nav_observer(popup, 1);
900   ASSERT_TRUE(ExecJs(cross_site_subframe,
901                      content::JsReplace("top.location = $1", kRedirectedUrl)));
902   nav_observer.Wait();
903   EXPECT_EQ(kRedirectTargetUrl, popup->GetLastCommittedURL());
904   EXPECT_TRUE(popup->GetMainFrame()->GetLastCommittedOrigin().opaque());
905
906   // 5. Verify that with site-per-process the data: URL is hosted in a brand
907   //    new, separate process (separate from the opener and the previous popup
908   //    process).
909   if (content::AreAllSitesIsolatedForTesting()) {
910     EXPECT_NE(opener->GetSiteInstance(), popup->GetSiteInstance());
911     EXPECT_NE(old_popup_site_instance.get(), popup->GetSiteInstance());
912     EXPECT_EQ(url::kDataScheme,
913               popup->GetSiteInstance()->GetSiteURL().scheme());
914   } else {
915     EXPECT_EQ(opener->GetSiteInstance(), popup->GetSiteInstance());
916     EXPECT_EQ(old_popup_site_instance.get(), popup->GetSiteInstance());
917     EXPECT_NE(url::kDataScheme,
918               popup->GetSiteInstance()->GetSiteURL().scheme());
919   }
920 }
921
922 class SignInIsolationBrowserTest : public ChromeNavigationBrowserTest {
923  public:
924   SignInIsolationBrowserTest()
925       : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
926   ~SignInIsolationBrowserTest() override {}
927
928   void SetUp() override {
929     https_server_.ServeFilesFromSourceDirectory("chrome/test/data");
930     ASSERT_TRUE(https_server_.InitializeAndListen());
931     ChromeNavigationBrowserTest::SetUp();
932   }
933
934   void SetUpCommandLine(base::CommandLine* command_line) override {
935     // Override the sign-in URL so that it includes correct port from the test
936     // server.
937     command_line->AppendSwitchASCII(
938         ::switches::kGaiaUrl,
939         https_server()->GetURL("accounts.google.com", "/").spec());
940
941     // Ignore cert errors so that the sign-in URL can be loaded from a site
942     // other than localhost (the EmbeddedTestServer serves a certificate that
943     // is valid for localhost).
944     command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
945
946     ChromeNavigationBrowserTest::SetUpCommandLine(command_line);
947   }
948
949   void SetUpOnMainThread() override {
950     https_server_.StartAcceptingConnections();
951     ChromeNavigationBrowserTest::SetUpOnMainThread();
952   }
953
954   net::EmbeddedTestServer* https_server() { return &https_server_; }
955
956  private:
957   net::EmbeddedTestServer https_server_;
958
959   DISALLOW_COPY_AND_ASSIGN(SignInIsolationBrowserTest);
960 };
961
962 // This test ensures that the sign-in origin requires a dedicated process.  It
963 // only ensures that the sign-in origin is added as an isolated origin at
964 // chrome/ layer; IsolatedOriginTest provides the main test coverage of origins
965 // whitelisted for process isolation.  See https://crbug.com/739418.
966 IN_PROC_BROWSER_TEST_F(SignInIsolationBrowserTest, NavigateToSignInPage) {
967   const GURL first_url =
968       embedded_test_server()->GetURL("google.com", "/title1.html");
969   const GURL signin_url =
970       https_server()->GetURL("accounts.google.com", "/title1.html");
971   ui_test_utils::NavigateToURL(browser(), first_url);
972   content::WebContents* web_contents =
973       browser()->tab_strip_model()->GetActiveWebContents();
974   scoped_refptr<content::SiteInstance> first_instance(
975       web_contents->GetMainFrame()->GetSiteInstance());
976
977   // Make sure that a renderer-initiated navigation to the sign-in page swaps
978   // processes.
979   content::TestNavigationManager manager(web_contents, signin_url);
980   EXPECT_TRUE(
981       ExecuteScript(web_contents, "location = '" + signin_url.spec() + "';"));
982   manager.WaitForNavigationFinished();
983   EXPECT_NE(web_contents->GetMainFrame()->GetSiteInstance(), first_instance);
984 }
985
986 class WebstoreIsolationBrowserTest : public ChromeNavigationBrowserTest {
987  public:
988   WebstoreIsolationBrowserTest()
989       : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
990   ~WebstoreIsolationBrowserTest() override {}
991
992   void SetUp() override {
993     https_server_.ServeFilesFromSourceDirectory("chrome/test/data");
994     ASSERT_TRUE(https_server_.InitializeAndListen());
995     ChromeNavigationBrowserTest::SetUp();
996   }
997
998   void SetUpCommandLine(base::CommandLine* command_line) override {
999     // Override the webstore URL.
1000     command_line->AppendSwitchASCII(
1001         ::switches::kAppsGalleryURL,
1002         https_server()->GetURL("chrome.foo.com", "/frame_tree").spec());
1003
1004     // Ignore cert errors so that the webstore URL can be loaded from a site
1005     // other than localhost (the EmbeddedTestServer serves a certificate that
1006     // is valid for localhost).
1007     command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
1008
1009     ChromeNavigationBrowserTest::SetUpCommandLine(command_line);
1010   }
1011
1012   void SetUpOnMainThread() override {
1013     https_server_.StartAcceptingConnections();
1014     ChromeNavigationBrowserTest::SetUpOnMainThread();
1015   }
1016
1017   net::EmbeddedTestServer* https_server() { return &https_server_; }
1018
1019  private:
1020   net::EmbeddedTestServer https_server_;
1021
1022   DISALLOW_COPY_AND_ASSIGN(WebstoreIsolationBrowserTest);
1023 };
1024
1025 // Make sure that Chrome Web Store origins are isolated from the rest of their
1026 // foo.com site.  See https://crbug.com/939108.
1027 IN_PROC_BROWSER_TEST_F(WebstoreIsolationBrowserTest, WebstorePopupIsIsolated) {
1028   const GURL first_url = https_server()->GetURL("foo.com", "/title1.html");
1029   ui_test_utils::NavigateToURL(browser(), first_url);
1030   content::WebContents* web_contents =
1031       browser()->tab_strip_model()->GetActiveWebContents();
1032
1033   // Open a popup for chrome.foo.com and ensure that it's isolated in a
1034   // different SiteInstance and process from the rest of foo.com.  Note that
1035   // we're opening a URL that does *not* match the web store URL due to a
1036   // different path, so there will be no BrowsingInstance swap, and window.open
1037   // is still expected to return a valid window reference.
1038   content::TestNavigationObserver popup_waiter(nullptr, 1);
1039   popup_waiter.StartWatchingNewWebContents();
1040   const GURL webstore_origin_url =
1041       https_server()->GetURL("chrome.foo.com", "/title1.html");
1042   EXPECT_TRUE(content::EvalJs(
1043                   web_contents,
1044                   content::JsReplace("!!window.open($1);", webstore_origin_url))
1045                   .ExtractBool());
1046   popup_waiter.Wait();
1047   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1048   content::WebContents* popup =
1049       browser()->tab_strip_model()->GetActiveWebContents();
1050   EXPECT_NE(popup, web_contents);
1051   EXPECT_TRUE(content::WaitForLoadStop(popup));
1052
1053   scoped_refptr<content::SiteInstance> popup_instance(
1054       popup->GetMainFrame()->GetSiteInstance());
1055   EXPECT_NE(web_contents->GetMainFrame()->GetSiteInstance(), popup_instance);
1056   EXPECT_NE(web_contents->GetMainFrame()->GetSiteInstance()->GetProcess(),
1057             popup_instance->GetProcess());
1058
1059   // Also navigate the popup to the full web store URL and confirm that this
1060   // causes a BrowsingInstance swap.
1061   const GURL webstore_url =
1062       https_server()->GetURL("chrome.foo.com", "/frame_tree/simple.htm");
1063   content::TestNavigationManager manager(popup, webstore_url);
1064   EXPECT_TRUE(
1065       ExecuteScript(popup, "location = '" + webstore_url.spec() + "';"));
1066   manager.WaitForNavigationFinished();
1067   EXPECT_NE(popup->GetMainFrame()->GetSiteInstance(), popup_instance);
1068   EXPECT_NE(popup->GetMainFrame()->GetSiteInstance(),
1069             web_contents->GetMainFrame()->GetSiteInstance());
1070   EXPECT_FALSE(popup->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
1071       popup_instance.get()));
1072   EXPECT_FALSE(popup->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance(
1073       web_contents->GetMainFrame()->GetSiteInstance()));
1074 }
1075
1076 // Helper class. Track one navigation and tell whether a response from the
1077 // server has been received or not. It is useful for discerning navigations
1078 // blocked after or before the request has been sent.
1079 class WillProcessResponseObserver : public content::WebContentsObserver {
1080  public:
1081   explicit WillProcessResponseObserver(content::WebContents* web_contents,
1082                                        const GURL& url)
1083       : content::WebContentsObserver(web_contents), url_(url) {}
1084   ~WillProcessResponseObserver() override {}
1085
1086   bool WillProcessResponseCalled() { return will_process_response_called_; }
1087
1088  private:
1089   GURL url_;
1090   bool will_process_response_called_ = false;
1091
1092   // Is used to set |will_process_response_called_| to true when
1093   // NavigationThrottle::WillProcessResponse() is called.
1094   class WillProcessResponseObserverThrottle
1095       : public content::NavigationThrottle {
1096    public:
1097     WillProcessResponseObserverThrottle(content::NavigationHandle* handle,
1098                                         bool* will_process_response_called)
1099         : NavigationThrottle(handle),
1100           will_process_response_called_(will_process_response_called) {}
1101
1102     const char* GetNameForLogging() override {
1103       return "WillProcessResponseObserverThrottle";
1104     }
1105
1106    private:
1107     bool* will_process_response_called_;
1108     NavigationThrottle::ThrottleCheckResult WillProcessResponse() override {
1109       *will_process_response_called_ = true;
1110       return NavigationThrottle::PROCEED;
1111     }
1112   };
1113
1114   // WebContentsObserver
1115   void DidStartNavigation(content::NavigationHandle* handle) override {
1116     if (handle->GetURL() == url_) {
1117       handle->RegisterThrottleForTesting(
1118           std::make_unique<WillProcessResponseObserverThrottle>(
1119               handle, &will_process_response_called_));
1120     }
1121   }
1122 };
1123
1124 // In HTTP/HTTPS documents, check that no request with the "ftp:" scheme are
1125 // submitted to load an iframe.
1126 // See https://crbug.com/757809.
1127 // Note: This test couldn't be a content_browsertests, since there would be
1128 // no handler defined for the "ftp" protocol in
1129 // URLRequestJobFactoryImpl::protocol_handler_map_.
1130 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, BlockLegacySubresources) {
1131   net::SpawnedTestServer ftp_server(net::SpawnedTestServer::TYPE_FTP,
1132                                     GetChromeTestDataDir());
1133   ASSERT_TRUE(ftp_server.Start());
1134
1135   GURL main_url_http(embedded_test_server()->GetURL("/iframe.html"));
1136   GURL iframe_url_http(embedded_test_server()->GetURL("/simple.html"));
1137   GURL iframe_url_ftp(ftp_server.GetURL("simple.html"));
1138   GURL redirect_url(embedded_test_server()->GetURL("/server-redirect?"));
1139
1140   struct {
1141     GURL main_url;
1142     GURL iframe_url;
1143     bool allowed;
1144   } kTestCases[] = {
1145       {main_url_http, iframe_url_http, true},
1146       {main_url_http, iframe_url_ftp, false},
1147   };
1148   for (const auto& test_case : kTestCases) {
1149     // Blocking the request should work, even after a redirect.
1150     for (bool redirect : {false, true}) {
1151       GURL iframe_url =
1152           redirect ? GURL(redirect_url.spec() + test_case.iframe_url.spec())
1153                    : test_case.iframe_url;
1154       SCOPED_TRACE(::testing::Message()
1155                    << std::endl
1156                    << "- main_url = " << test_case.main_url << std::endl
1157                    << "- iframe_url = " << iframe_url << std::endl);
1158
1159       ui_test_utils::NavigateToURL(browser(), test_case.main_url);
1160       content::WebContents* web_contents =
1161           browser()->tab_strip_model()->GetActiveWebContents();
1162       content::NavigationHandleObserver navigation_handle_observer(web_contents,
1163                                                                    iframe_url);
1164       WillProcessResponseObserver will_process_response_observer(web_contents,
1165                                                                  iframe_url);
1166       EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", iframe_url));
1167
1168       if (test_case.allowed) {
1169         EXPECT_TRUE(will_process_response_observer.WillProcessResponseCalled());
1170         EXPECT_FALSE(navigation_handle_observer.is_error());
1171         EXPECT_EQ(test_case.iframe_url,
1172                   navigation_handle_observer.last_committed_url());
1173       } else {
1174         EXPECT_FALSE(
1175             will_process_response_observer.WillProcessResponseCalled());
1176         EXPECT_TRUE(navigation_handle_observer.is_error());
1177         EXPECT_EQ(net::ERR_ABORTED,
1178                   navigation_handle_observer.net_error_code());
1179       }
1180     }
1181   }
1182 }
1183
1184 // Check that it's possible to navigate to a chrome scheme URL from a crashed
1185 // tab. See https://crbug.com/764641.
1186 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, ChromeSchemeNavFromSadTab) {
1187   // Kill the renderer process.
1188   content::RenderProcessHost* process = browser()
1189                                             ->tab_strip_model()
1190                                             ->GetActiveWebContents()
1191                                             ->GetMainFrame()
1192                                             ->GetProcess();
1193   content::RenderProcessHostWatcher crash_observer(
1194       process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
1195   process->Shutdown(-1);
1196   crash_observer.Wait();
1197
1198   // Attempt to navigate to a chrome://... URL.
1199   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIVersionURL));
1200 }
1201
1202 // Check that a browser-initiated navigation to a cross-site URL that then
1203 // redirects to a pdf hosted on another site works.
1204 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, CrossSiteRedirectionToPDF) {
1205   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
1206   https_server.AddDefaultHandlers(GetChromeTestDataDir());
1207   ASSERT_TRUE(https_server.Start());
1208
1209   GURL initial_url = embedded_test_server()->GetURL("/title1.html");
1210   GURL pdf_url = embedded_test_server()->GetURL("/pdf/test.pdf");
1211   GURL cross_site_redirecting_url =
1212       https_server.GetURL("/server-redirect?" + pdf_url.spec());
1213   ui_test_utils::NavigateToURL(browser(), initial_url);
1214   ui_test_utils::NavigateToURL(browser(), cross_site_redirecting_url);
1215   EXPECT_EQ(pdf_url, browser()
1216                          ->tab_strip_model()
1217                          ->GetActiveWebContents()
1218                          ->GetLastCommittedURL());
1219 }
1220
1221 // Check that clicking on a link doesn't carry the transient user activation
1222 // from the original page to the navigated page (crbug.com/865243).
1223 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
1224                        WindowOpenBlockedAfterClickNavigation) {
1225   // Navigate to a test page with links.
1226   ui_test_utils::NavigateToURL(browser(),
1227                                embedded_test_server()->GetURL("/links.html"));
1228
1229   // Click to navigate to title1.html.
1230   content::WebContents* main_contents =
1231       browser()->tab_strip_model()->GetActiveWebContents();
1232   content::TestNavigationObserver observer(main_contents);
1233   ASSERT_TRUE(ExecuteScript(main_contents,
1234                             "document.getElementById('title1').click();"));
1235   observer.Wait();
1236
1237   // Make sure popup attempt fails due to lack of transient user activation.
1238   bool opened = false;
1239   EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool(
1240       main_contents, "window.domAutomationController.send(!!window.open());",
1241       &opened));
1242   EXPECT_FALSE(opened);
1243
1244   EXPECT_EQ(embedded_test_server()->GetURL("/title1.html"),
1245             main_contents->GetLastCommittedURL());
1246   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1247 }
1248
1249 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
1250                        OpenerNavigation_DownloadPolicy_Disallowed) {
1251   browser()->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload,
1252                                                false);
1253   ui_test_utils::NavigateToURL(
1254       browser(), embedded_test_server()->GetURL("a.com", "/title1.html"));
1255
1256   // Open a popup.
1257   bool opened = false;
1258   content::WebContents* opener =
1259       browser()->tab_strip_model()->GetActiveWebContents();
1260   const char* kScriptFormat =
1261       "window.domAutomationController.send(!!window.open('%s'));";
1262   GURL popup_url = embedded_test_server()->GetURL("b.com", "/title1.html");
1263   content::TestNavigationObserver popup_waiter(nullptr, 1);
1264   popup_waiter.StartWatchingNewWebContents();
1265   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1266       opener, base::StringPrintf(kScriptFormat, popup_url.spec().c_str()),
1267       &opened));
1268   EXPECT_TRUE(opened);
1269   popup_waiter.Wait();
1270   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1271
1272   // Using the popup, navigate its opener to a download.
1273   base::HistogramTester histograms;
1274   content::WebContents* popup =
1275       browser()->tab_strip_model()->GetActiveWebContents();
1276   EXPECT_NE(popup, opener);
1277   EXPECT_TRUE(WaitForLoadStop(popup));
1278
1279   content::ConsoleObserverDelegate console_observer(
1280       opener,
1281       "Navigating a cross-origin opener to a download (*) is deprecated*");
1282   opener->SetDelegate(&console_observer);
1283   EXPECT_TRUE(content::ExecuteScript(
1284       popup,
1285       "window.opener.location ='data:html/text;base64,'+btoa('payload');"));
1286
1287   console_observer.Wait();
1288   histograms.ExpectBucketCount(
1289       "Blink.UseCounter.Features",
1290       blink::mojom::WebFeature::kOpenerNavigationDownloadCrossOrigin, 1);
1291
1292   // Ensure that no download happened.
1293   std::vector<download::DownloadItem*> download_items;
1294   content::DownloadManager* manager =
1295       content::BrowserContext::GetDownloadManager(browser()->profile());
1296   manager->GetAllDownloads(&download_items);
1297   EXPECT_TRUE(download_items.empty());
1298 }
1299
1300 // Opener navigations from a same-origin popup should be allowed.
1301 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
1302                        OpenerNavigation_DownloadPolicy_Allowed) {
1303   browser()->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload,
1304                                                false);
1305   ui_test_utils::NavigateToURL(
1306       browser(), embedded_test_server()->GetURL("a.com", "/title1.html"));
1307
1308   // Open a popup.
1309   bool opened = false;
1310   content::WebContents* opener =
1311       browser()->tab_strip_model()->GetActiveWebContents();
1312   const char* kScriptFormat =
1313       "window.domAutomationController.send(!!window.open('%s'));";
1314   GURL popup_url = embedded_test_server()->GetURL("a.com", "/title1.html");
1315   content::TestNavigationObserver popup_waiter(nullptr, 1);
1316   popup_waiter.StartWatchingNewWebContents();
1317   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1318       opener, base::StringPrintf(kScriptFormat, popup_url.spec().c_str()),
1319       &opened));
1320   EXPECT_TRUE(opened);
1321   popup_waiter.Wait();
1322   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1323
1324   // Using the popup, navigate its opener to a download.
1325   base::HistogramTester histograms;
1326   content::WebContents* popup =
1327       browser()->tab_strip_model()->GetActiveWebContents();
1328   EXPECT_NE(popup, opener);
1329   EXPECT_TRUE(WaitForLoadStop(popup));
1330
1331   content::DownloadTestObserverInProgress observer(
1332       content::BrowserContext::GetDownloadManager(browser()->profile()),
1333       1 /* wait_count */);
1334   EXPECT_TRUE(content::ExecuteScript(
1335       popup,
1336       "window.opener.location ='data:html/text;base64,'+btoa('payload');"));
1337   observer.WaitForFinished();
1338
1339   histograms.ExpectBucketCount(
1340       "Blink.UseCounter.Features",
1341       blink::mojom::WebFeature::kOpenerNavigationDownloadCrossOrigin, 0);
1342
1343   // Delete any pending download.
1344   std::vector<download::DownloadItem*> download_items;
1345   content::DownloadManager* manager =
1346       content::BrowserContext::GetDownloadManager(browser()->profile());
1347   manager->GetAllDownloads(&download_items);
1348   for (auto* item : download_items) {
1349     if (!item->IsDone())
1350       item->Cancel(true);
1351   }
1352 }
1353
1354 // Test which verifies that a noopener link/window.open() properly focus the
1355 // newly opened tab. See https://crbug.com/912348.
1356 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
1357                        NoopenerCorrectlyFocusesNewTab) {
1358   content::WebContents* main_contents =
1359       browser()->tab_strip_model()->GetActiveWebContents();
1360
1361   // Navigate to a test page with links.
1362   {
1363     content::TestNavigationObserver observer(main_contents);
1364     ui_test_utils::NavigateToURL(
1365         browser(),
1366         embedded_test_server()->GetURL("/click-noreferrer-links.html"));
1367     observer.Wait();
1368     EXPECT_TRUE(observer.last_navigation_succeeded());
1369   }
1370
1371   // Click a link with noopener that navigates in a new window.
1372   content::WebContents* link_web_contents = nullptr;
1373   {
1374     ui_test_utils::AllBrowserTabAddedWaiter tab_added;
1375     EXPECT_TRUE(
1376         content::ExecJs(main_contents, "clickSameSiteNoOpenerTargetedLink();"));
1377     link_web_contents = tab_added.Wait();
1378   }
1379
1380   EXPECT_NE(main_contents, link_web_contents);
1381   EXPECT_TRUE(link_web_contents->GetRenderWidgetHostView()->HasFocus());
1382
1383   // Execute window.open() with noopener.
1384   content::WebContents* open_web_contents = nullptr;
1385   {
1386     ui_test_utils::AllBrowserTabAddedWaiter tab_added;
1387     EXPECT_TRUE(content::ExecJs(
1388         main_contents, content::JsReplace("window.open($1, 'bar', 'noopener');",
1389                                           embedded_test_server()->GetURL(
1390                                               "a.com", "/title1.html"))));
1391     open_web_contents = tab_added.Wait();
1392   }
1393
1394   EXPECT_NE(main_contents, open_web_contents);
1395   EXPECT_NE(link_web_contents, open_web_contents);
1396   EXPECT_TRUE(open_web_contents->GetRenderWidgetHostView()->HasFocus());
1397 }
1398
1399 // Tests the ukm entry logged when the navigation entry is marked as skippable
1400 // on back/forward button on doing a renderer initiated navigation without ever
1401 // getting a user activation.
1402 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
1403                        NoUserActivationSetSkipOnBackForward) {
1404   GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
1405   ui_test_utils::NavigateToURL(browser(), skippable_url);
1406
1407   GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
1408
1409   // Navigate to a new document from the renderer without a user gesture.
1410   content::WebContents* main_contents =
1411       browser()->tab_strip_model()->GetActiveWebContents();
1412   content::TestNavigationObserver observer(main_contents);
1413   EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
1414       main_contents, "location = '" + redirected_url.spec() + "';"));
1415   observer.Wait();
1416   EXPECT_EQ(redirected_url, main_contents->GetLastCommittedURL());
1417
1418   // Verify UKM.
1419   using Entry = ukm::builders::HistoryManipulationIntervention;
1420   const auto& ukm_entries =
1421       test_ukm_recorder()->GetEntriesByName(Entry::kEntryName);
1422   EXPECT_EQ(1u, ukm_entries.size());
1423   test_ukm_recorder()->ExpectEntrySourceHasUrl(ukm_entries[0], skippable_url);
1424
1425   // Verify the metric where user tries to go specifically to a skippable entry
1426   // using long press.
1427   base::HistogramTester histogram;
1428   std::unique_ptr<BackForwardMenuModel> back_model(
1429       std::make_unique<BackForwardMenuModel>(
1430           browser(), BackForwardMenuModel::ModelType::kBackward));
1431   back_model->set_test_web_contents(main_contents);
1432   back_model->ActivatedAt(0);
1433   histogram.ExpectBucketCount(
1434       "Navigation.BackForward.NavigatingToEntryMarkedToBeSkipped", true, 1);
1435 }
1436
1437 // Same as above except the navigation is cross-site.
1438 IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest,
1439                        NoUserActivationSetSkipOnBackForwardCrossSite) {
1440   GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
1441   ui_test_utils::NavigateToURL(browser(), skippable_url);
1442
1443   GURL redirected_url(
1444       embedded_test_server()->GetURL("foo.com", "/title2.html"));
1445   {
1446     // Navigate to a new document from the renderer without a user gesture.
1447     content::WebContents* main_contents =
1448         browser()->tab_strip_model()->GetActiveWebContents();
1449     content::TestNavigationObserver observer(main_contents);
1450     EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
1451         main_contents, "location = '" + redirected_url.spec() + "';"));
1452     observer.Wait();
1453     EXPECT_EQ(redirected_url, main_contents->GetLastCommittedURL());
1454   }
1455
1456   // Verify UKM.
1457   using Entry = ukm::builders::HistoryManipulationIntervention;
1458   const auto& ukm_entries =
1459       test_ukm_recorder()->GetEntriesByName(Entry::kEntryName);
1460   EXPECT_EQ(1u, ukm_entries.size());
1461   test_ukm_recorder()->ExpectEntrySourceHasUrl(ukm_entries[0], skippable_url);
1462 }
1463
1464 // TODO(csharrison): These tests should become tentative WPT, once the feature
1465 // is enabled by default.
1466 using NavigationConsumingTest = ChromeNavigationBrowserTest;
1467
1468 // The fullscreen API is spec'd to require a user activation (aka user gesture),
1469 // so use that API to test if navigation consumes the activation.
1470 // https://fullscreen.spec.whatwg.org/#allowed-to-request-fullscreen
1471 IN_PROC_BROWSER_TEST_F(NavigationConsumingTest,
1472                        NavigationConsumesUserGesture_Fullscreen) {
1473   ui_test_utils::NavigateToURL(
1474       browser(),
1475       embedded_test_server()->GetURL("/navigation_consumes_gesture.html"));
1476   content::WebContents* contents =
1477       browser()->tab_strip_model()->GetActiveWebContents();
1478
1479   // Normally, fullscreen should work, as long as there is a user gesture.
1480   bool is_fullscreen = false;
1481   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1482       contents, "document.body.webkitRequestFullscreen();", &is_fullscreen));
1483   EXPECT_TRUE(is_fullscreen);
1484
1485   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1486       contents, "document.webkitExitFullscreen();", &is_fullscreen));
1487   EXPECT_FALSE(is_fullscreen);
1488
1489   // However, starting a navigation should consume the gesture. Fullscreen
1490   // should not work afterwards. Make sure the navigation is synchronously
1491   // started via click().
1492   std::string script = R"(
1493     document.getElementsByTagName('a')[0].click();
1494     document.body.webkitRequestFullscreen();
1495   )";
1496
1497   // Use the TestNavigationManager to ensure the navigation is not finished
1498   // before fullscreen can occur.
1499   content::TestNavigationManager nav_manager(
1500       contents, embedded_test_server()->GetURL("/title1.html"));
1501   EXPECT_TRUE(
1502       content::ExecuteScriptAndExtractBool(contents, script, &is_fullscreen));
1503   EXPECT_FALSE(is_fullscreen);
1504 }
1505
1506 // Similar to the fullscreen test above, but checks that popups are successfully
1507 // blocked if spawned after a navigation.
1508 IN_PROC_BROWSER_TEST_F(NavigationConsumingTest,
1509                        NavigationConsumesUserGesture_Popups) {
1510   ui_test_utils::NavigateToURL(browser(),
1511                                embedded_test_server()->GetURL("/links.html"));
1512   content::WebContents* contents =
1513       browser()->tab_strip_model()->GetActiveWebContents();
1514
1515   // Normally, a popup should open fine if it is associated with a user gesture.
1516   bool did_open = false;
1517   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1518       contents, "window.domAutomationController.send(!!window.open());",
1519       &did_open));
1520   EXPECT_TRUE(did_open);
1521
1522   // Starting a navigation should consume a gesture, but make sure that starting
1523   // a same-document navigation doesn't do the consuming.
1524   std::string same_document_script = R"(
1525     document.getElementById("ref").click();
1526     window.domAutomationController.send(!!window.open());
1527   )";
1528   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1529       contents, same_document_script, &did_open));
1530   EXPECT_TRUE(did_open);
1531
1532   // If the navigation is to a different document, the gesture should be
1533   // successfully consumed.
1534   std::string different_document_script = R"(
1535     document.getElementById("title1").click();
1536     window.domAutomationController.send(!!window.open());
1537   )";
1538   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1539       contents, different_document_script, &did_open));
1540   EXPECT_FALSE(did_open);
1541 }
1542
1543 // Regression test for https://crbug.com/856779, where a navigation to a
1544 // top-level, same process frame in another tab fails to focus that tab.
1545 IN_PROC_BROWSER_TEST_F(NavigationConsumingTest, TargetNavigationFocus) {
1546   content::WebContents* opener =
1547       browser()->tab_strip_model()->GetActiveWebContents();
1548   ui_test_utils::NavigateToURL(
1549       browser(), embedded_test_server()->GetURL("/link_with_target.html"));
1550
1551   {
1552     content::TestNavigationObserver new_tab_observer(nullptr, 1);
1553     new_tab_observer.StartWatchingNewWebContents();
1554     ASSERT_TRUE(ExecuteScript(
1555         opener, "document.getElementsByTagName('a')[0].click();"));
1556     new_tab_observer.Wait();
1557   }
1558
1559   content::WebContents* new_contents =
1560       browser()->tab_strip_model()->GetActiveWebContents();
1561   EXPECT_NE(new_contents, opener);
1562
1563   // Re-focusing the opener and clicking again should re-focus the popup.
1564   opener->GetDelegate()->ActivateContents(opener);
1565   EXPECT_EQ(opener, browser()->tab_strip_model()->GetActiveWebContents());
1566   {
1567     content::TestNavigationObserver new_tab_observer(new_contents, 1);
1568     ASSERT_TRUE(ExecuteScript(
1569         opener, "document.getElementsByTagName('a')[0].click();"));
1570     new_tab_observer.Wait();
1571   }
1572   EXPECT_EQ(new_contents, browser()->tab_strip_model()->GetActiveWebContents());
1573 }
1574
1575 using HistoryManipulationInterventionBrowserTest = ChromeNavigationBrowserTest;
1576
1577 // Tests that chrome::GoBack does nothing if all the previous entries are marked
1578 // as skippable and the back button is disabled.
1579 IN_PROC_BROWSER_TEST_F(HistoryManipulationInterventionBrowserTest,
1580                        AllEntriesSkippableBackButtonDisabled) {
1581   // Create a new tab to avoid confusion from having a NTP navigation entry.
1582   GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
1583   ui_test_utils::NavigateToURLWithDisposition(
1584       browser(), skippable_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
1585       ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
1586
1587   content::WebContents* main_contents =
1588       browser()->tab_strip_model()->GetActiveWebContents();
1589
1590   // Navigate to a new document from the renderer without a user gesture.
1591   GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
1592   content::TestNavigationManager manager(main_contents, redirected_url);
1593   EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
1594       main_contents, "location = '" + redirected_url.spec() + "';"));
1595   manager.WaitForNavigationFinished();
1596   ASSERT_EQ(redirected_url, main_contents->GetLastCommittedURL());
1597   ASSERT_EQ(2, main_contents->GetController().GetEntryCount());
1598
1599   // Attempting to go back should do nothing.
1600   ASSERT_FALSE(chrome::CanGoBack(browser()));
1601   chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
1602   ASSERT_EQ(redirected_url, main_contents->GetLastCommittedURL());
1603
1604   // Back command should be disabled.
1605   EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_BACK));
1606 }
1607
1608 // Tests that chrome::GoBack is successful if there is at least one entry not
1609 // marked as skippable and the back button should be enabled.
1610 IN_PROC_BROWSER_TEST_F(HistoryManipulationInterventionBrowserTest,
1611                        AllEntriesNotSkippableBackButtonEnabled) {
1612   // Navigate to a URL in the same tab. Note that at the start of the test this
1613   // tab already has about:blank.
1614   GURL skippable_url(embedded_test_server()->GetURL("/title1.html"));
1615   ui_test_utils::NavigateToURL(browser(), skippable_url);
1616
1617   content::WebContents* main_contents =
1618       browser()->tab_strip_model()->GetActiveWebContents();
1619
1620   // Navigate to a new document from the renderer without a user gesture.
1621   GURL redirected_url(embedded_test_server()->GetURL("/title2.html"));
1622   content::TestNavigationManager manager(main_contents, redirected_url);
1623   EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
1624       main_contents, "location = '" + redirected_url.spec() + "';"));
1625   manager.WaitForNavigationFinished();
1626   ASSERT_EQ(redirected_url, main_contents->GetLastCommittedURL());
1627   ASSERT_EQ(3, main_contents->GetController().GetEntryCount());
1628
1629   // Back command should be enabled.
1630   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_BACK));
1631
1632   // Attempting to go back should skip |skippable_url| and go to about:blank.
1633   ASSERT_TRUE(chrome::CanGoBack(browser()));
1634   content::TestNavigationObserver observer(main_contents);
1635   chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
1636   observer.Wait();
1637   ASSERT_EQ(GURL("about:blank"), main_contents->GetLastCommittedURL());
1638 }
1639
1640 // Tests that a main frame hosting pdf does not get skipped because of history
1641 // manipulation intervention if there was a user gesture.
1642 IN_PROC_BROWSER_TEST_F(HistoryManipulationInterventionBrowserTest,
1643                        PDFDoNotSkipOnBackForwardDueToUserGesture) {
1644   GURL pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf"));
1645   ui_test_utils::NavigateToURL(browser(), pdf_url);
1646
1647   GURL url(embedded_test_server()->GetURL("/title2.html"));
1648
1649   // Navigate to a new document from the renderer with a user gesture.
1650   content::WebContents* main_contents =
1651       browser()->tab_strip_model()->GetActiveWebContents();
1652   content::TestNavigationObserver observer(main_contents);
1653   EXPECT_TRUE(ExecuteScript(main_contents, "location = '" + url.spec() + "';"));
1654   observer.Wait();
1655   EXPECT_EQ(url, main_contents->GetLastCommittedURL());
1656
1657   // Since pdf_url initiated a navigation with a user gesture, it will
1658   // not be skipped. Going back should be allowed and should navigate to
1659   // pdf_url.
1660   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_BACK));
1661
1662   ASSERT_TRUE(chrome::CanGoBack(browser()));
1663   chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
1664   EXPECT_TRUE(content::WaitForLoadStop(main_contents));
1665   ASSERT_EQ(pdf_url, main_contents->GetLastCommittedURL());
1666 }
1667
1668 // Tests that a main frame hosting pdf gets skipped because of history
1669 // manipulation intervention if there was no user gesture.
1670 IN_PROC_BROWSER_TEST_F(HistoryManipulationInterventionBrowserTest,
1671                        PDFSkipOnBackForwardNoUserGesture) {
1672   GURL pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf"));
1673   ui_test_utils::NavigateToURL(browser(), pdf_url);
1674
1675   GURL url(embedded_test_server()->GetURL("/title2.html"));
1676
1677   // Navigate to a new document from the renderer without a user gesture.
1678   content::WebContents* main_contents =
1679       browser()->tab_strip_model()->GetActiveWebContents();
1680   content::TestNavigationObserver observer(main_contents);
1681   EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
1682       main_contents, "location = '" + url.spec() + "';"));
1683   observer.Wait();
1684   EXPECT_EQ(url, main_contents->GetLastCommittedURL());
1685
1686   // Since pdf_url initiated a navigation without a user gesture, it will
1687   // be skipped. Going back should be allowed and should navigate to
1688   // about:blank.
1689   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_BACK));
1690
1691   ASSERT_TRUE(chrome::CanGoBack(browser()));
1692   chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
1693   EXPECT_TRUE(content::WaitForLoadStop(main_contents));
1694   ASSERT_EQ(GURL("about:blank"), main_contents->GetLastCommittedURL());
1695 }
1696
1697 // This test class turns on the mode where sites where the user enters a
1698 // password are dynamically added to the list of sites requiring a dedicated
1699 // process.  It also disables strict site isolation so that the effects of
1700 // password isolation can be observed.
1701 class SiteIsolationForPasswordSitesBrowserTest
1702     : public ChromeNavigationBrowserTest {
1703  public:
1704   SiteIsolationForPasswordSitesBrowserTest() {
1705     feature_list_.InitWithFeatures(
1706         {site_isolation::features::kSiteIsolationForPasswordSites},
1707         {features::kSitePerProcess});
1708   }
1709
1710   std::vector<std::string> GetSavedIsolatedSites() {
1711     return GetSavedIsolatedSites(browser()->profile());
1712   }
1713
1714   std::vector<std::string> GetSavedIsolatedSites(Profile* profile) {
1715     PrefService* prefs = profile->GetPrefs();
1716     auto* list =
1717         prefs->GetList(site_isolation::prefs::kUserTriggeredIsolatedOrigins);
1718     std::vector<std::string> sites;
1719     for (const base::Value& value : list->GetList())
1720       sites.push_back(value.GetString());
1721     return sites;
1722   }
1723
1724   bool HasSyntheticTrial(const std::string& trial_name) {
1725     std::vector<std::string> synthetic_trials;
1726     variations::GetSyntheticTrialGroupIdsAsString(&synthetic_trials);
1727     std::string trial_hash =
1728         base::StringPrintf("%x", variations::HashName(trial_name));
1729     auto it =
1730         std::find_if(synthetic_trials.begin(), synthetic_trials.end(),
1731                      [trial_hash](const auto& trial) {
1732                        return base::StartsWith(trial, trial_hash,
1733                                                base::CompareCase::SENSITIVE);
1734                      });
1735     return it != synthetic_trials.end();
1736   }
1737
1738   bool IsInSyntheticTrialGroup(const std::string& trial_name,
1739                                const std::string& trial_group) {
1740     std::vector<std::string> synthetic_trials;
1741     variations::GetSyntheticTrialGroupIdsAsString(&synthetic_trials);
1742     std::string expected_entry =
1743         base::StringPrintf("%x-%x", variations::HashName(trial_name),
1744                            variations::HashName(trial_group));
1745     return std::find(synthetic_trials.begin(), synthetic_trials.end(),
1746                      expected_entry) != synthetic_trials.end();
1747   }
1748
1749   const std::string kSiteIsolationSyntheticTrialName = "SiteIsolationActive";
1750   const std::string kOOPIFSyntheticTrialName = "OutOfProcessIframesActive";
1751   const std::string kSyntheticTrialGroup = "Enabled";
1752
1753  protected:
1754   void SetUpCommandLine(base::CommandLine* command_line) override {
1755     ChromeNavigationBrowserTest::SetUpCommandLine(command_line);
1756
1757     // This simulates a whitelist of isolated sites.
1758     std::string origin_list =
1759         embedded_test_server()->GetURL("isolated1.com", "/").spec() + "," +
1760         embedded_test_server()->GetURL("isolated2.com", "/").spec();
1761     command_line->AppendSwitchASCII(switches::kIsolateOrigins, origin_list);
1762
1763     // Allow HTTPS server to be used on sites other than localhost.
1764     command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
1765   }
1766
1767  private:
1768   base::test::ScopedFeatureList feature_list_;
1769 };
1770
1771 // Verifies that a site gets process-isolated after a password is typed on a
1772 // page from that site.
1773 IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest,
1774                        SiteIsIsolatedAfterEnteringPassword) {
1775   // This test requires dynamic isolated origins to be enabled.
1776   if (!content::SiteIsolationPolicy::AreDynamicIsolatedOriginsEnabled())
1777     return;
1778
1779   GURL url(embedded_test_server()->GetURL("sub.foo.com",
1780                                           "/password/password_form.html"));
1781   ui_test_utils::NavigateToURL(browser(), url);
1782   content::WebContents* contents =
1783       browser()->tab_strip_model()->GetActiveWebContents();
1784
1785   // foo.com should not be isolated to start with. Verify that a cross-site
1786   // iframe does not become an OOPIF.
1787   EXPECT_FALSE(
1788       contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
1789   std::string kAppendIframe = R"(
1790       var i = document.createElement('iframe');
1791       i.id = 'child';
1792       document.body.appendChild(i);)";
1793   EXPECT_TRUE(ExecJs(contents, kAppendIframe));
1794   GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
1795   EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url));
1796   content::RenderFrameHost* child = ChildFrameAt(contents->GetMainFrame(), 0);
1797   EXPECT_FALSE(child->IsCrossProcessSubframe());
1798
1799   // Fill a form and submit through a <input type="submit"> button.
1800   content::TestNavigationObserver observer(contents);
1801   std::string kFillAndSubmit =
1802       "document.getElementById('username_field').value = 'temp';"
1803       "document.getElementById('password_field').value = 'random';"
1804       "document.getElementById('input_submit_button').click()";
1805   EXPECT_TRUE(content::ExecJs(contents, kFillAndSubmit));
1806   observer.Wait();
1807
1808   // Since there were no script references from other windows, we should've
1809   // swapped BrowsingInstances and put the result of the form submission into a
1810   // dedicated process, locked to foo.com.  Check that a cross-site iframe now
1811   // becomes an OOPIF.
1812   EXPECT_TRUE(
1813       contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
1814   EXPECT_TRUE(ExecJs(contents, kAppendIframe));
1815   EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url));
1816   child = ChildFrameAt(contents->GetMainFrame(), 0);
1817   EXPECT_TRUE(child->IsCrossProcessSubframe());
1818
1819   // Open a fresh tab (also forcing a new BrowsingInstance), navigate to
1820   // foo.com, and verify that a cross-site iframe becomes an OOPIF.
1821   AddBlankTabAndShow(browser());
1822   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1823   content::WebContents* new_contents =
1824       browser()->tab_strip_model()->GetActiveWebContents();
1825   EXPECT_NE(new_contents, contents);
1826
1827   ui_test_utils::NavigateToURL(browser(), url);
1828   EXPECT_TRUE(ExecJs(new_contents, kAppendIframe));
1829   EXPECT_TRUE(NavigateIframeToURL(new_contents, "child", bar_url));
1830   content::RenderFrameHost* new_child =
1831       ChildFrameAt(new_contents->GetMainFrame(), 0);
1832   EXPECT_TRUE(new_child->IsCrossProcessSubframe());
1833 }
1834
1835 // This test checks that the synthetic field trial is activated properly after
1836 // a navigation to an isolated origin commits in a main frame.
1837 IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest,
1838                        SyntheticTrialFromMainFrame) {
1839   content::WebContents* web_contents =
1840       browser()->tab_strip_model()->GetActiveWebContents();
1841
1842   NavigationMetricsRecorder* recorder =
1843       content::WebContentsUserData<NavigationMetricsRecorder>::FromWebContents(
1844           web_contents);
1845   recorder->EnableSiteIsolationSyntheticTrialForTesting();
1846
1847   EXPECT_FALSE(HasSyntheticTrial(kSiteIsolationSyntheticTrialName));
1848   EXPECT_FALSE(HasSyntheticTrial(kOOPIFSyntheticTrialName));
1849
1850   // Browse to a page with some iframes without involving any isolated origins.
1851   GURL unisolated_url(embedded_test_server()->GetURL(
1852       "a.com", "/cross_site_iframe_factory.html?a(b,c(a))"));
1853   ui_test_utils::NavigateToURL(browser(), unisolated_url);
1854   EXPECT_FALSE(HasSyntheticTrial(kSiteIsolationSyntheticTrialName));
1855
1856   // Now browse to an isolated origin.
1857   GURL isolated_url(
1858       embedded_test_server()->GetURL("isolated1.com", "/title1.html"));
1859   ui_test_utils::NavigateToURL(browser(), isolated_url);
1860   EXPECT_TRUE(IsInSyntheticTrialGroup(kSiteIsolationSyntheticTrialName,
1861                                       kSyntheticTrialGroup));
1862
1863   // The OOPIF synthetic trial shouldn't be activated, since the isolated
1864   // oriign page doesn't have any OOPIFs.
1865   EXPECT_FALSE(
1866       IsInSyntheticTrialGroup(kOOPIFSyntheticTrialName, kSyntheticTrialGroup));
1867 }
1868
1869 // This test checks that the synthetic field trials for both site isolation and
1870 // encountering OOPIFs are activated properly after a navigation to an isolated
1871 // origin commits in a subframe.
1872 IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest,
1873                        SyntheticTrialFromSubframe) {
1874   content::WebContents* web_contents =
1875       browser()->tab_strip_model()->GetActiveWebContents();
1876
1877   NavigationMetricsRecorder* recorder =
1878       content::WebContentsUserData<NavigationMetricsRecorder>::FromWebContents(
1879           web_contents);
1880   recorder->EnableSiteIsolationSyntheticTrialForTesting();
1881
1882   EXPECT_FALSE(HasSyntheticTrial(kSiteIsolationSyntheticTrialName));
1883   EXPECT_FALSE(HasSyntheticTrial(kOOPIFSyntheticTrialName));
1884
1885   // Browse to a page with an isolated origin on one of the iframes.
1886   GURL isolated_url(embedded_test_server()->GetURL(
1887       "a.com", "/cross_site_iframe_factory.html?a(b,c,isolated2,d)"));
1888   ui_test_utils::NavigateToURL(browser(), isolated_url);
1889   EXPECT_TRUE(IsInSyntheticTrialGroup(kSiteIsolationSyntheticTrialName,
1890                                       kSyntheticTrialGroup));
1891   EXPECT_TRUE(
1892       IsInSyntheticTrialGroup(kOOPIFSyntheticTrialName, kSyntheticTrialGroup));
1893 }
1894
1895 // Verifies that persistent isolated sites survive restarts.  Part 1.
1896 IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest,
1897                        PRE_IsolatedSitesPersistAcrossRestarts) {
1898   // There shouldn't be any saved isolated origins to start with.
1899   EXPECT_THAT(GetSavedIsolatedSites(), IsEmpty());
1900
1901   // Isolate saved.com and saved2.com persistently.
1902   GURL saved_url(embedded_test_server()->GetURL("saved.com", "/title1.html"));
1903   content::SiteInstance::StartIsolatingSite(browser()->profile(), saved_url);
1904   GURL saved2_url(embedded_test_server()->GetURL("saved2.com", "/title1.html"));
1905   content::SiteInstance::StartIsolatingSite(browser()->profile(), saved2_url);
1906
1907   // Check that saved.com utilizes a dedicated process in future navigations.
1908   // Open a new tab to force creation of a new BrowsingInstance.
1909   AddBlankTabAndShow(browser());
1910   ui_test_utils::NavigateToURL(browser(), saved_url);
1911   content::WebContents* contents =
1912       browser()->tab_strip_model()->GetActiveWebContents();
1913   EXPECT_TRUE(
1914       contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
1915
1916   // Check that saved.com and saved2.com were saved to disk.
1917   EXPECT_THAT(GetSavedIsolatedSites(),
1918               UnorderedElementsAre("http://saved.com", "http://saved2.com"));
1919 }
1920
1921 // Verifies that process-isolated sites persist across restarts.  Part 2.
1922 // This runs after Part 1 above and in the same profile.  Part 1 has already
1923 // added "saved.com" as a persisted isolated origin, so this part verifies that
1924 // it requires a dedicated process after restart.
1925 IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest,
1926                        IsolatedSitesPersistAcrossRestarts) {
1927   // Check that saved.com and saved2.com are still saved to disk.
1928   EXPECT_THAT(GetSavedIsolatedSites(),
1929               UnorderedElementsAre("http://saved.com", "http://saved2.com"));
1930
1931   // Check that these sites utilize a dedicated process after restarting, but a
1932   // non-isolated foo.com URL does not.
1933   GURL saved_url(embedded_test_server()->GetURL("saved.com", "/title1.html"));
1934   GURL saved2_url(embedded_test_server()->GetURL("saved2.com", "/title2.html"));
1935   GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title3.html"));
1936   ui_test_utils::NavigateToURL(browser(), saved_url);
1937   content::WebContents* contents =
1938       browser()->tab_strip_model()->GetActiveWebContents();
1939   EXPECT_TRUE(
1940       contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
1941   ui_test_utils::NavigateToURL(browser(), saved2_url);
1942   EXPECT_TRUE(
1943       contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
1944   ui_test_utils::NavigateToURL(browser(), foo_url);
1945   EXPECT_FALSE(
1946       contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
1947 }
1948
1949 // Verify that trying to isolate a site multiple times will only save it to
1950 // disk once.
1951 IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest,
1952                        IsolatedSiteIsSavedOnlyOnce) {
1953   GURL saved_url(embedded_test_server()->GetURL("saved.com", "/title1.html"));
1954   content::SiteInstance::StartIsolatingSite(browser()->profile(), saved_url);
1955   content::SiteInstance::StartIsolatingSite(browser()->profile(), saved_url);
1956   content::SiteInstance::StartIsolatingSite(browser()->profile(), saved_url);
1957   EXPECT_THAT(GetSavedIsolatedSites(),
1958               UnorderedElementsAre("http://saved.com"));
1959 }
1960
1961 // Check that Incognito doesn't inherit saved isolated origins from its
1962 // original profile, and that any isolated origins added in Incognito don't
1963 // affect the original profile.
1964 IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest,
1965                        IncognitoWithIsolatedSites) {
1966   // Isolate saved.com and verify it's been saved to disk.
1967   GURL saved_url(embedded_test_server()->GetURL("saved.com", "/title1.html"));
1968   content::SiteInstance::StartIsolatingSite(browser()->profile(), saved_url);
1969   EXPECT_THAT(GetSavedIsolatedSites(),
1970               UnorderedElementsAre("http://saved.com"));
1971
1972   // Create an incognito browser and browse to saved.com.  Verify that it's
1973   // *not* isolated in incognito.
1974   //
1975   // TODO(alexmos): This might change in the future if we decide to inherit
1976   // main profile's isolated origins in incognito. See
1977   // https://crbug.com/905513.
1978   Browser* incognito = CreateIncognitoBrowser();
1979   ui_test_utils::NavigateToURL(incognito, saved_url);
1980   content::WebContents* contents =
1981       incognito->tab_strip_model()->GetActiveWebContents();
1982   EXPECT_FALSE(
1983       contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
1984
1985   // Add an isolated site in incognito, and verify that while future
1986   // navigations to this site in incognito require a dedicated process,
1987   // navigations to this site in the main profile do not require a dedicated
1988   // process, and the site is not persisted for either the main or incognito
1989   // profiles.
1990   GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
1991   content::SiteInstance::StartIsolatingSite(incognito->profile(), foo_url);
1992
1993   AddBlankTabAndShow(incognito);
1994   ui_test_utils::NavigateToURL(incognito, foo_url);
1995   contents = incognito->tab_strip_model()->GetActiveWebContents();
1996   EXPECT_TRUE(
1997       contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
1998
1999   AddBlankTabAndShow(browser());
2000   ui_test_utils::NavigateToURL(browser(), foo_url);
2001   contents = browser()->tab_strip_model()->GetActiveWebContents();
2002   EXPECT_FALSE(
2003       contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess());
2004
2005   EXPECT_THAT(GetSavedIsolatedSites(browser()->profile()),
2006               testing::Not(testing::Contains("http://foo.com")));
2007   EXPECT_THAT(GetSavedIsolatedSites(incognito->profile()),
2008               testing::Not(testing::Contains("http://foo.com")));
2009 }
2010
2011 // Verify that serving a Clear-Site-Data header does not clear saved isolated
2012 // sites.  Saved isolated sites should only be cleared by user-initiated
2013 // actions.
2014 IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest,
2015                        ClearSiteDataDoesNotClearSavedIsolatedSites) {
2016   // Start an HTTPS server, as Clear-Site-Data is only available on HTTPS URLs.
2017   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
2018   https_server.AddDefaultHandlers(GetChromeTestDataDir());
2019   ASSERT_TRUE(https_server.Start());
2020
2021   // Isolate saved.com and verify it's been saved to disk.
2022   GURL saved_url(https_server.GetURL("saved.com", "/clear_site_data.html"));
2023   content::SiteInstance::StartIsolatingSite(browser()->profile(), saved_url);
2024   EXPECT_THAT(GetSavedIsolatedSites(),
2025               UnorderedElementsAre("https://saved.com"));
2026
2027   // Navigate to a URL that serves a Clear-Site-Data header for cache, cookies,
2028   // and DOM storage. This is the most that a Clear-Site-Data header could
2029   // clear, and this should not clear saved isolated sites.
2030   ui_test_utils::NavigateToURL(browser(), saved_url);
2031   EXPECT_THAT(GetSavedIsolatedSites(),
2032               UnorderedElementsAre("https://saved.com"));
2033 }