1 // Copyright (c) 2012 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 "chrome/browser/ui/browser_navigator_browsertest.h"
6 #include "content/public/test/browser_test.h"
7 
8 #include <memory>
9 
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "build/build_config.h"
13 #include "chrome/app/chrome_command_ids.h"
14 #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h"
15 #include "chrome/browser/prefs/incognito_mode_prefs.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/renderer_host/chrome_navigation_ui_data.h"
18 #include "chrome/browser/search/search.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_commands.h"
21 #include "chrome/browser/ui/browser_finder.h"
22 #include "chrome/browser/ui/browser_navigator.h"
23 #include "chrome/browser/ui/browser_navigator_params.h"
24 #include "chrome/browser/ui/browser_tabstrip.h"
25 #include "chrome/browser/ui/browser_window.h"
26 #include "chrome/browser/ui/chrome_pages.h"
27 #include "chrome/browser/ui/location_bar/location_bar.h"
28 #include "chrome/browser/ui/search/local_ntp_test_utils.h"
29 #include "chrome/browser/ui/singleton_tabs.h"
30 #include "chrome/browser/ui/tabs/tab_strip_model.h"
31 #include "chrome/browser/web_applications/components/web_app_helpers.h"
32 #include "chrome/browser/web_applications/components/web_application_info.h"
33 #include "chrome/common/pref_names.h"
34 #include "chrome/common/url_constants.h"
35 #include "chrome/test/base/ui_test_utils.h"
36 #include "components/captive_portal/core/buildflags.h"
37 #include "components/omnibox/browser/omnibox_edit_model.h"
38 #include "components/omnibox/browser/omnibox_view.h"
39 #include "components/prefs/pref_service.h"
40 #include "content/public/browser/navigation_handle.h"
41 #include "content/public/browser/notification_service.h"
42 #include "content/public/browser/notification_types.h"
43 #include "content/public/browser/render_frame_host.h"
44 #include "content/public/browser/render_process_host.h"
45 #include "content/public/browser/render_view_host.h"
46 #include "content/public/browser/web_contents.h"
47 #include "content/public/common/bindings_policy.h"
48 #include "content/public/test/browser_test_utils.h"
49 #include "content/public/test/test_frame_navigation_observer.h"
50 #include "content/public/test/test_navigation_observer.h"
51 #include "net/test/embedded_test_server/embedded_test_server.h"
52 #include "services/network/public/cpp/resource_request_body.h"
53 
54 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
55 #include "components/captive_portal/content/captive_portal_tab_helper.h"
56 #endif
57 
58 using content::WebContents;
59 
60 namespace {
61 
62 const char kExpectedTitle[] = "PASSED!";
63 const char kEchoTitleCommand[] = "/echotitle";
64 
GetGoogleURL()65 GURL GetGoogleURL() {
66   return GURL("http://www.google.com/");
67 }
68 
GetSettingsURL()69 GURL GetSettingsURL() {
70   return GURL(chrome::kChromeUISettingsURL);
71 }
72 
GetWebUINewTabPage()73 GURL GetWebUINewTabPage() {
74   return GURL(chrome::kChromeUINewTabPageURL);
75 }
76 
GetContentSettingsURL()77 GURL GetContentSettingsURL() {
78   return GetSettingsURL().Resolve(chrome::kContentSettingsSubPage);
79 }
80 
GetClearBrowsingDataURL()81 GURL GetClearBrowsingDataURL() {
82   return GetSettingsURL().Resolve(chrome::kClearBrowserDataSubPage);
83 }
84 
ShowSettings(Browser * browser)85 void ShowSettings(Browser* browser) {
86   // chrome::ShowSettings just calls ShowSettingsSubPageInTabbedBrowser on
87   // non chromeos, but we want to test tab navigation here so call
88   // ShowSettingsSubPageInTabbedBrowser directly.
89   chrome::ShowSettingsSubPageInTabbedBrowser(browser, std::string());
90 }
91 
92 }  // namespace
93 
MakeNavigateParams() const94 NavigateParams BrowserNavigatorTest::MakeNavigateParams() const {
95   return MakeNavigateParams(browser());
96 }
97 
MakeNavigateParams(Browser * browser) const98 NavigateParams BrowserNavigatorTest::MakeNavigateParams(
99     Browser* browser) const {
100   NavigateParams params(browser, GetGoogleURL(), ui::PAGE_TRANSITION_LINK);
101   params.window_action = NavigateParams::SHOW_WINDOW;
102   return params;
103 }
104 
OpenPOSTURLInNewForegroundTabAndGetTitle(const GURL & url,const std::string & post_data,bool is_browser_initiated,base::string16 * title)105 bool BrowserNavigatorTest::OpenPOSTURLInNewForegroundTabAndGetTitle(
106     const GURL& url,
107     const std::string& post_data,
108     bool is_browser_initiated,
109     base::string16* title) {
110   NavigateParams param(MakeNavigateParams());
111   param.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
112   param.url = url;
113   param.initiator_origin = url::Origin();
114   param.is_renderer_initiated = !is_browser_initiated;
115   param.post_data = network::ResourceRequestBody::CreateFromBytes(
116       post_data.data(), post_data.size());
117 
118   ui_test_utils::NavigateToURL(&param);
119   if (!param.navigated_or_inserted_contents)
120     return false;
121 
122   // Navigate() should have opened the contents in new foreground tab in the
123   // current Browser.
124   EXPECT_EQ(browser(), param.browser);
125   EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
126             param.navigated_or_inserted_contents);
127   // We should have one window, with one tab.
128   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
129   EXPECT_EQ(2, browser()->tab_strip_model()->count());
130 
131   *title = param.navigated_or_inserted_contents->GetTitle();
132   return true;
133 }
134 
CreateEmptyBrowserForType(Browser::Type type,Profile * profile)135 Browser* BrowserNavigatorTest::CreateEmptyBrowserForType(Browser::Type type,
136                                                          Profile* profile) {
137   Browser* browser =
138       Browser::Create(Browser::CreateParams(type, profile, true));
139   chrome::AddTabAt(browser, GURL(), -1, true);
140   return browser;
141 }
142 
CreateEmptyBrowserForApp(Profile * profile)143 Browser* BrowserNavigatorTest::CreateEmptyBrowserForApp(Profile* profile) {
144   Browser* browser = Browser::Create(Browser::CreateParams::CreateForApp(
145       "Test", false /* trusted_source */, gfx::Rect(), profile, true));
146   chrome::AddTabAt(browser, GURL(), -1, true);
147   return browser;
148 }
149 
CreateWebContents(bool initialize_renderer)150 std::unique_ptr<WebContents> BrowserNavigatorTest::CreateWebContents(
151     bool initialize_renderer) {
152   WebContents::CreateParams create_params(browser()->profile());
153   create_params.desired_renderer_state =
154       initialize_renderer
155           ? WebContents::CreateParams::kInitializeAndWarmupRendererProcess
156           : WebContents::CreateParams::kOkayToHaveRendererProcess;
157   return WebContents::Create(create_params);
158 }
159 
RunSuppressTest(WindowOpenDisposition disposition)160 void BrowserNavigatorTest::RunSuppressTest(WindowOpenDisposition disposition) {
161   GURL old_url = browser()->tab_strip_model()->GetActiveWebContents()->GetURL();
162   NavigateParams params(MakeNavigateParams());
163   params.disposition = disposition;
164   Navigate(&params);
165 
166   // Nothing should have happened as a result of Navigate();
167   EXPECT_EQ(1, browser()->tab_strip_model()->count());
168   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
169   EXPECT_EQ(old_url,
170             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
171 }
172 
RunUseNonIncognitoWindowTest(const GURL & url,const ui::PageTransition & page_transition)173 void BrowserNavigatorTest::RunUseNonIncognitoWindowTest(
174     const GURL& url,
175     const ui::PageTransition& page_transition) {
176   Browser* incognito_browser = CreateIncognitoBrowser();
177 
178   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
179   EXPECT_EQ(1, browser()->tab_strip_model()->count());
180   EXPECT_EQ(1, incognito_browser->tab_strip_model()->count());
181 
182   // Navigate to the page.
183   NavigateParams params(MakeNavigateParams(incognito_browser));
184   params.disposition = WindowOpenDisposition::SINGLETON_TAB;
185   params.url = url;
186   params.window_action = NavigateParams::SHOW_WINDOW;
187   params.transition = page_transition;
188   Navigate(&params);
189 
190   // This page should be opened in browser() window.
191   EXPECT_NE(incognito_browser, params.browser);
192   EXPECT_EQ(browser(), params.browser);
193   EXPECT_EQ(2, browser()->tab_strip_model()->count());
194   EXPECT_EQ(url,
195             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
196 }
197 
RunDoNothingIfIncognitoIsForcedTest(const GURL & url)198 void BrowserNavigatorTest::RunDoNothingIfIncognitoIsForcedTest(
199     const GURL& url) {
200   Browser* browser = CreateIncognitoBrowser();
201 
202   // Set kIncognitoModeAvailability to FORCED.
203   PrefService* prefs1 = browser->profile()->GetPrefs();
204   prefs1->SetInteger(prefs::kIncognitoModeAvailability,
205                      IncognitoModePrefs::FORCED);
206   PrefService* prefs2 = browser->profile()->GetOriginalProfile()->GetPrefs();
207   prefs2->SetInteger(prefs::kIncognitoModeAvailability,
208                      IncognitoModePrefs::FORCED);
209 
210   // Navigate to the page.
211   NavigateParams params(MakeNavigateParams(browser));
212   params.disposition = WindowOpenDisposition::OFF_THE_RECORD;
213   params.url = url;
214   params.window_action = NavigateParams::SHOW_WINDOW;
215   Navigate(&params);
216 
217   // The page should not be opened.
218   EXPECT_EQ(browser, params.browser);
219   EXPECT_EQ(1, browser->tab_strip_model()->count());
220   EXPECT_EQ(GURL(url::kAboutBlankURL),
221             browser->tab_strip_model()->GetActiveWebContents()->GetURL());
222 }
223 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)224 void BrowserNavigatorTest::Observe(
225     int type,
226     const content::NotificationSource& source,
227     const content::NotificationDetails& details) {
228   DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED, type);
229   ++created_tab_contents_count_;
230 }
231 
232 // Subclass of TestNavigationObserver that saves ChromeNavigationUIData.
233 class TestNavigationUIDataObserver : public content::TestNavigationObserver {
234  public:
235   // Creates an observer that watches navigations to |target_url| on
236   // existing and newly added WebContents.
TestNavigationUIDataObserver(const GURL & target_url)237   explicit TestNavigationUIDataObserver(const GURL& target_url)
238       : content::TestNavigationObserver(target_url) {
239     WatchExistingWebContents();
240     StartWatchingNewWebContents();
241   }
242 
last_navigation_ui_data() const243   const ChromeNavigationUIData* last_navigation_ui_data() const {
244     return static_cast<ChromeNavigationUIData*>(last_navigation_ui_data_.get());
245   }
246 
247  private:
OnDidFinishNavigation(content::NavigationHandle * navigation_handle)248   void OnDidFinishNavigation(
249       content::NavigationHandle* navigation_handle) override {
250     last_navigation_ui_data_ =
251         navigation_handle->GetNavigationUIData()->Clone();
252     content::TestNavigationObserver::OnDidFinishNavigation(navigation_handle);
253   }
254 
255   std::unique_ptr<content::NavigationUIData> last_navigation_ui_data_ = nullptr;
256 };
257 
NavigateHelper(const GURL & url,Browser * browser,WindowOpenDisposition disposition,bool wait_for_navigation)258 Browser* BrowserNavigatorTest::NavigateHelper(const GURL& url,
259                                               Browser* browser,
260                                               WindowOpenDisposition disposition,
261                                               bool wait_for_navigation) {
262   content::WindowedNotificationObserver observer(
263       content::NOTIFICATION_LOAD_STOP,
264       content::NotificationService::AllSources());
265 
266   NavigateParams params(MakeNavigateParams(browser));
267   params.disposition = disposition;
268   params.url = url;
269   params.window_action = NavigateParams::SHOW_WINDOW;
270   Navigate(&params);
271 
272   if (wait_for_navigation)
273     observer.Wait();
274 
275   return params.browser;
276 }
277 
278 namespace {
279 
280 // This test verifies that when a navigation occurs within a tab, the tab count
281 // of the Browser remains the same and the current tab bears the loaded URL.
282 // Note that network URLs are not actually loaded in tests, so this also tests
283 // that error pages leave the intended URL in the address bar.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_CurrentTab)284 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_CurrentTab) {
285   ui_test_utils::NavigateToURL(browser(), GetGoogleURL());
286   EXPECT_EQ(GetGoogleURL(),
287             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
288   // We should have one window with one tab.
289   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
290   EXPECT_EQ(1, browser()->tab_strip_model()->count());
291 }
292 
293 // This test verifies that a singleton tab is refocused if one is already opened
294 // in another or an existing window, or added if it is not.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_SingletonTabExisting)295 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_SingletonTabExisting) {
296   const GURL singleton_url1("http://maps.google.com/");
297 
298   // Register for a notification if an additional WebContents was instantiated.
299   // Opening a Singleton tab that is already opened should not be opening a new
300   // tab nor be creating a new WebContents object.
301   content::NotificationRegistrar registrar;
302 
303   // As the registrar object goes out of scope, this will get unregistered
304   registrar.Add(this,
305                 content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
306                 content::NotificationService::AllSources());
307 
308   chrome::AddSelectedTabWithURL(browser(), singleton_url1,
309                                 ui::PAGE_TRANSITION_LINK);
310   chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
311                                 ui::PAGE_TRANSITION_LINK);
312 
313   // We should have one browser with 3 tabs, the 3rd selected.
314   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
315   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
316 
317   unsigned int previous_tab_contents_count = created_tab_contents_count_ = 0;
318 
319   // Navigate to singleton_url1.
320   NavigateParams params(MakeNavigateParams());
321   params.disposition = WindowOpenDisposition::SINGLETON_TAB;
322   params.url = singleton_url1;
323   Navigate(&params);
324 
325   // The middle tab should now be selected.
326   EXPECT_EQ(browser(), params.browser);
327   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
328 
329   // No tab contents should have been created
330   EXPECT_EQ(previous_tab_contents_count, created_tab_contents_count_);
331 }
332 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_SingletonTabNoneExisting)333 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
334                        Disposition_SingletonTabNoneExisting) {
335   const GURL singleton_url1("http://maps.google.com/");
336 
337   // We should have one browser with 1 tab.
338   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
339   EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
340 
341   // Navigate to singleton_url1.
342   NavigateParams params(MakeNavigateParams());
343   params.disposition = WindowOpenDisposition::SINGLETON_TAB;
344   params.url = singleton_url1;
345   Navigate(&params);
346 
347   // We should now have 2 tabs, the 2nd one selected.
348   EXPECT_EQ(browser(), params.browser);
349   EXPECT_EQ(2, browser()->tab_strip_model()->count());
350   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
351 }
352 
353 // This test verifies that when a navigation results in a foreground tab, the
354 // tab count of the Browser increases and the selected tab shifts to the new
355 // foreground tab.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewForegroundTab)356 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewForegroundTab) {
357   WebContents* old_contents =
358       browser()->tab_strip_model()->GetActiveWebContents();
359   NavigateParams params(MakeNavigateParams());
360   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
361   Navigate(&params);
362   EXPECT_NE(old_contents, browser()->tab_strip_model()->GetActiveWebContents());
363   EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
364             params.navigated_or_inserted_contents);
365   EXPECT_EQ(2, browser()->tab_strip_model()->count());
366 }
367 
368 // This test verifies that when a navigation results in a background tab, the
369 // tab count of the Browser increases but the selected tab remains the same.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewBackgroundTab)370 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewBackgroundTab) {
371   WebContents* old_contents =
372       browser()->tab_strip_model()->GetActiveWebContents();
373   NavigateParams params(MakeNavigateParams());
374   params.disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB;
375   Navigate(&params);
376   WebContents* new_contents =
377       browser()->tab_strip_model()->GetActiveWebContents();
378   // The selected tab should have remained unchanged, since the new tab was
379   // opened in the background.
380   EXPECT_EQ(old_contents, new_contents);
381   EXPECT_EQ(2, browser()->tab_strip_model()->count());
382 }
383 
384 // This test verifies that when a navigation requiring a new foreground tab
385 // occurs in a Browser that cannot host multiple tabs, the new foreground tab
386 // is created in an existing compatible Browser.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_IncompatibleWindow_Existing)387 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
388                        Disposition_IncompatibleWindow_Existing) {
389   // Open a foreground tab in a window that cannot open popups when there is an
390   // existing compatible window somewhere else that they can be opened within.
391   Browser* popup =
392       CreateEmptyBrowserForType(Browser::TYPE_POPUP, browser()->profile());
393   NavigateParams params(MakeNavigateParams(popup));
394   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
395   Navigate(&params);
396 
397   // Navigate() should have opened the tab in a different browser since the
398   // one we supplied didn't support additional tabs.
399   EXPECT_NE(popup, params.browser);
400 
401   // Since browser() is an existing compatible tabbed browser, it should have
402   // opened the tab there.
403   EXPECT_EQ(browser(), params.browser);
404 
405   // We should be left with 2 windows, the popup with one tab and the browser()
406   // provided by the framework with two.
407   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
408   EXPECT_EQ(1, popup->tab_strip_model()->count());
409   EXPECT_EQ(2, browser()->tab_strip_model()->count());
410 }
411 
412 // This test verifies that when a navigation requiring a new foreground tab
413 // occurs in a Browser that cannot host multiple tabs and no compatible Browser
414 // that can is open, a compatible Browser is created.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_IncompatibleWindow_NoExisting)415 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
416                        Disposition_IncompatibleWindow_NoExisting) {
417   // We want to simulate not being able to find an existing window compatible
418   // with our non-tabbed browser window so Navigate() is forced to create a
419   // new compatible window. Because browser() supplied by the in-process
420   // browser testing framework is compatible with browser()->profile(), we
421   // need a different profile, and creating a popup window with an incognito
422   // profile is a quick and dirty way of achieving this.
423   Browser* popup = CreateEmptyBrowserForType(
424       Browser::TYPE_POPUP, browser()->profile()->GetPrimaryOTRProfile());
425   NavigateParams params(MakeNavigateParams(popup));
426   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
427   Navigate(&params);
428 
429   // Navigate() should have opened the tab in a different browser since the
430   // one we supplied didn't support additional tabs.
431   EXPECT_NE(popup, params.browser);
432 
433   // This time, browser() is _not_ compatible with popup since it is not an
434   // incognito window.
435   EXPECT_NE(browser(), params.browser);
436 
437   // We should have three windows, each with one tab:
438   // 1. the browser() provided by the framework (unchanged in this test)
439   // 2. the incognito popup we created originally
440   // 3. the new incognito tabbed browser that was created by Navigate().
441   EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
442   EXPECT_EQ(1, browser()->tab_strip_model()->count());
443   EXPECT_EQ(1, popup->tab_strip_model()->count());
444   EXPECT_EQ(1, params.browser->tab_strip_model()->count());
445   EXPECT_TRUE(params.browser->is_type_normal());
446   EXPECT_TRUE(params.browser->window()->IsToolbarVisible());
447 }
448 
449 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
450 // from a normal Browser results in a new Browser with TYPE_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewPopup)451 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopup) {
452   NavigateParams params(MakeNavigateParams());
453   params.disposition = WindowOpenDisposition::NEW_POPUP;
454   params.window_bounds = gfx::Rect(0, 0, 200, 200);
455   // Wait for new popup to to load and gain focus.
456   ui_test_utils::NavigateToURL(&params);
457 
458   // Navigate() should have opened a new, focused popup window, with a toolbar.
459   EXPECT_NE(browser(), params.browser);
460 #if 0
461   // TODO(stevenjb): Enable this test. See: crbug.com/79493
462   EXPECT_TRUE(browser->window()->IsActive());
463 #endif
464   EXPECT_TRUE(params.browser->is_type_popup());
465   EXPECT_TRUE(params.browser->window()->IsToolbarVisible());
466 
467   // We should have two windows, the browser() provided by the framework and the
468   // new popup window.
469   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
470   EXPECT_EQ(1, browser()->tab_strip_model()->count());
471   EXPECT_EQ(1, params.browser->tab_strip_model()->count());
472 }
473 
474 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
475 // from a (kind of app) Browser results in a new Browser with TYPE_APP_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewPopup_ExtensionId)476 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopup_ExtensionId) {
477   NavigateParams params(MakeNavigateParams());
478   params.disposition = WindowOpenDisposition::NEW_POPUP;
479   params.extension_app_id = "extensionappid";
480   params.window_bounds = gfx::Rect(0, 0, 200, 200);
481   // Wait for new popup to to load and gain focus.
482   ui_test_utils::NavigateToURL(&params);
483 
484   // Navigate() should have opened a new, focused TYPE_APP_POPUP window with no
485   // toolbar.
486   EXPECT_NE(browser(), params.browser);
487   EXPECT_TRUE(params.browser->is_type_app_popup());
488   EXPECT_FALSE(params.browser->window()->IsToolbarVisible());
489 
490   // We should have two windows, the browser() provided by the framework and the
491   // new popup window.
492   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
493   EXPECT_EQ(1, browser()->tab_strip_model()->count());
494   EXPECT_EQ(1, params.browser->tab_strip_model()->count());
495 }
496 
497 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
498 // from a normal popup results in a new Browser with TYPE_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewPopupFromPopup)499 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupFromPopup) {
500   // Open a popup.
501   NavigateParams params1(MakeNavigateParams());
502   params1.disposition = WindowOpenDisposition::NEW_POPUP;
503   params1.window_bounds = gfx::Rect(0, 0, 200, 200);
504   Navigate(&params1);
505   // Open another popup.
506   NavigateParams params2(MakeNavigateParams(params1.browser));
507   params2.disposition = WindowOpenDisposition::NEW_POPUP;
508   params2.window_bounds = gfx::Rect(0, 0, 200, 200);
509   Navigate(&params2);
510 
511   // Navigate() should have opened a new normal popup window.
512   EXPECT_NE(params1.browser, params2.browser);
513   EXPECT_TRUE(params2.browser->is_type_popup());
514   EXPECT_TRUE(params2.browser->window()->IsToolbarVisible());
515 
516   // We should have three windows, the browser() provided by the framework,
517   // the first popup window, and the second popup window.
518   EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
519   EXPECT_EQ(1, browser()->tab_strip_model()->count());
520   EXPECT_EQ(1, params1.browser->tab_strip_model()->count());
521   EXPECT_EQ(1, params2.browser->tab_strip_model()->count());
522 }
523 
524 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
525 // from an app frame results in a new Browser with TYPE_APP_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewPopupFromAppWindow)526 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
527                        Disposition_NewPopupFromAppWindow) {
528   Browser* app_browser = CreateEmptyBrowserForApp(browser()->profile());
529   NavigateParams params(MakeNavigateParams(app_browser));
530   params.disposition = WindowOpenDisposition::NEW_POPUP;
531   params.window_bounds = gfx::Rect(0, 0, 200, 200);
532   Navigate(&params);
533 
534   // Navigate() should have opened a new TYPE_APP_POPUP window with no toolbar.
535   EXPECT_NE(app_browser, params.browser);
536   EXPECT_NE(browser(), params.browser);
537   EXPECT_TRUE(params.browser->is_type_app_popup());
538   EXPECT_FALSE(params.browser->window()->IsToolbarVisible());
539 
540   // We should now have three windows, the app window, the app popup it created,
541   // and the original browser() provided by the framework.
542   EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
543   EXPECT_EQ(1, browser()->tab_strip_model()->count());
544   EXPECT_EQ(1, app_browser->tab_strip_model()->count());
545   EXPECT_EQ(1, params.browser->tab_strip_model()->count());
546 }
547 
548 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
549 // from an app popup results in a new Browser also of TYPE_APP_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewPopupFromAppPopup)550 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupFromAppPopup) {
551   Browser* app_browser = CreateEmptyBrowserForApp(browser()->profile());
552   // Open an app popup.
553   NavigateParams params1(MakeNavigateParams(app_browser));
554   params1.disposition = WindowOpenDisposition::NEW_POPUP;
555   params1.window_bounds = gfx::Rect(0, 0, 200, 200);
556   Navigate(&params1);
557   // Now open another app popup.
558   NavigateParams params2(MakeNavigateParams(params1.browser));
559   params2.disposition = WindowOpenDisposition::NEW_POPUP;
560   params2.window_bounds = gfx::Rect(0, 0, 200, 200);
561   Navigate(&params2);
562 
563   // Navigate() should have opened a new popup app window.
564   EXPECT_NE(browser(), params1.browser);
565   EXPECT_NE(params1.browser, params2.browser);
566   EXPECT_TRUE(params2.browser->is_type_app_popup());
567   EXPECT_FALSE(params2.browser->window()->IsToolbarVisible());
568 
569   // We should now have four windows, the app window, the first app popup,
570   // the second app popup, and the original browser() provided by the framework.
571   EXPECT_EQ(4u, chrome::GetTotalBrowserCount());
572   EXPECT_EQ(1, browser()->tab_strip_model()->count());
573   EXPECT_EQ(1, app_browser->tab_strip_model()->count());
574   EXPECT_EQ(1, params1.browser->tab_strip_model()->count());
575   EXPECT_EQ(1, params2.browser->tab_strip_model()->count());
576 }
577 
578 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
579 // from an extension app tab results in a new Browser with TYPE_APP_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewPopupFromExtensionApp)580 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
581                        Disposition_NewPopupFromExtensionApp) {
582   // TODO(beng): TBD.
583 }
584 
585 // This test verifies that navigating with window_action = SHOW_WINDOW_INACTIVE
586 // does not focus a new new popup window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewPopupUnfocused)587 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupUnfocused) {
588   NavigateParams params(MakeNavigateParams());
589   params.disposition = WindowOpenDisposition::NEW_POPUP;
590   params.window_bounds = gfx::Rect(0, 0, 200, 200);
591   params.window_action = NavigateParams::SHOW_WINDOW_INACTIVE;
592   // Wait for new popup to load (and gain focus if the test fails).
593   ui_test_utils::NavigateToURL(&params);
594 
595   // Navigate() should have opened a new, unfocused, popup window.
596   EXPECT_NE(browser(), params.browser);
597   EXPECT_TRUE(params.browser->is_type_popup());
598   EXPECT_TRUE(params.browser->window()->IsToolbarVisible());
599 #if 0
600 // TODO(stevenjb): Enable this test. See: crbug.com/79493
601   EXPECT_FALSE(p.browser->window()->IsActive());
602 #endif
603 }
604 
605 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
606 // and trusted_source = true results in a new Browser where is_trusted_source()
607 // is true.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewPopupTrusted)608 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupTrusted) {
609   NavigateParams params(MakeNavigateParams());
610   params.disposition = WindowOpenDisposition::NEW_POPUP;
611   params.trusted_source = true;
612   params.window_bounds = gfx::Rect(0, 0, 200, 200);
613   // Wait for new popup to to load and gain focus.
614   ui_test_utils::NavigateToURL(&params);
615 
616   // Navigate() should have opened a new popup window of TYPE_POPUP with no
617   // toolbar.
618   EXPECT_NE(browser(), params.browser);
619   EXPECT_TRUE(params.browser->is_type_popup());
620   EXPECT_TRUE(params.browser->is_trusted_source());
621   EXPECT_FALSE(params.browser->window()->IsToolbarVisible());
622 }
623 
624 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
625 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
626 // and is_captive_portal_popup = true results in a new WebContents where
627 // is_captive_portal_window() is true.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewPopupCaptivePortal)628 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
629                        Disposition_NewPopupCaptivePortal) {
630   NavigateParams params(MakeNavigateParams());
631   params.disposition = WindowOpenDisposition::NEW_POPUP;
632   params.is_captive_portal_popup = true;
633   params.window_bounds = gfx::Rect(0, 0, 200, 200);
634   // Wait for new popup to to load and gain focus.
635   ui_test_utils::NavigateToURL(&params);
636 
637   // Navigate() should have opened a new popup window of TYPE_POPUP with a
638   // toolbar.
639   EXPECT_NE(browser(), params.browser);
640   EXPECT_TRUE(params.browser->is_type_popup());
641   EXPECT_TRUE(params.browser->window()->IsToolbarVisible());
642   EXPECT_TRUE(captive_portal::CaptivePortalTabHelper::FromWebContents(
643                   params.navigated_or_inserted_contents)
644                   ->is_captive_portal_window());
645 }
646 #endif
647 
648 // This test verifies that navigating with WindowOpenDisposition = NEW_WINDOW
649 // always opens a new window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_NewWindow)650 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewWindow) {
651   NavigateParams params(MakeNavigateParams());
652   params.disposition = WindowOpenDisposition::NEW_WINDOW;
653   Navigate(&params);
654 
655   // Navigate() should have opened a new toplevel window.
656   EXPECT_NE(browser(), params.browser);
657   EXPECT_TRUE(params.browser->is_type_normal());
658   EXPECT_TRUE(params.browser->window()->IsToolbarVisible());
659 
660   // We should now have two windows, the browser() provided by the framework and
661   // the new normal window.
662   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
663   EXPECT_EQ(1, browser()->tab_strip_model()->count());
664   EXPECT_EQ(1, params.browser->tab_strip_model()->count());
665 }
666 
667 // This test verifies that a source tab to the left of the target tab can
668 // be switched away from and closed. It verifies that if we close the
669 // earlier tab, that we don't use a stale index, and select the wrong tab.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,OutOfOrderTabSwitchTest)670 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, OutOfOrderTabSwitchTest) {
671   const GURL singleton_url("http://maps.google.com/");
672 
673   NavigateHelper(singleton_url, browser(),
674                  WindowOpenDisposition::NEW_FOREGROUND_TAB, true);
675 
676   browser()->tab_strip_model()->ActivateTabAt(
677       0, {TabStripModel::GestureType::kOther});
678 
679   NavigateHelper(singleton_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
680                  false);
681 }
682 
683 // This test verifies the two cases of attempting to switch to a tab that no
684 // longer exists: if NTP, load in current tab, otherwise load in new
685 // foreground tab.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateOnTabSwitchLostTest)686 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, NavigateOnTabSwitchLostTest) {
687   const GURL singleton_url("chrome://dino");
688 
689   NavigateHelper(singleton_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
690                  true);
691   EXPECT_EQ(1, browser()->tab_strip_model()->count());
692 
693   NavigateHelper(GURL("chrome://about"), browser(),
694                  WindowOpenDisposition::NEW_FOREGROUND_TAB, true);
695   browser()->tab_strip_model()->CloseWebContentsAt(0,
696                                                    TabStripModel::CLOSE_NONE);
697   NavigateHelper(singleton_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
698                  true);
699   EXPECT_EQ(2, browser()->tab_strip_model()->count());
700 }
701 
702 // This test verifies that IsTabOpenWithURL() and GetIndexOfExistingTab()
703 // will not discriminate between http and https.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SchemeMismatchTabSwitchTest)704 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SchemeMismatchTabSwitchTest) {
705   GURL navigate_url("https://maps.google.com/");
706   GURL search_url("http://maps.google.com/");
707 
708   // Generate history so the tab isn't closed.
709   NavigateHelper(GURL("chrome://dino/"), browser(),
710                  WindowOpenDisposition::CURRENT_TAB, true);
711 
712   NavigateHelper(navigate_url, browser(),
713                  WindowOpenDisposition::NEW_BACKGROUND_TAB, true);
714 
715   // We must be on another tab than the target for it to be found and
716   // switched to.
717   EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
718 
719   ChromeAutocompleteProviderClient client(browser()->profile());
720   EXPECT_TRUE(client.IsTabOpenWithURL(search_url, nullptr));
721 
722   NavigateHelper(search_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
723                  false);
724 
725   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
726 }
727 
728 // Make sure that switching tabs preserves the post-focus state (of the
729 // content area) of the previous tab.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SaveAfterFocusTabSwitchTest)730 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SaveAfterFocusTabSwitchTest) {
731   GURL first_url("chrome://dino/");
732   GURL second_url("chrome://history/");
733 
734   NavigateHelper(first_url, browser(), WindowOpenDisposition::CURRENT_TAB,
735                  true);
736 
737   // Generate history so the tab isn't closed.
738   NavigateHelper(second_url, browser(),
739                  WindowOpenDisposition::NEW_FOREGROUND_TAB, true);
740 
741   LocationBar* location_bar = browser()->window()->GetLocationBar();
742   location_bar->FocusLocation(true);
743 
744   NavigateHelper(first_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
745                  false);
746 
747   browser()->tab_strip_model()->ActivateTabAt(
748       1, {TabStripModel::GestureType::kOther});
749 
750   OmniboxView* omnibox_view = location_bar->GetOmniboxView();
751   EXPECT_EQ(omnibox_view->model()->focus_state(),
752             OmniboxFocusState::OMNIBOX_FOCUS_NONE);
753 }
754 
755 // This test verifies that we're picking the correct browser and tab to
756 // switch to. It verifies that we don't recommend the active tab, and that,
757 // when switching, we don't mistakenly pick the current browser.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SwitchToTabCorrectWindow)758 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SwitchToTabCorrectWindow) {
759   const GURL singleton_url("http://maps.google.com/");
760 
761   // Make singleton tab.
762   Browser* orig_browser = NavigateHelper(
763       singleton_url, browser(), WindowOpenDisposition::CURRENT_TAB, true);
764 
765   // Make a new window with different URL.
766   Browser* middle_browser =
767       NavigateHelper(GURL("http://www.google.com/"), orig_browser,
768                      WindowOpenDisposition::NEW_WINDOW, true);
769   EXPECT_NE(orig_browser, middle_browser);
770 
771   ChromeAutocompleteProviderClient client(browser()->profile());
772   // We avoid recommending the active tab, because during navigation, we
773   // actively avoid it (because the user almost certainly doesn't want to
774   // switch to the tab they're already on). While we are not on the target
775   // tab, make sure the provider client recommends our other window.
776   EXPECT_TRUE(client.IsTabOpenWithURL(singleton_url, nullptr));
777 
778   // Navigate to the singleton again.
779   Browser* test_browser =
780       NavigateHelper(singleton_url, middle_browser,
781                      WindowOpenDisposition::SWITCH_TO_TAB, false);
782 
783   // Make sure we chose the browser with the tab, not simply the current
784   // browser.
785   EXPECT_EQ(orig_browser, test_browser);
786   // Now that we're on the tab, make sure the provider client doesn't
787   // recommend it.
788   EXPECT_FALSE(client.IsTabOpenWithURL(singleton_url, nullptr));
789 }
790 
791 // This test verifies that "switch to tab" prefers the latest used browser,
792 // if multiple exist.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SwitchToTabLatestWindow)793 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SwitchToTabLatestWindow) {
794   // Navigate to a site.
795   NavigateHelper(GURL("http://maps.google.com/"), browser(),
796                  WindowOpenDisposition::CURRENT_TAB, true);
797 
798   // Navigate to a new window.
799   Browser* browser1 = NavigateHelper(GURL("http://maps.google.com/"), browser(),
800                                      WindowOpenDisposition::NEW_WINDOW, true);
801 
802   // Make yet another window.
803   Browser* browser2 = NavigateHelper(GURL("http://maps.google.com/"), browser(),
804                                      WindowOpenDisposition::NEW_WINDOW, true);
805 
806   // Navigate to the latest copy of the URL, in spite of specifying
807   // the previous browser.
808   Browser* test_browser =
809       NavigateHelper(GURL("http://maps.google.com/"), browser1,
810                      WindowOpenDisposition::SWITCH_TO_TAB, false);
811 
812   EXPECT_EQ(browser2, test_browser);
813 }
814 
815 // Tests that a disposition of SINGLETON_TAB cannot see outside its
816 // window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SingletonWindowLeak)817 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SingletonWindowLeak) {
818   Browser* browser1;
819 
820   // Navigate to a site.
821   browser1 = NavigateHelper(GURL("chrome://dino"), browser(),
822                             WindowOpenDisposition::CURRENT_TAB, true);
823 
824   // Navigate to a new window.
825   Browser* browser2 = NavigateHelper(GURL("chrome://about"), browser(),
826                                      WindowOpenDisposition::NEW_WINDOW, true);
827 
828   // Make sure we open non-special URL here.
829   Browser* test_browser =
830       NavigateHelper(GURL("chrome://dino"), browser2,
831                      WindowOpenDisposition::NEW_FOREGROUND_TAB, true);
832   EXPECT_EQ(browser2, test_browser);
833 }
834 
835 // Tests that a disposition of SINGLETON_TAB cannot see across anonymity,
836 // except for certain non-incognito affinity URLs (e.g. settings).
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SingletonIncognitoLeak)837 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SingletonIncognitoLeak) {
838   Browser* orig_browser;
839 
840   // Navigate to a site.
841   orig_browser = NavigateHelper(GURL(chrome::kChromeUIVersionURL), browser(),
842                                 WindowOpenDisposition::CURRENT_TAB, true);
843 
844   // Open about for (not) finding later.
845   NavigateHelper(GURL(chrome::kChromeUIAboutURL), orig_browser,
846                  WindowOpenDisposition::NEW_FOREGROUND_TAB, true);
847 
848   // Also open settings for finding later.
849   NavigateHelper(GURL(chrome::kChromeUISettingsURL), orig_browser,
850                  WindowOpenDisposition::NEW_FOREGROUND_TAB, false);
851 
852   EXPECT_EQ(3, browser()->tab_strip_model()->count());
853 
854   Browser* test_browser;
855 
856   {
857     Browser* incognito_browser = CreateIncognitoBrowser();
858 
859     test_browser =
860         NavigateHelper(GURL(chrome::kChromeUIDownloadsURL), incognito_browser,
861                        WindowOpenDisposition::OFF_THE_RECORD, true);
862     // Sanity check where OTR tab landed.
863     EXPECT_EQ(incognito_browser, test_browser);
864 
865     // Sanity check that browser() always returns original.
866     EXPECT_EQ(orig_browser, browser());
867 
868     // Open about singleton. Should not find in regular browser and
869     // open locally.
870     test_browser =
871         NavigateHelper(GURL(chrome::kChromeUIAboutURL), incognito_browser,
872                        WindowOpenDisposition::SINGLETON_TAB, true);
873     EXPECT_NE(orig_browser, test_browser);
874 
875     // Open settings. Should switch to non-incognito profile to do so.
876     test_browser =
877         NavigateHelper(GURL(chrome::kChromeUISettingsURL), incognito_browser,
878                        WindowOpenDisposition::SINGLETON_TAB, false);
879     EXPECT_EQ(orig_browser, test_browser);
880   }
881 
882   // Open downloads singleton. Should not search OTR browser and
883   // should open in regular browser.
884   test_browser =
885       NavigateHelper(GURL(chrome::kChromeUIDownloadsURL), orig_browser,
886                      WindowOpenDisposition::SINGLETON_TAB, true);
887   EXPECT_EQ(browser(), test_browser);
888 }
889 
890 // Tests that a disposition of SWITCH_TAB cannot see across anonymity,
891 // except for certain non-incognito affinity URLs (e.g. settings).
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SwitchToTabIncognitoLeak)892 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SwitchToTabIncognitoLeak) {
893   Browser* orig_browser;
894 
895   // Navigate to a site.
896   orig_browser = NavigateHelper(GURL(chrome::kChromeUIVersionURL), browser(),
897                                 WindowOpenDisposition::CURRENT_TAB, true);
898 
899   // Also open settings for finding later.
900   NavigateHelper(GURL(chrome::kChromeUISettingsURL), orig_browser,
901                  WindowOpenDisposition::NEW_FOREGROUND_TAB, false);
902 
903   // Also open about for searching too.
904   NavigateHelper(GURL(chrome::kChromeUIAboutURL), orig_browser,
905                  WindowOpenDisposition::NEW_FOREGROUND_TAB, true);
906 
907   EXPECT_EQ(3, browser()->tab_strip_model()->count());
908 
909   Browser* test_browser;
910 
911   {
912     Browser* incognito_browser = CreateIncognitoBrowser();
913 
914     test_browser =
915         NavigateHelper(GURL(chrome::kChromeUIDownloadsURL), incognito_browser,
916                        WindowOpenDisposition::OFF_THE_RECORD, true);
917     // Sanity check where OTR tab landed.
918     EXPECT_EQ(incognito_browser, test_browser);
919 
920     // Sanity check that browser() always returns original.
921     EXPECT_EQ(orig_browser, browser());
922 
923     // Try to open the original chrome://about via switch-to-tab. Should not
924     // find copy in regular browser, and open new tab in incognito.
925     test_browser =
926         NavigateHelper(GURL(chrome::kChromeUIAboutURL), incognito_browser,
927                        WindowOpenDisposition::SWITCH_TO_TAB, true);
928     EXPECT_EQ(incognito_browser, test_browser);
929 
930     // Open settings. Should switch to non-incognito profile to do so.
931     test_browser =
932         NavigateHelper(GURL(chrome::kChromeUISettingsURL), incognito_browser,
933                        WindowOpenDisposition::SWITCH_TO_TAB, false);
934     EXPECT_EQ(orig_browser, test_browser);
935   }
936 
937   // Switch-to-tab shouldn't find the incognito tab, and open new one in
938   // current browser.
939   test_browser =
940       NavigateHelper(GURL(chrome::kChromeUIDownloadsURL), orig_browser,
941                      WindowOpenDisposition::SWITCH_TO_TAB, true);
942   EXPECT_EQ(browser(), test_browser);
943 }
944 
945 #if defined(OS_MAC) && defined(ADDRESS_SANITIZER)
946 // Flaky on ASAN on Mac. See https://crbug.com/674497.
947 #define MAYBE_Disposition_Incognito DISABLED_Disposition_Incognito
948 #else
949 #define MAYBE_Disposition_Incognito Disposition_Incognito
950 #endif
951 // This test verifies that navigating with WindowOpenDisposition = INCOGNITO
952 // opens a new incognito window if no existing incognito window is present.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,MAYBE_Disposition_Incognito)953 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, MAYBE_Disposition_Incognito) {
954   NavigateParams params(MakeNavigateParams());
955   params.disposition = WindowOpenDisposition::OFF_THE_RECORD;
956   Navigate(&params);
957 
958   // Navigate() should have opened a new toplevel incognito window.
959   EXPECT_NE(browser(), params.browser);
960   EXPECT_EQ(browser()->profile()->GetPrimaryOTRProfile(),
961             params.browser->profile());
962 
963   // |source_contents| should be set to NULL because the profile for the new
964   // page is different from the originating page.
965   EXPECT_FALSE(params.source_contents);
966 
967   // We should now have two windows, the browser() provided by the framework and
968   // the new incognito window.
969   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
970   EXPECT_EQ(1, browser()->tab_strip_model()->count());
971   EXPECT_EQ(1, params.browser->tab_strip_model()->count());
972 }
973 
974 // This test verifies that navigating with WindowOpenDisposition = INCOGNITO
975 // reuses an existing incognito window when possible.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_IncognitoRefocus)976 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_IncognitoRefocus) {
977   Browser* incognito_browser = CreateEmptyBrowserForType(
978       Browser::TYPE_NORMAL, browser()->profile()->GetPrimaryOTRProfile());
979   NavigateParams params(MakeNavigateParams());
980   params.disposition = WindowOpenDisposition::OFF_THE_RECORD;
981   Navigate(&params);
982 
983   // Navigate() should have opened a new tab in the existing incognito window.
984   EXPECT_NE(browser(), params.browser);
985   EXPECT_EQ(params.browser, incognito_browser);
986 
987   // We should now have two windows, the browser() provided by the framework and
988   // the incognito window we opened earlier.
989   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
990   EXPECT_EQ(1, browser()->tab_strip_model()->count());
991   EXPECT_EQ(2, incognito_browser->tab_strip_model()->count());
992 }
993 
994 // This test verifies that no navigation action occurs when
995 // WindowOpenDisposition = SAVE_TO_DISK.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_SaveToDisk)996 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_SaveToDisk) {
997   RunSuppressTest(WindowOpenDisposition::SAVE_TO_DISK);
998 }
999 
1000 // This test verifies that no navigation action occurs when
1001 // WindowOpenDisposition = IGNORE_ACTION.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_IgnoreAction)1002 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_IgnoreAction) {
1003   RunSuppressTest(WindowOpenDisposition::IGNORE_ACTION);
1004 }
1005 
1006 // This tests adding a foreground tab with a predefined WebContents.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,TargetContents_ForegroundTab)1007 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, TargetContents_ForegroundTab) {
1008   NavigateParams params(MakeNavigateParams());
1009   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
1010   params.contents_to_insert = CreateWebContents(false);
1011   Navigate(&params);
1012 
1013   // Navigate() should have opened the contents in a new foreground tab in the
1014   // current Browser.
1015   EXPECT_EQ(browser(), params.browser);
1016   EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
1017             params.navigated_or_inserted_contents);
1018 
1019   // We should have one window, with two tabs.
1020   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1021   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1022 }
1023 
1024 #if defined(OS_WIN)
1025 // This tests adding a popup with a predefined WebContents.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,DISABLED_TargetContents_Popup)1026 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, DISABLED_TargetContents_Popup) {
1027   NavigateParams params(MakeNavigateParams());
1028   params.disposition = WindowOpenDisposition::NEW_POPUP;
1029   params.contents_to_insert = CreateWebContents(false);
1030   params.window_bounds = gfx::Rect(10, 10, 500, 500);
1031   Navigate(&params);
1032 
1033   // Navigate() should have opened a new popup window.
1034   EXPECT_NE(browser(), params.browser);
1035   EXPECT_TRUE(params.browser->is_type_popup());
1036   EXPECT_TRUE(params.browser->window()->IsToolbarVisible());
1037 
1038   // The web platform is weird. The window bounds specified in
1039   // |params.window_bounds| are used as follows:
1040   // - the origin is used to position the window
1041   // - the size is used to size the WebContents of the window.
1042   // As such the position of the resulting window will always match
1043   // params.window_bounds.origin(), but its size will not. We need to match
1044   // the size against the selected tab's view's container size.
1045   // Only Windows positions the window according to
1046   // |params.window_bounds.origin()| - on Mac the window is offset from the
1047   // opener and on Linux it always opens at 0,0.
1048   EXPECT_EQ(params.window_bounds.origin(),
1049             params.browser->window()->GetRestoredBounds().origin());
1050   // All platforms should respect size however provided width > 400 (Mac has a
1051   // minimum window width of 400).
1052   EXPECT_EQ(params.window_bounds.size(),
1053             params.navigated_or_inserted_contents->GetContainerBounds().size());
1054 
1055   // We should have two windows, the new popup and the browser() provided by the
1056   // framework.
1057   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
1058   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1059   EXPECT_EQ(1, params.browser->tab_strip_model()->count());
1060 }
1061 #endif
1062 
1063 // This test checks that we can create WebContents with renderer process and
1064 // RenderFrame without navigating it.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,CreateWebContentsWithRendererProcess)1065 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1066                        CreateWebContentsWithRendererProcess) {
1067   NavigateParams params(MakeNavigateParams());
1068   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
1069   params.contents_to_insert = CreateWebContents(true);
1070   ASSERT_TRUE(params.contents_to_insert);
1071 
1072   // There is no navigation (to about:blank or something like that).
1073   EXPECT_FALSE(params.contents_to_insert->IsLoading());
1074 
1075   ASSERT_TRUE(params.contents_to_insert->GetMainFrame());
1076   EXPECT_TRUE(params.contents_to_insert->GetMainFrame()->IsRenderFrameLive());
1077   EXPECT_TRUE(
1078       params.contents_to_insert->GetController().IsInitialBlankNavigation());
1079   int renderer_id =
1080       params.contents_to_insert->GetMainFrame()->GetProcess()->GetID();
1081 
1082   // We should have one window, with one tab of WebContents differ from
1083   // params.target_contents.
1084   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1085   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1086   EXPECT_NE(browser()->tab_strip_model()->GetActiveWebContents(),
1087             params.contents_to_insert.get());
1088 
1089   Navigate(&params);
1090 
1091   // Navigate() should have opened the contents in a new foreground tab in the
1092   // current Browser, without changing the renderer process of target_contents.
1093   EXPECT_EQ(browser(), params.browser);
1094   EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
1095             params.navigated_or_inserted_contents);
1096   EXPECT_EQ(renderer_id, params.navigated_or_inserted_contents->GetMainFrame()
1097                              ->GetProcess()
1098                              ->GetID());
1099 
1100   // We should have one window, with two tabs.
1101   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1102   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1103 }
1104 
1105 // This tests adding a tab at a specific index.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Tabstrip_InsertAtIndex)1106 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Tabstrip_InsertAtIndex) {
1107   // This is not meant to be a comprehensive test of whether or not the tab
1108   // implementation of the browser observes the insertion index. That is
1109   // covered by the unit tests for TabStripModel. This merely verifies that
1110   // insertion index preference is reflected in common cases.
1111   NavigateParams params(MakeNavigateParams());
1112   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
1113   params.tabstrip_index = 0;
1114   params.tabstrip_add_types = TabStripModel::ADD_FORCE_INDEX;
1115   Navigate(&params);
1116 
1117   // Navigate() should have inserted a new tab at slot 0 in the tabstrip.
1118   EXPECT_EQ(browser(), params.browser);
1119   EXPECT_EQ(0, browser()->tab_strip_model()->GetIndexOfWebContents(
1120                    static_cast<const WebContents*>(
1121                        params.navigated_or_inserted_contents)));
1122 
1123   // We should have one window - the browser() provided by the framework.
1124   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1125   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1126 }
1127 
1128 // This test verifies that constructing params with disposition = SINGLETON_TAB
1129 // and IGNORE_AND_NAVIGATE opens a new tab navigated to the specified URL if
1130 // no previous tab with that URL (minus the path) exists.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_SingletonTabNew_IgnorePath)1131 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1132                        Disposition_SingletonTabNew_IgnorePath) {
1133   chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
1134                                 ui::PAGE_TRANSITION_LINK);
1135 
1136   // We should have one browser with 2 tabs, the 2nd selected.
1137   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1138   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1139   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
1140 
1141   // Navigate to a new singleton tab with a sub-page.
1142   NavigateParams params(MakeNavigateParams());
1143   params.disposition = WindowOpenDisposition::SINGLETON_TAB;
1144   params.url = GetContentSettingsURL();
1145   params.window_action = NavigateParams::SHOW_WINDOW;
1146   params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
1147   Navigate(&params);
1148 
1149   // The last tab should now be selected and navigated to the sub-page of the
1150   // URL.
1151   EXPECT_EQ(browser(), params.browser);
1152   EXPECT_EQ(3, browser()->tab_strip_model()->count());
1153   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
1154   EXPECT_EQ(GetContentSettingsURL(),
1155             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1156 }
1157 
1158 // This test verifies that constructing params with disposition = SINGLETON_TAB
1159 // and IGNORE_AND_NAVIGATE opens an existing tab with the matching URL (minus
1160 // the path) which is navigated to the specified URL.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_SingletonTabExisting_IgnorePath)1161 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1162                        Disposition_SingletonTabExisting_IgnorePath) {
1163   const GURL singleton_url(GetSettingsURL());
1164   chrome::AddSelectedTabWithURL(browser(), singleton_url,
1165                                 ui::PAGE_TRANSITION_LINK);
1166   chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
1167                                 ui::PAGE_TRANSITION_LINK);
1168 
1169   // We should have one browser with 3 tabs, the 3rd selected.
1170   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1171   EXPECT_EQ(3, browser()->tab_strip_model()->count());
1172   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
1173 
1174   // Navigate to |singleton_url|.
1175   NavigateParams params(MakeNavigateParams());
1176   params.disposition = WindowOpenDisposition::SINGLETON_TAB;
1177   params.url = GetContentSettingsURL();
1178   params.window_action = NavigateParams::SHOW_WINDOW;
1179   params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
1180   Navigate(&params);
1181 
1182   // The middle tab should now be selected and navigated to the sub-page of the
1183   // URL.
1184   EXPECT_EQ(browser(), params.browser);
1185   EXPECT_EQ(3, browser()->tab_strip_model()->count());
1186   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
1187   EXPECT_EQ(GetContentSettingsURL(),
1188             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1189 }
1190 
1191 // This test verifies that constructing params with disposition = SINGLETON_TAB
1192 // and IGNORE_AND_NAVIGATE opens an existing tab with the matching URL (minus
1193 // the path) which is navigated to the specified URL.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_SingletonTabExistingSubPath_IgnorePath)1194 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1195                        Disposition_SingletonTabExistingSubPath_IgnorePath) {
1196   const GURL singleton_url(GetContentSettingsURL());
1197   chrome::AddSelectedTabWithURL(browser(), singleton_url,
1198                                 ui::PAGE_TRANSITION_LINK);
1199   chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
1200                                 ui::PAGE_TRANSITION_LINK);
1201 
1202   // We should have one browser with 3 tabs, the 3rd selected.
1203   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1204   EXPECT_EQ(3, browser()->tab_strip_model()->count());
1205   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
1206 
1207   // Navigate to |singleton_url|.
1208   NavigateParams params(MakeNavigateParams());
1209   params.disposition = WindowOpenDisposition::SINGLETON_TAB;
1210   params.url = GetClearBrowsingDataURL();
1211   params.window_action = NavigateParams::SHOW_WINDOW;
1212   params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
1213   Navigate(&params);
1214 
1215   // The middle tab should now be selected and navigated to the sub-page of the
1216   // URL.
1217   EXPECT_EQ(browser(), params.browser);
1218   EXPECT_EQ(3, browser()->tab_strip_model()->count());
1219   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
1220   EXPECT_EQ(GetClearBrowsingDataURL(),
1221             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1222 }
1223 
1224 // This test verifies that constructing params with disposition = SINGLETON_TAB
1225 // and IGNORE_AND_NAVIGATE will update the current tab's URL if the currently
1226 // selected tab is a match but has a different path.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_SingletonTabFocused_IgnorePath)1227 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1228                        Disposition_SingletonTabFocused_IgnorePath) {
1229   const GURL singleton_url_current(GetContentSettingsURL());
1230   chrome::AddSelectedTabWithURL(browser(), singleton_url_current,
1231                                 ui::PAGE_TRANSITION_LINK);
1232 
1233   // We should have one browser with 2 tabs, the 2nd selected.
1234   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1235   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1236   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
1237 
1238   // Navigate to a different settings path.
1239   const GURL singleton_url_target(GetClearBrowsingDataURL());
1240   NavigateParams params(MakeNavigateParams());
1241   params.disposition = WindowOpenDisposition::SINGLETON_TAB;
1242   params.url = singleton_url_target;
1243   params.window_action = NavigateParams::SHOW_WINDOW;
1244   params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
1245   Navigate(&params);
1246 
1247   // The second tab should still be selected, but navigated to the new path.
1248   EXPECT_EQ(browser(), params.browser);
1249   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1250   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
1251   EXPECT_EQ(singleton_url_target,
1252             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1253 }
1254 
1255 // This test verifies that constructing params with disposition = SINGLETON_TAB
1256 // and IGNORE_AND_NAVIGATE will open an existing matching tab with a different
1257 // query.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_SingletonTabExisting_IgnoreQuery)1258 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1259                        Disposition_SingletonTabExisting_IgnoreQuery) {
1260   int initial_tab_count = browser()->tab_strip_model()->count();
1261   const GURL singleton_url_current(GetContentSettingsURL());
1262   chrome::AddSelectedTabWithURL(browser(), singleton_url_current,
1263                                 ui::PAGE_TRANSITION_LINK);
1264 
1265   EXPECT_EQ(initial_tab_count + 1, browser()->tab_strip_model()->count());
1266   EXPECT_EQ(initial_tab_count, browser()->tab_strip_model()->active_index());
1267 
1268   // Navigate to a different settings path.
1269   const GURL singleton_url_target(GetClearBrowsingDataURL());
1270   NavigateParams params(MakeNavigateParams());
1271   params.disposition = WindowOpenDisposition::SINGLETON_TAB;
1272   params.url = singleton_url_target;
1273   params.window_action = NavigateParams::SHOW_WINDOW;
1274   params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
1275   Navigate(&params);
1276 
1277   // Last tab should still be selected.
1278   EXPECT_EQ(browser(), params.browser);
1279   EXPECT_EQ(initial_tab_count + 1, browser()->tab_strip_model()->count());
1280   EXPECT_EQ(initial_tab_count, browser()->tab_strip_model()->active_index());
1281 }
1282 
1283 // This test verifies that the settings page isn't opened in the incognito
1284 // window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_Settings_UseNonIncognitoWindow)1285 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1286                        Disposition_Settings_UseNonIncognitoWindow) {
1287   RunUseNonIncognitoWindowTest(
1288       GetSettingsURL(), ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK);
1289 }
1290 
1291 // This test verifies that chrome://new-tab-page isn't opened in the incognito
1292 // window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_WebUINewTabPage_UseNonIncognitoWindow)1293 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1294                        Disposition_WebUINewTabPage_UseNonIncognitoWindow) {
1295   RunUseNonIncognitoWindowTest(
1296       GetWebUINewTabPage(), ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK);
1297 }
1298 
1299 // This test verifies that the view-source settings page isn't opened in the
1300 // incognito window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_ViewSource_Settings_DoNothingIfIncognitoForced)1301 IN_PROC_BROWSER_TEST_F(
1302     BrowserNavigatorTest,
1303     Disposition_ViewSource_Settings_DoNothingIfIncognitoForced) {
1304   std::string view_source(content::kViewSourceScheme);
1305   view_source.append(":");
1306   view_source.append(chrome::kChromeUISettingsURL);
1307   RunDoNothingIfIncognitoIsForcedTest(GURL(view_source));
1308 }
1309 
1310 // This test verifies that the view-source settings page isn't opened in the
1311 // incognito window even if incognito mode is forced (does nothing in that
1312 // case).
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_ViewSource_Settings_UseNonIncognitoWindow)1313 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1314                        Disposition_ViewSource_Settings_UseNonIncognitoWindow) {
1315   std::string view_source(content::kViewSourceScheme);
1316   view_source.append(":");
1317   view_source.append(chrome::kChromeUISettingsURL);
1318   RunUseNonIncognitoWindowTest(
1319       GURL(view_source), ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK);
1320 }
1321 
1322 // This test verifies that the settings page isn't opened in the incognito
1323 // window from a non-incognito window (bookmark open-in-incognito trigger).
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_Settings_UseNonIncognitoWindowForBookmark)1324 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1325                        Disposition_Settings_UseNonIncognitoWindowForBookmark) {
1326   NavigateParams params(browser(), GetSettingsURL(),
1327                         ui::PAGE_TRANSITION_AUTO_BOOKMARK);
1328   params.disposition = WindowOpenDisposition::OFF_THE_RECORD;
1329   {
1330     content::WindowedNotificationObserver observer(
1331         content::NOTIFICATION_LOAD_STOP,
1332         content::NotificationService::AllSources());
1333     Navigate(&params);
1334     observer.Wait();
1335   }
1336 
1337   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1338   EXPECT_EQ(GetSettingsURL(),
1339             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1340 }
1341 
1342 // Settings page is expected to always open in normal mode regardless
1343 // of whether the user is trying to open it in incognito mode or not.
1344 // This test verifies that if incognito mode is forced (by policy), settings
1345 // page doesn't open at all.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_Settings_DoNothingIfIncognitoIsForced)1346 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1347                        Disposition_Settings_DoNothingIfIncognitoIsForced) {
1348   RunDoNothingIfIncognitoIsForcedTest(GetSettingsURL());
1349 }
1350 
1351 // This test verifies that the bookmarks page isn't opened in the incognito
1352 // window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_Bookmarks_UseNonIncognitoWindow)1353 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1354                        Disposition_Bookmarks_UseNonIncognitoWindow) {
1355   RunUseNonIncognitoWindowTest(
1356       GURL(chrome::kChromeUIBookmarksURL),
1357       ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK);
1358 }
1359 
1360 // Bookmark manager is expected to always open in normal mode regardless
1361 // of whether the user is trying to open it in incognito mode or not.
1362 // This test verifies that if incognito mode is forced (by policy), bookmark
1363 // manager doesn't open at all.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,Disposition_Bookmarks_DoNothingIfIncognitoIsForced)1364 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1365                        Disposition_Bookmarks_DoNothingIfIncognitoIsForced) {
1366   RunDoNothingIfIncognitoIsForcedTest(GURL(chrome::kChromeUIBookmarksURL));
1367 }
1368 
1369 // This test makes sure a crashed singleton tab reloads from a new navigation.
1370 // TODO(https://crbug.com/396371): Disabled due to flakiness.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,DISABLED_NavigateToCrashedSingletonTab)1371 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1372                        DISABLED_NavigateToCrashedSingletonTab) {
1373   const GURL singleton_url(GetContentSettingsURL());
1374   WebContents* web_contents = chrome::AddSelectedTabWithURL(
1375       browser(), singleton_url, ui::PAGE_TRANSITION_LINK);
1376 
1377   // We should have one browser with 2 tabs, the 2nd selected.
1378   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1379   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1380   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
1381 
1382   // Kill the singleton tab.
1383   web_contents->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1384   EXPECT_TRUE(web_contents->IsCrashed());
1385 
1386   NavigateParams params(MakeNavigateParams());
1387   params.disposition = WindowOpenDisposition::SINGLETON_TAB;
1388   params.url = singleton_url;
1389   params.window_action = NavigateParams::SHOW_WINDOW;
1390   params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
1391   ui_test_utils::NavigateToURL(&params);
1392 
1393   // The tab should not be sad anymore.
1394   EXPECT_FALSE(web_contents->IsCrashed());
1395 }
1396 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateFromDefaultToOptionsInSameTab)1397 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1398                        NavigateFromDefaultToOptionsInSameTab) {
1399   {
1400     content::WindowedNotificationObserver observer(
1401         content::NOTIFICATION_LOAD_STOP,
1402         content::NotificationService::AllSources());
1403     ShowSettings(browser());
1404     observer.Wait();
1405   }
1406   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1407   EXPECT_EQ(GetSettingsURL(),
1408             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1409 }
1410 
1411 // TODO(1024166): Timing out on linux-chromeos-dbg.
1412 #if defined(OS_CHROMEOS)
1413 #define MAYBE_NavigateFromBlankToOptionsInSameTab \
1414   DISABLED_NavigateFromBlankToOptionsInSameTab
1415 #else
1416 #define MAYBE_NavigateFromBlankToOptionsInSameTab \
1417   NavigateFromBlankToOptionsInSameTab
1418 #endif
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,MAYBE_NavigateFromBlankToOptionsInSameTab)1419 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1420                        MAYBE_NavigateFromBlankToOptionsInSameTab) {
1421   NavigateParams params(MakeNavigateParams());
1422   params.url = GURL(url::kAboutBlankURL);
1423   ui_test_utils::NavigateToURL(&params);
1424 
1425   {
1426     content::WindowedNotificationObserver observer(
1427         content::NOTIFICATION_LOAD_STOP,
1428         content::NotificationService::AllSources());
1429     ShowSettings(browser());
1430     observer.Wait();
1431   }
1432   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1433   EXPECT_EQ(GetSettingsURL(),
1434             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1435 }
1436 
1437 // TODO(1024166): Timing out on linux-chromeos-dbg.
1438 #if defined(OS_CHROMEOS)
1439 #define MAYBE_NavigateFromNTPToOptionsInSameTab \
1440   DISABLED_NavigateFromNTPToOptionsInSameTab
1441 #else
1442 #define MAYBE_NavigateFromNTPToOptionsInSameTab \
1443   NavigateFromNTPToOptionsInSameTab
1444 #endif
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,MAYBE_NavigateFromNTPToOptionsInSameTab)1445 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1446                        MAYBE_NavigateFromNTPToOptionsInSameTab) {
1447   NavigateParams params(MakeNavigateParams());
1448   params.url = GURL(chrome::kChromeUINewTabURL);
1449   ui_test_utils::NavigateToURL(&params);
1450   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1451   EXPECT_EQ(local_ntp_test_utils::GetFinalNtpUrl(browser()->profile()),
1452             browser()
1453                 ->tab_strip_model()
1454                 ->GetActiveWebContents()
1455                 ->GetLastCommittedURL());
1456 
1457   {
1458     content::WindowedNotificationObserver observer(
1459         content::NOTIFICATION_LOAD_STOP,
1460         content::NotificationService::AllSources());
1461     ShowSettings(browser());
1462     observer.Wait();
1463   }
1464   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1465   EXPECT_EQ(GetSettingsURL(),
1466             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1467 }
1468 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateFromPageToOptionsInNewTab)1469 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1470                        NavigateFromPageToOptionsInNewTab) {
1471   NavigateParams params(MakeNavigateParams());
1472   ui_test_utils::NavigateToURL(&params);
1473   EXPECT_EQ(GetGoogleURL(),
1474             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1475   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1476   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1477 
1478   {
1479     content::WindowedNotificationObserver observer(
1480         content::NOTIFICATION_LOAD_STOP,
1481         content::NotificationService::AllSources());
1482     ShowSettings(browser());
1483     observer.Wait();
1484   }
1485   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1486   EXPECT_EQ(GetSettingsURL(),
1487             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1488 }
1489 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateFromNTPToOptionsSingleton)1490 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1491                        NavigateFromNTPToOptionsSingleton) {
1492   {
1493     content::WindowedNotificationObserver observer(
1494         content::NOTIFICATION_LOAD_STOP,
1495         content::NotificationService::AllSources());
1496     ShowSettings(browser());
1497     observer.Wait();
1498   }
1499   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1500 
1501   chrome::NewTab(browser());
1502   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1503 
1504   {
1505     content::WindowedNotificationObserver observer(
1506         content::NOTIFICATION_LOAD_STOP,
1507         content::NotificationService::AllSources());
1508     ShowSettings(browser());
1509     observer.Wait();
1510   }
1511   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1512   EXPECT_EQ(GetSettingsURL(),
1513             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1514 }
1515 
1516 // TODO(1024166): Timing out on linux-chromeos-dbg.
1517 #if defined(OS_CHROMEOS)
1518 #define MAYBE_NavigateFromNTPToOptionsPageInSameTab \
1519   DISABLED_NavigateFromNTPToOptionsPageInSameTab
1520 #else
1521 #define MAYBE_NavigateFromNTPToOptionsPageInSameTab \
1522   NavigateFromNTPToOptionsPageInSameTab
1523 #endif
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,MAYBE_NavigateFromNTPToOptionsPageInSameTab)1524 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1525                        MAYBE_NavigateFromNTPToOptionsPageInSameTab) {
1526   {
1527     content::WindowedNotificationObserver observer(
1528         content::NOTIFICATION_LOAD_STOP,
1529         content::NotificationService::AllSources());
1530     chrome::ShowSettingsSubPageInTabbedBrowser(
1531         browser(), chrome::kClearBrowserDataSubPage);
1532     observer.Wait();
1533   }
1534   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1535   EXPECT_EQ(GetClearBrowsingDataURL(),
1536             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1537 
1538   chrome::NewTab(browser());
1539   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1540 
1541   {
1542     content::WindowedNotificationObserver observer(
1543         content::NOTIFICATION_LOAD_STOP,
1544         content::NotificationService::AllSources());
1545     chrome::ShowSettingsSubPageInTabbedBrowser(
1546         browser(), chrome::kClearBrowserDataSubPage);
1547     observer.Wait();
1548   }
1549   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1550   EXPECT_EQ(GetClearBrowsingDataURL(),
1551             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1552 }
1553 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateFromOtherTabToSingletonOptions)1554 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1555                        NavigateFromOtherTabToSingletonOptions) {
1556   {
1557     content::WindowedNotificationObserver observer(
1558         content::NOTIFICATION_LOAD_STOP,
1559         content::NotificationService::AllSources());
1560     ShowSettings(browser());
1561     observer.Wait();
1562   }
1563   {
1564     content::WindowedNotificationObserver observer(
1565         content::NOTIFICATION_LOAD_STOP,
1566         content::NotificationService::AllSources());
1567     chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
1568                                   ui::PAGE_TRANSITION_LINK);
1569     observer.Wait();
1570   }
1571 
1572   // This load should simply cause a tab switch.
1573   ShowSettings(browser());
1574 
1575   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1576   EXPECT_EQ(GetSettingsURL(),
1577             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1578 }
1579 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateFromNoTabStripWindowToOptions)1580 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1581                        NavigateFromNoTabStripWindowToOptions) {
1582   {
1583     content::WindowedNotificationObserver observer(
1584         content::NOTIFICATION_LOAD_STOP,
1585         content::NotificationService::AllSources());
1586     ShowSettings(browser());
1587     observer.Wait();
1588   }
1589   {
1590     content::WindowedNotificationObserver observer(
1591         content::NOTIFICATION_LOAD_STOP,
1592         content::NotificationService::AllSources());
1593     chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
1594                                   ui::PAGE_TRANSITION_LINK);
1595     observer.Wait();
1596   }
1597   Browser* app_browser = CreateBrowserForApp("TestApp", browser()->profile());
1598 
1599   // This load should cause a window and tab switch.
1600   ShowSingletonTab(app_browser, GetSettingsURL());
1601 
1602   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1603   EXPECT_EQ(GetSettingsURL(),
1604             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1605 }
1606 
1607 // TODO(1024166): Timing out on linux-chromeos-dbg.
1608 #if defined(OS_CHROMEOS)
1609 #define MAYBE_CloseSingletonTab DISABLED_CloseSingletonTab
1610 #else
1611 #define MAYBE_CloseSingletonTab CloseSingletonTab
1612 #endif
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,MAYBE_CloseSingletonTab)1613 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, MAYBE_CloseSingletonTab) {
1614   for (int i = 0; i < 2; ++i) {
1615     content::WindowedNotificationObserver observer(
1616         content::NOTIFICATION_LOAD_STOP,
1617         content::NotificationService::AllSources());
1618     chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
1619                                   ui::PAGE_TRANSITION_TYPED);
1620     observer.Wait();
1621   }
1622 
1623   browser()->tab_strip_model()->ActivateTabAt(
1624       0, {TabStripModel::GestureType::kOther});
1625 
1626   {
1627     content::WindowedNotificationObserver observer(
1628         content::NOTIFICATION_LOAD_STOP,
1629         content::NotificationService::AllSources());
1630     ShowSettings(browser());
1631     observer.Wait();
1632   }
1633 
1634   EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt(
1635       2, TabStripModel::CLOSE_USER_GESTURE));
1636   EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
1637 }
1638 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateFromDefaultToHistoryInSameTab)1639 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1640                        NavigateFromDefaultToHistoryInSameTab) {
1641   {
1642     content::WindowedNotificationObserver observer(
1643         content::NOTIFICATION_LOAD_STOP,
1644         content::NotificationService::AllSources());
1645     chrome::ShowHistory(browser());
1646     observer.Wait();
1647   }
1648   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1649   EXPECT_EQ(GURL(chrome::kChromeUIHistoryURL),
1650             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1651 }
1652 
1653 // TODO(linux_aura) http://crbug.com/163931
1654 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
1655 #define MAYBE_NavigateFromDefaultToBookmarksInSameTab \
1656   DISABLED_NavigateFromDefaultToBookmarksInSameTab
1657 #else
1658 #define MAYBE_NavigateFromDefaultToBookmarksInSameTab \
1659   NavigateFromDefaultToBookmarksInSameTab
1660 #endif
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,MAYBE_NavigateFromDefaultToBookmarksInSameTab)1661 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1662                        MAYBE_NavigateFromDefaultToBookmarksInSameTab) {
1663   {
1664     content::WindowedNotificationObserver observer(
1665         content::NOTIFICATION_LOAD_STOP,
1666         content::NotificationService::AllSources());
1667     chrome::ShowBookmarkManager(browser());
1668     observer.Wait();
1669   }
1670   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1671   EXPECT_TRUE(base::StartsWith(
1672       browser()->tab_strip_model()->GetActiveWebContents()->GetURL().spec(),
1673       chrome::kChromeUIBookmarksURL, base::CompareCase::SENSITIVE));
1674 }
1675 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateFromDefaultToDownloadsInSameTab)1676 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1677                        NavigateFromDefaultToDownloadsInSameTab) {
1678   {
1679     content::WindowedNotificationObserver observer(
1680         content::NOTIFICATION_LOAD_STOP,
1681         content::NotificationService::AllSources());
1682     chrome::ShowDownloads(browser());
1683     observer.Wait();
1684   }
1685   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1686   EXPECT_EQ(GURL(chrome::kChromeUIDownloadsURL),
1687             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1688 }
1689 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateWithoutBrowser)1690 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, NavigateWithoutBrowser) {
1691   // First navigate using the profile of the existing browser window, and
1692   // check that the window is reused.
1693   NavigateParams params(browser()->profile(), GetGoogleURL(),
1694                         ui::PAGE_TRANSITION_LINK);
1695   ui_test_utils::NavigateToURL(&params);
1696   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1697 
1698   // Now navigate using the incognito profile and check that a new window
1699   // is created.
1700   NavigateParams params_incognito(browser()->profile()->GetPrimaryOTRProfile(),
1701                                   GetGoogleURL(), ui::PAGE_TRANSITION_LINK);
1702   ui_test_utils::NavigateToURL(&params_incognito);
1703   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
1704 }
1705 
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,ViewSourceIsntSingleton)1706 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, ViewSourceIsntSingleton) {
1707   const std::string viewsource_ntp_url =
1708       std::string(content::kViewSourceScheme) + ":" +
1709       chrome::kChromeUIVersionURL;
1710 
1711   NavigateParams viewsource_params(browser(), GURL(viewsource_ntp_url),
1712                                    ui::PAGE_TRANSITION_LINK);
1713   ui_test_utils::NavigateToURL(&viewsource_params);
1714 
1715   NavigateParams singleton_params(browser(), GURL(chrome::kChromeUIVersionURL),
1716                                   ui::PAGE_TRANSITION_LINK);
1717   singleton_params.disposition = WindowOpenDisposition::SINGLETON_TAB;
1718   EXPECT_EQ(-1, GetIndexOfExistingTab(browser(), singleton_params));
1719 }
1720 
1721 // This test verifies that browser initiated navigations can send requests
1722 // using POST.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SendBrowserInitiatedRequestUsingPOST)1723 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1724                        SendBrowserInitiatedRequestUsingPOST) {
1725   // Uses a test sever to verify POST request.
1726   ASSERT_TRUE(embedded_test_server()->Start());
1727 
1728   // Open a browser initiated POST request in new foreground tab.
1729   base::string16 expected_title(base::ASCIIToUTF16(kExpectedTitle));
1730   std::string post_data = kExpectedTitle;
1731   base::string16 title;
1732   ASSERT_TRUE(OpenPOSTURLInNewForegroundTabAndGetTitle(
1733       embedded_test_server()->GetURL(kEchoTitleCommand), post_data, true,
1734       &title));
1735   EXPECT_EQ(expected_title, title);
1736 }
1737 
1738 // This test verifies that renderer initiated navigations can also send requests
1739 // using POST.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SendRendererInitiatedRequestUsingPOST)1740 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1741                        SendRendererInitiatedRequestUsingPOST) {
1742   // Uses a test sever to verify POST request.
1743   ASSERT_TRUE(embedded_test_server()->Start());
1744 
1745   // Open a renderer initiated POST request in new foreground tab.
1746   base::string16 expected_title(base::ASCIIToUTF16(kExpectedTitle));
1747   std::string post_data = kExpectedTitle;
1748   base::string16 title;
1749   ASSERT_TRUE(OpenPOSTURLInNewForegroundTabAndGetTitle(
1750       embedded_test_server()->GetURL(kEchoTitleCommand), post_data, false,
1751       &title));
1752   EXPECT_EQ(expected_title, title);
1753 }
1754 
1755 // This test navigates to a data URL that contains BiDi control
1756 // characters. For security reasons, BiDi control chars should always be
1757 // escaped in the URL but they should be unescaped in the loaded HTML.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,NavigateToDataURLWithBiDiControlChars)1758 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
1759                        NavigateToDataURLWithBiDiControlChars) {
1760   // Text in Arabic.
1761   std::string text = "\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1";
1762   // Page title starts with RTL mark.
1763   std::string unescaped_title = "\xE2\x80\x8F" + text;
1764   std::string data_url = "data:text/html;charset=utf-8,<html><title>" +
1765                          unescaped_title + "</title></html>";
1766   // BiDi control chars in URLs are always escaped, so the expected URL should
1767   // have the title with the escaped RTL mark.
1768   std::string escaped_title = "%E2%80%8F" + text;
1769   std::string expected_url = "data:text/html;charset=utf-8,<html><title>" +
1770                              escaped_title + "</title></html>";
1771 
1772   // Navigate to the page.
1773   NavigateParams params(MakeNavigateParams());
1774   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
1775   params.url = GURL(data_url);
1776   params.window_action = NavigateParams::SHOW_WINDOW;
1777   ui_test_utils::NavigateToURL(&params);
1778 
1779   base::string16 expected_title(base::UTF8ToUTF16(unescaped_title));
1780   EXPECT_TRUE(params.navigated_or_inserted_contents);
1781   EXPECT_EQ(expected_title, params.navigated_or_inserted_contents->GetTitle());
1782   // GURL always keeps non-ASCII characters escaped, but check them anyways.
1783   EXPECT_EQ(GURL(expected_url).spec(),
1784             params.navigated_or_inserted_contents->GetURL().spec());
1785   // Check the omnibox text. It should have escaped RTL with unescaped text.
1786   LocationBar* location_bar = browser()->window()->GetLocationBar();
1787   OmniboxView* omnibox_view = location_bar->GetOmniboxView();
1788   EXPECT_EQ(base::UTF8ToUTF16(expected_url), omnibox_view->GetText());
1789 }
1790 
1791 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN)
1792 // Flaky on Win and Linux. See https://crbug.com/1044335.
1793 #define MAYBE_ReuseRVHWithWebUI DISABLED_ReuseRVHWithWebUI
1794 #else
1795 #define MAYBE_ReuseRVHWithWebUI ReuseRVHWithWebUI
1796 #endif
1797 
1798 // Test that there's no crash when a navigation to a WebUI page reuses an
1799 // existing swapped out RenderViewHost.  Previously, this led to a browser
1800 // process crash in WebUI pages that use MojoWebUIController, which tried to
1801 // use the RenderViewHost's GetMainFrame() when it was invalid in
1802 // RenderViewCreated(). See https://crbug.com/627027.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,MAYBE_ReuseRVHWithWebUI)1803 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, MAYBE_ReuseRVHWithWebUI) {
1804   ASSERT_TRUE(embedded_test_server()->Start());
1805 
1806   // Visit a WebUI page with bindings.
1807   GURL webui_url(chrome::kChromeUIOmniboxURL);
1808   ui_test_utils::NavigateToURL(browser(), webui_url);
1809 
1810   // window.open a new tab.  This will keep the chrome://omnibox process alive
1811   // once we navigate away from it.
1812   content::WindowedNotificationObserver windowed_observer(
1813       content::NOTIFICATION_LOAD_STOP,
1814       content::NotificationService::AllSources());
1815   ASSERT_TRUE(content::ExecuteScript(
1816       browser()->tab_strip_model()->GetActiveWebContents(),
1817       "window.open('" + webui_url.spec() + "');"));
1818   windowed_observer.Wait();
1819   content::NavigationController* controller =
1820       content::Source<content::NavigationController>(windowed_observer.source())
1821           .ptr();
1822   WebContents* popup = controller->GetWebContents();
1823   ASSERT_TRUE(popup);
1824   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1825   content::RenderViewHost* webui_rvh =
1826       popup->GetMainFrame()->GetRenderViewHost();
1827   content::RenderFrameHost* webui_rfh = popup->GetMainFrame();
1828   EXPECT_TRUE(content::BINDINGS_POLICY_MOJO_WEB_UI &
1829               webui_rfh->GetEnabledBindings());
1830 
1831   // Navigate to another page in the popup.
1832   GURL nonwebui_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
1833   ui_test_utils::NavigateToURL(browser(), nonwebui_url);
1834   EXPECT_NE(webui_rvh, popup->GetMainFrame()->GetRenderViewHost());
1835 
1836   // Go back in the popup.  This should finish without crashing and should
1837   // reuse the old RenderViewHost.
1838   content::TestNavigationObserver back_load_observer(popup);
1839   controller->GoBack();
1840   back_load_observer.Wait();
1841   EXPECT_EQ(webui_rvh, popup->GetMainFrame()->GetRenderViewHost());
1842   EXPECT_TRUE(webui_rvh->IsRenderViewLive());
1843   EXPECT_TRUE(content::BINDINGS_POLICY_MOJO_WEB_UI &
1844               webui_rvh->GetMainFrame()->GetEnabledBindings());
1845 }
1846 
1847 // Test that main frame navigations generate a NavigationUIData with the
1848 // correct disposition.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,MainFrameNavigationUIData)1849 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, MainFrameNavigationUIData) {
1850   ASSERT_TRUE(embedded_test_server()->Start());
1851 
1852   {
1853     const GURL url = embedded_test_server()->GetURL("/title1.html");
1854     TestNavigationUIDataObserver observer(url);
1855 
1856     NavigateParams params(MakeNavigateParams());
1857     params.url = url;
1858     params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
1859     ui_test_utils::NavigateToURL(&params);
1860     observer.WaitForNavigationFinished();
1861 
1862     EXPECT_EQ(WindowOpenDisposition::NEW_FOREGROUND_TAB,
1863               observer.last_navigation_ui_data()->window_open_disposition());
1864   }
1865 
1866   {
1867     const GURL url = embedded_test_server()->GetURL("/title2.html");
1868     TestNavigationUIDataObserver observer(url);
1869 
1870     NavigateParams params(MakeNavigateParams());
1871     params.url = url;
1872     params.disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB;
1873     ui_test_utils::NavigateToURL(&params);
1874     observer.WaitForNavigationFinished();
1875 
1876     EXPECT_EQ(WindowOpenDisposition::NEW_BACKGROUND_TAB,
1877               observer.last_navigation_ui_data()->window_open_disposition());
1878   }
1879 }
1880 
1881 // Test that subframe navigations generate a NavigationUIData with no
1882 // disposition.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,SubFrameNavigationUIData)1883 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SubFrameNavigationUIData) {
1884   ASSERT_TRUE(embedded_test_server()->Start());
1885 
1886   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1887 
1888   // Load page with iframe.
1889   const GURL url1 = embedded_test_server()->GetURL("/iframe.html");
1890   ui_test_utils::NavigateToURL(browser(), url1);
1891 
1892   // Retrieve the iframe.
1893   const auto all_frames = tab->GetAllFrames();
1894   const content::RenderFrameHost* main_frame = tab->GetMainFrame();
1895   DCHECK_EQ(2u, all_frames.size());
1896   auto it = std::find_if(all_frames.begin(), all_frames.end(),
1897                          [main_frame](content::RenderFrameHost* frame) {
1898                            return main_frame != frame;
1899                          });
1900   DCHECK(it != all_frames.end());
1901   content::RenderFrameHost* iframe = *it;
1902 
1903   // Navigate the iframe with a disposition.
1904   NavigateParams params(browser(),
1905                         embedded_test_server()->GetURL("/simple.html"),
1906                         ui::PAGE_TRANSITION_LINK);
1907   params.frame_tree_node_id = iframe->GetFrameTreeNodeId();
1908   params.disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB;
1909 
1910   TestNavigationUIDataObserver observer(
1911       embedded_test_server()->GetURL("/simple.html"));
1912   ui_test_utils::NavigateToURL(&params);
1913   observer.WaitForNavigationFinished();
1914 
1915   // The disposition passed to NavigateToURL should be ignored for sub frame
1916   // navigations.
1917   EXPECT_EQ(WindowOpenDisposition::CURRENT_TAB,
1918             observer.last_navigation_ui_data()->window_open_disposition());
1919 }
1920 
1921 }  // namespace
1922