// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/browser_navigator_browsertest.h"

#include <memory>

#include "base/compiler_specific.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_future.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/file_system_access/file_system_access_features.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/chrome_navigation_ui_data.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/browser/ui/page_info/chrome_page_info_delegate.h"
#include "chrome/browser/ui/search/ntp_test_utils.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/ui/tabs/tab_enums.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/captive_portal/core/buildflags.h"
#include "components/content_settings/core/common/features.h"
#include "components/omnibox/browser/tab_matcher.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/no_renderer_crashes_assertion.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "net/base/features.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "net/test/scoped_mutually_exclusive_feature_list.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "third_party/blink/public/common/features.h"
#include "ui/display/screen_base.h"

#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
#include "components/captive_portal/content/captive_portal_tab_helper.h"
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "ash/shell.h"
#include "ui/display/test/display_manager_test_api.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#endif

using content::WebContents;

namespace {

const char kExpectedTitle[] = "PASSED!";
const char16_t kExpectedTitle16[] = u"PASSED!";
const char kEchoTitleCommand[] = "/echotitle";

GURL GetGoogleURL() {
  return GURL("http://www.google.com/");
}

GURL GetSettingsURL() {
  return GURL(chrome::kChromeUISettingsURL);
}

GURL GetContentSettingsURL() {
  return GetSettingsURL().Resolve(chrome::kContentSettingsSubPage);
}

GURL GetClearBrowsingDataURL() {
  return GetSettingsURL().Resolve(chrome::kClearBrowserDataSubPage);
}

void ShowSettings(Browser* browser) {
  // chrome::ShowSettings just calls ShowSettingsSubPageInTabbedBrowser on
  // non chromeos, but we want to test tab navigation here so call
  // ShowSettingsSubPageInTabbedBrowser directly.
  chrome::ShowSettingsSubPageInTabbedBrowser(browser, std::string());
}

// Intercepts requests and makes them 302 to the 'redirect' query parameter
// if it's set. If the 'popin-policy' query parameter is set, it sets the
// 'Popin-Policy' response header to that value.
std::unique_ptr<net::test_server::HttpResponse> PopinRequestHandler(
    const net::test_server::HttpRequest& request) {
  auto response = std::make_unique<net::test_server::BasicHttpResponse>();
  response->set_content_type("text/html");
  response->set_content("<html></html");
  net::test_server::RequestQuery query =
      net::test_server::ParseQuery(request.GetURL());
  if (query.find("redirect") != query.end()) {
    response->AddCustomHeader("Location", query["redirect"][0]);
    response->set_code(net::HTTP_FOUND);
  } else {
    response->set_code(net::HTTP_OK);
  }
  if (query.find("popin_policy") != query.end()) {
    std::string proposed_policy = query["popin_policy"][0];
    // We need to fixup the dynamic port so that the policies can match.
    base::ReplaceSubstringsAfterOffset(&proposed_policy, 0, "a.test",
                                       "a.test:" + request.GetURL().GetPort());
    response->AddCustomHeader("Popin-Policy", "partitioned=" + proposed_policy);
  }
  return response;
}

}  // namespace

BrowserNavigatorTest::BrowserNavigatorTest() {
  scoped_feature_list_.InitWithFeatures(
      {
          features::kFileSystemAccessPersistentPermissions,
          blink::features::kPartitionedPopins,
          content_settings::features::kTrackingProtection3pcd,
      },
      {});
}

void BrowserNavigatorTest::SetUpOnMainThread() {
  host_resolver()->AddRule("*", "127.0.0.1");
}

NavigateParams BrowserNavigatorTest::MakeNavigateParams() const {
  return MakeNavigateParams(browser());
}

NavigateParams BrowserNavigatorTest::MakeNavigateParams(
    BrowserWindowInterface* browser) const {
  NavigateParams params(browser, GetGoogleURL(), ui::PAGE_TRANSITION_LINK);
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  return params;
}

bool BrowserNavigatorTest::OpenPOSTURLInNewForegroundTabAndGetTitle(
    const GURL& url,
    const std::string& post_data,
    bool is_browser_initiated,
    std::u16string* title) {
  NavigateParams param(MakeNavigateParams());
  param.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  param.url = url;
  param.initiator_origin = url::Origin();
  param.is_renderer_initiated = !is_browser_initiated;
  param.post_data = network::ResourceRequestBody::CreateFromCopyOfBytes(
      base::as_byte_span(post_data));

  ui_test_utils::NavigateToURL(&param);
  if (!param.navigated_or_inserted_contents) {
    return false;
  }

  // Navigate() should have opened the contents in new foreground tab in the
  // current Browser.
  EXPECT_EQ(browser(), param.browser);
  EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
            param.navigated_or_inserted_contents);
  // We should have one window, with one tab.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  *title = param.navigated_or_inserted_contents->GetTitle();
  return true;
}

Browser* BrowserNavigatorTest::CreateEmptyBrowserForType(Browser::Type type,
                                                         Profile* profile) {
  Browser* browser =
      Browser::Create(Browser::CreateParams(type, profile, true));
  chrome::AddTabAt(browser, GURL(), -1, true);
  return browser;
}

Browser* BrowserNavigatorTest::CreateEmptyBrowserForApp(Profile* profile) {
  Browser* browser = Browser::Create(Browser::CreateParams::CreateForApp(
      "Test", false /* trusted_source */, gfx::Rect(), profile, true));
  chrome::AddTabAt(browser, GURL(), -1, true);
  return browser;
}

std::unique_ptr<WebContents> BrowserNavigatorTest::CreateWebContents(
    bool initialize_renderer) {
  WebContents::CreateParams create_params(browser()->profile());
  create_params.desired_renderer_state =
      initialize_renderer
          ? WebContents::CreateParams::kInitializeAndWarmupRendererProcess
          : WebContents::CreateParams::kOkayToHaveRendererProcess;
  return WebContents::Create(create_params);
}

void BrowserNavigatorTest::RunSuppressTest(WindowOpenDisposition disposition) {
  GURL old_url = browser()->tab_strip_model()->GetActiveWebContents()->GetURL();
  NavigateParams params(MakeNavigateParams());
  params.disposition = disposition;
  Navigate(&params);

  // Nothing should have happened as a result of Navigate();
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(old_url,
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

void BrowserNavigatorTest::RunUseNonIncognitoWindowTest(
    const GURL& url,
    const ui::PageTransition& page_transition) {
  Browser* incognito_browser = CreateIncognitoBrowser();

  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, incognito_browser->tab_strip_model()->count());

  // Navigate to the page.
  NavigateParams params(MakeNavigateParams(incognito_browser));
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = url;
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  params.transition = page_transition;
  Navigate(&params);

  // This page should be opened in browser() window.
  EXPECT_NE(incognito_browser, params.browser);
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(url,
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

void BrowserNavigatorTest::RunDoNothingIfIncognitoIsForcedTest(
    const GURL& url) {
  Browser* browser = CreateIncognitoBrowser();

  // Set kIncognitoModeAvailability to FORCED.
  PrefService* prefs1 = browser->profile()->GetPrefs();
  prefs1->SetInteger(
      policy::policy_prefs::kIncognitoModeAvailability,
      static_cast<int>(policy::IncognitoModeAvailability::kForced));
  PrefService* prefs2 = browser->profile()->GetOriginalProfile()->GetPrefs();
  prefs2->SetInteger(
      policy::policy_prefs::kIncognitoModeAvailability,
      static_cast<int>(policy::IncognitoModeAvailability::kForced));

  // Navigate to the page.
  NavigateParams params(MakeNavigateParams(browser));
  params.disposition = WindowOpenDisposition::OFF_THE_RECORD;
  params.url = url;
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  Navigate(&params);

  // The page should not be opened.
  EXPECT_EQ(browser, params.browser);
  EXPECT_EQ(1, browser->tab_strip_model()->count());
  EXPECT_EQ(GURL(url::kAboutBlankURL),
            browser->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// Subclass of TestNavigationObserver that saves ChromeNavigationUIData.
class TestNavigationUIDataObserver : public content::TestNavigationObserver {
 public:
  // Creates an observer that watches navigations to |target_url| on
  // existing and newly added WebContents.
  explicit TestNavigationUIDataObserver(const GURL& target_url)
      : content::TestNavigationObserver(target_url) {
    WatchExistingWebContents();
    StartWatchingNewWebContents();
  }

  const ChromeNavigationUIData* last_navigation_ui_data() const {
    return static_cast<ChromeNavigationUIData*>(last_navigation_ui_data_.get());
  }

 private:
  void OnDidFinishNavigation(
      content::NavigationHandle* navigation_handle) override {
    last_navigation_ui_data_ =
        navigation_handle->GetNavigationUIData()->Clone();
    content::TestNavigationObserver::OnDidFinishNavigation(navigation_handle);
  }

  std::unique_ptr<content::NavigationUIData> last_navigation_ui_data_;
};

Browser* BrowserNavigatorTest::NavigateHelper(const GURL& url,
                                              Browser* browser,
                                              WindowOpenDisposition disposition,
                                              bool wait_for_navigation,
                                              WebContents* expected_contents) {
  // If this should navigate the current tab, than assume that the WebContents
  // will be the same one.  This is a convenience for the common case.
  if (disposition == WindowOpenDisposition::CURRENT_TAB) {
    EXPECT_FALSE(expected_contents);
    expected_contents = browser->tab_strip_model()->GetActiveWebContents();
  }
  std::optional<content::CreateAndLoadWebContentsObserver> new_tab_observer;
  std::optional<content::LoadStopObserver> load_stop_observer;
  if (wait_for_navigation) {
    if (expected_contents) {
      load_stop_observer.emplace(expected_contents);
    } else {
      new_tab_observer.emplace();
    }
  }

  NavigateParams params(MakeNavigateParams(browser));
  params.disposition = disposition;
  params.url = url;
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  Navigate(&params);

  if (load_stop_observer) {
    load_stop_observer->Wait();
  }
  if (new_tab_observer) {
    new_tab_observer->Wait();
  }

  return params.browser->GetBrowserForMigrationOnly();
}

namespace {

// This test verifies that when a navigation occurs within a tab, the tab count
// of the Browser remains the same and the current tab bears the loaded URL.
// Note that network URLs are not actually loaded in tests, so this also tests
// that error pages leave the intended URL in the address bar.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_CurrentTab) {
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetGoogleURL()));
  EXPECT_EQ(GetGoogleURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
  // We should have one window with one tab.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
}

// This test verifies that a singleton tab is refocused if one is already opened
// in another or an existing window, or added if it is not.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_SingletonTabExisting) {
  const GURL singleton_url1("http://maps.google.com/");

  chrome::AddSelectedTabWithURL(browser(), singleton_url1,
                                ui::PAGE_TRANSITION_LINK);
  chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
                                ui::PAGE_TRANSITION_LINK);

  // We should have one browser with 3 tabs, the 3rd selected.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(3, browser()->tab_strip_model()->count());
  EXPECT_EQ(2, browser()->tab_strip_model()->active_index());

  // Navigate to singleton_url1.
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = singleton_url1;
  Navigate(&params);

  // The middle tab should now be selected.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());

  // No tab contents should have been created
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(3, browser()->tab_strip_model()->count());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_SingletonTabNoneExisting) {
  const GURL singleton_url1("http://maps.google.com/");

  // We should have one browser with 1 tab.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(0, browser()->tab_strip_model()->active_index());

  // Navigate to singleton_url1.
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = singleton_url1;
  Navigate(&params);

  // We should now have 2 tabs, the 2nd one selected.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
}

// This test verifies that when a navigation results in a foreground tab, the
// tab count of the Browser increases and the selected tab shifts to the new
// foreground tab.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewForegroundTab) {
  WebContents* old_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  Navigate(&params);
  EXPECT_NE(old_contents, browser()->tab_strip_model()->GetActiveWebContents());
  EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
            params.navigated_or_inserted_contents);
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
}

// This test verifies that when a navigation results in a background tab, the
// tab count of the Browser increases but the selected tab remains the same.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewBackgroundTab) {
  WebContents* old_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB;
  Navigate(&params);
  WebContents* new_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  // The selected tab should have remained unchanged, since the new tab was
  // opened in the background.
  EXPECT_EQ(old_contents, new_contents);
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
}

// This test verifies that when a navigation requiring a new foreground tab
// occurs in a Browser that cannot host multiple tabs, the new foreground tab
// is created in an existing compatible Browser.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_IncompatibleWindow_Existing) {
  // Open a foreground tab in a window that cannot open popups when there is an
  // existing compatible window somewhere else that they can be opened within.
  Browser* popup =
      CreateEmptyBrowserForType(Browser::TYPE_POPUP, browser()->profile());
  NavigateParams params(MakeNavigateParams(popup));
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  Navigate(&params);

  // Navigate() should have opened the tab in a different browser since the
  // one we supplied didn't support additional tabs.
  EXPECT_NE(popup, params.browser);

  // Since browser() is an existing compatible tabbed browser, it should have
  // opened the tab there.
  EXPECT_EQ(browser(), params.browser);

  // We should be left with 2 windows, the popup with one tab and the browser()
  // provided by the framework with two.
  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, popup->tab_strip_model()->count());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
}

// This test verifies that when a navigation requiring a new foreground tab
// occurs in a Browser that cannot host multiple tabs and no compatible Browser
// that can is open, a compatible Browser is created.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_IncompatibleWindow_NoExisting) {
  // We want to simulate not being able to find an existing window compatible
  // with our non-tabbed browser window so Navigate() is forced to create a
  // new compatible window. Because browser() supplied by the in-process
  // browser testing framework is compatible with browser()->profile(), we
  // need a different profile, and creating a popup window with an incognito
  // profile is a quick and dirty way of achieving this.
  Browser* popup = CreateEmptyBrowserForType(
      Browser::TYPE_POPUP,
      browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true));
  NavigateParams params(MakeNavigateParams(popup));
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  Navigate(&params);

  // Navigate() should have opened the tab in a different browser since the
  // one we supplied didn't support additional tabs.
  EXPECT_NE(popup, params.browser);

  // This time, browser() is _not_ compatible with popup since it is not an
  // incognito window.
  EXPECT_NE(browser(), params.browser);

  // We should have three windows, each with one tab:
  // 1. the browser() provided by the framework (unchanged in this test)
  // 2. the incognito popup we created originally
  // 3. the new incognito tabbed browser that was created by Navigate().
  EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, popup->tab_strip_model()->count());
  EXPECT_EQ(
      1,
      params.browser->GetBrowserForMigrationOnly()->tab_strip_model()->count());
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()->is_type_normal());
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()
                  ->window()
                  ->IsToolbarVisible());
}

// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
// from a normal Browser results in a new Browser with TYPE_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopup) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_POPUP;
  params.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  // Wait for new popup to to load and gain focus.
  ui_test_utils::NavigateToURL(&params);

  // Navigate() should have opened a new, focused popup window, with a toolbar.
  EXPECT_NE(browser(), params.browser);
#if 0
  // TODO(stevenjb): Enable this test. See: crbug.com/79493
  EXPECT_TRUE(browser->window()->IsActive());
#endif
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()->is_type_popup());
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()
                  ->window()
                  ->IsToolbarVisible());

  // We should have two windows, the browser() provided by the framework and the
  // new popup window.
  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(
      1,
      params.browser->GetBrowserForMigrationOnly()->tab_strip_model()->count());
}

// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
// from a (kind of app) Browser results in a new Browser with TYPE_APP_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopup_ExtensionId) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_POPUP;
  params.app_id = "extensionappid";
  params.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  // Wait for new popup to to load and gain focus.
  ui_test_utils::NavigateToURL(&params);

  // Navigate() should have opened a new, focused TYPE_APP_POPUP window with no
  // toolbar.
  EXPECT_NE(browser(), params.browser);
  EXPECT_TRUE(
      params.browser->GetBrowserForMigrationOnly()->is_type_app_popup());
  EXPECT_FALSE(params.browser->GetBrowserForMigrationOnly()
                   ->window()
                   ->IsToolbarVisible());

  // We should have two windows, the browser() provided by the framework and the
  // new popup window.
  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(
      1,
      params.browser->GetBrowserForMigrationOnly()->tab_strip_model()->count());
}

// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
// from a normal popup results in a new Browser with TYPE_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupFromPopup) {
  // Open a popup.
  NavigateParams params1(MakeNavigateParams());
  params1.disposition = WindowOpenDisposition::NEW_POPUP;
  params1.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  Navigate(&params1);
  // Open another popup.
  NavigateParams params2(MakeNavigateParams(params1.browser));
  params2.disposition = WindowOpenDisposition::NEW_POPUP;
  params2.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  Navigate(&params2);

  // Navigate() should have opened a new normal popup window.
  EXPECT_NE(params1.browser, params2.browser);
  EXPECT_TRUE(params2.browser->GetBrowserForMigrationOnly()->is_type_popup());
  EXPECT_TRUE(params2.browser->GetBrowserForMigrationOnly()
                  ->window()
                  ->IsToolbarVisible());

  // We should have three windows, the browser() provided by the framework,
  // the first popup window, and the second popup window.
  EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, params1.browser->GetBrowserForMigrationOnly()
                   ->tab_strip_model()
                   ->count());
  EXPECT_EQ(1, params2.browser->GetBrowserForMigrationOnly()
                   ->tab_strip_model()
                   ->count());
}

// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
// from an app frame results in a new Browser with TYPE_APP_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_NewPopupFromAppWindow) {
  Browser* app_browser = CreateEmptyBrowserForApp(browser()->profile());
  NavigateParams params(MakeNavigateParams(app_browser));
  params.disposition = WindowOpenDisposition::NEW_POPUP;
  params.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  Navigate(&params);

  // Navigate() should have opened a new TYPE_APP_POPUP window with no toolbar.
  EXPECT_NE(app_browser, params.browser);
  EXPECT_NE(browser(), params.browser);
  EXPECT_TRUE(
      params.browser->GetBrowserForMigrationOnly()->is_type_app_popup());
  EXPECT_FALSE(params.browser->GetBrowserForMigrationOnly()
                   ->window()
                   ->IsToolbarVisible());

  // We should now have three windows, the app window, the app popup it created,
  // and the original browser() provided by the framework.
  EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(
      1, app_browser->GetBrowserForMigrationOnly()->tab_strip_model()->count());
  EXPECT_EQ(
      1,
      params.browser->GetBrowserForMigrationOnly()->tab_strip_model()->count());
}

// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
// from an app popup results in a new Browser also of TYPE_APP_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupFromAppPopup) {
  Browser* app_browser = CreateEmptyBrowserForApp(browser()->profile());
  // Open an app popup.
  NavigateParams params1(MakeNavigateParams(app_browser));
  params1.disposition = WindowOpenDisposition::NEW_POPUP;
  params1.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  Navigate(&params1);
  // Now open another app popup.
  NavigateParams params2(MakeNavigateParams(params1.browser));
  params2.disposition = WindowOpenDisposition::NEW_POPUP;
  params2.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  Navigate(&params2);

  // Navigate() should have opened a new popup app window.
  EXPECT_NE(browser(), params1.browser);
  EXPECT_NE(params1.browser, params2.browser);
  EXPECT_TRUE(
      params2.browser->GetBrowserForMigrationOnly()->is_type_app_popup());
  EXPECT_FALSE(params2.browser->GetBrowserForMigrationOnly()
                   ->window()
                   ->IsToolbarVisible());

  // We should now have four windows, the app window, the first app popup,
  // the second app popup, and the original browser() provided by the framework.
  EXPECT_EQ(4u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, app_browser->tab_strip_model()->count());
  EXPECT_EQ(1, params1.browser->GetBrowserForMigrationOnly()
                   ->tab_strip_model()
                   ->count());
  EXPECT_EQ(1, params2.browser->GetBrowserForMigrationOnly()
                   ->tab_strip_model()
                   ->count());
}

// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
// from an extension app tab results in a new Browser with TYPE_APP_POPUP.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_NewPopupFromExtensionApp) {
  // TODO(beng): TBD.
}

// This test verifies that navigating with window_action = SHOW_WINDOW_INACTIVE
// does not focus a new new popup window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupUnfocused) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_POPUP;
  params.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  params.window_action = NavigateParams::WindowAction::kShowWindowInactive;
  // Wait for new popup to load (and gain focus if the test fails).
  ui_test_utils::NavigateToURL(&params);

  // Navigate() should have opened a new, unfocused, popup window.
  EXPECT_NE(browser(), params.browser);
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()->is_type_popup());
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()
                  ->window()
                  ->IsToolbarVisible());
#if 0
// TODO(stevenjb): Enable this test. See: crbug.com/79493
  EXPECT_FALSE(p.browser->window()->IsActive());
#endif
}

// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
// and trusted_source = true results in a new Browser where is_trusted_source()
// is true.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupTrusted) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_POPUP;
  params.trusted_source = true;
  params.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  // Wait for new popup to to load and gain focus.
  ui_test_utils::NavigateToURL(&params);

  // Navigate() should have opened a new popup window of TYPE_POPUP with no
  // toolbar.
  EXPECT_NE(browser(), params.browser);
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()->is_type_popup());
  EXPECT_TRUE(
      params.browser->GetBrowserForMigrationOnly()->is_trusted_source());
  EXPECT_FALSE(params.browser->GetBrowserForMigrationOnly()
                   ->window()
                   ->IsToolbarVisible());
}

#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
// and NavigateParams::CaptivePortalWindowType::kPopup results in a new
// WebContents where is_captive_portal_window() is true.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_NewPopupCaptivePortal) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_POPUP;
  params.captive_portal_window_type =
      captive_portal::CaptivePortalWindowType::kPopup;
  params.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  // Wait for new popup to to load and gain focus.
  ui_test_utils::NavigateToURL(&params);

  // Navigate() should have opened a new popup window of TYPE_POPUP with a
  // toolbar.
  EXPECT_NE(browser(), params.browser);
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()->is_type_popup());
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()
                  ->window()
                  ->IsToolbarVisible());
  EXPECT_TRUE(captive_portal::CaptivePortalTabHelper::FromWebContents(
                  params.navigated_or_inserted_contents)
                  ->is_captive_portal_window());
}
#endif

// This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
// and is_tab_modal_popup_deprecated = true results in a new WebContents that is
// a popup and behaves like a tab modal.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupTabModal) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_POPUP;
  params.is_tab_modal_popup_deprecated = true;
  params.window_features.bounds = gfx::Rect(0, 0, 200, 200);
  // Wait for new popup to load and gain focus.
  ui_test_utils::NavigateToURL(&params);

  // Add a new tab.
  chrome::AddTabAt(browser(), GURL("about:blank"), -1, true);

  // Switch to the new tab.
  browser()->tab_strip_model()->ActivateTabAt(1);

  // Verify the popup window is hidden.
  EXPECT_FALSE(params.browser->GetWindow()->IsVisible());

  // Switch back to the original tab.
  browser()->tab_strip_model()->ActivateTabAt(0);

  // Verify the popup window is visible again.
  EXPECT_TRUE(params.browser->GetWindow()->IsVisible());

  // Verify the popup window is set as tab model popup.
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()
                  ->window()
                  ->IsTabModalPopupDeprecated());
}

// This test verifies that navigating with WindowOpenDisposition = NEW_WINDOW
// always opens a new window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewWindow) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_WINDOW;
  Navigate(&params);

  // Navigate() should have opened a new toplevel window.
  EXPECT_NE(browser(), params.browser);
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()->is_type_normal());
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()
                  ->window()
                  ->IsToolbarVisible());

  // We should now have two windows, the browser() provided by the framework and
  // the new normal window.
  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(
      1,
      params.browser->GetBrowserForMigrationOnly()->tab_strip_model()->count());
}

// This test verifies that a source tab to the left of the target tab can
// be switched away from and closed. It verifies that if we close the
// earlier tab, that we don't use a stale index, and select the wrong tab.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, OutOfOrderTabSwitchTest) {
  const GURL singleton_url("http://maps.google.com/");

  NavigateHelper(singleton_url, browser(),
                 WindowOpenDisposition::NEW_FOREGROUND_TAB, true);
  WebContents* new_tab = browser()->tab_strip_model()->GetActiveWebContents();

  browser()->tab_strip_model()->ActivateTabAt(
      0, TabStripUserGestureDetails(
             TabStripUserGestureDetails::GestureType::kOther));

  NavigateHelper(singleton_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
                 false, new_tab);
}

// This test verifies the two cases of attempting to switch to a tab that no
// longer exists: if NTP, load in current tab, otherwise load in new
// foreground tab.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, NavigateOnTabSwitchLostTest) {
  const GURL singleton_url("chrome://dino");

  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
  NavigateHelper(singleton_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
                 true, tab);
  EXPECT_EQ(1, browser()->tab_strip_model()->count());

  NavigateHelper(GURL("chrome://about"), browser(),
                 WindowOpenDisposition::NEW_FOREGROUND_TAB, true);
  int previous_tab_count = browser()->tab_strip_model()->count();
  browser()->tab_strip_model()->CloseWebContentsAt(0,
                                                   TabCloseTypes::CLOSE_NONE);
  EXPECT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count());
  // This expects a new WebContents, since we just closed the tab.
  NavigateHelper(singleton_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
                 true, nullptr /* expected_contents */);
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
}

// This test verifies that SWITCH_TO_TAB will switch to a tab even if the scheme
// mismatches, as long as the rest of the URL does.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SchemeMismatchTabSwitchTest) {
  GURL navigate_url("https://www.chromium.org/");
  GURL search_url("http://www.chromium.org/");
  GURL dino_url("chrome://dino");

  NavigateHelper(navigate_url, browser(), WindowOpenDisposition::CURRENT_TAB,
                 true);
  NavigateHelper(dino_url, browser(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
                 true);

  // We must be on another tab than the target for it to be found and
  // switched to. To meet that requirement, ensure the dino tab is currently
  // active.
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());

  NavigateHelper(search_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
                 false);
  EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
}

// Make sure that switching tabs preserves the post-focus state (of the
// content area) of the previous tab.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SaveAfterFocusTabSwitchTest) {
  GURL first_url("chrome://dino/");
  GURL second_url("chrome://history/");

  NavigateHelper(first_url, browser(), WindowOpenDisposition::CURRENT_TAB,
                 true);

  // Generate history so the tab isn't closed.
  NavigateHelper(second_url, browser(),
                 WindowOpenDisposition::NEW_FOREGROUND_TAB, true);

  LocationBar* location_bar = browser()->window()->GetLocationBar();
  location_bar->FocusLocation(true);

  NavigateHelper(first_url, browser(), WindowOpenDisposition::SWITCH_TO_TAB,
                 false);

  browser()->tab_strip_model()->ActivateTabAt(
      1, TabStripUserGestureDetails(
             TabStripUserGestureDetails::GestureType::kOther));

  OmniboxView* omnibox_view = location_bar->GetOmniboxView();
  EXPECT_EQ(omnibox_view->model()->focus_state(),
            OmniboxFocusState::OMNIBOX_FOCUS_NONE);
}

// This test verifies that we're picking the correct browser and tab to
// switch to. It verifies that we don't recommend the active tab, and that,
// when switching, we don't mistakenly pick the current browser. Note that this
// test checks which window the new tab was created in, but does not check
// whether the target window was activated - that would require a much slower
// interactive UI test, since we'd have to wait for the async window activation
// to complete to avoid flakes.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SwitchToTabCorrectWindow) {
  const GURL url1("http://example1.chromium.org");
  const GURL url2("http://example2.chromium.org");

  // Make singleton tab.
  Browser* browser1 =
      NavigateHelper(url1, browser(), WindowOpenDisposition::CURRENT_TAB, true);

  // Make a new window with different URL.
  Browser* browser2 =
      NavigateHelper(url2, browser1, WindowOpenDisposition::NEW_WINDOW, true);
  EXPECT_NE(browser1, browser2);

  EXPECT_EQ(browser1,
            NavigateHelper(url1, browser2, WindowOpenDisposition::SWITCH_TO_TAB,
                           false));
  EXPECT_EQ(browser2,
            NavigateHelper(url2, browser1, WindowOpenDisposition::SWITCH_TO_TAB,
                           false));
}

// TODO(crbug.com/40806044): Reactivate the test.
// This test verifies that "switch to tab" prefers the latest used browser,
// if multiple exist.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, DISABLED_SwitchToTabLatestWindow) {
  // Navigate to a site.
  NavigateHelper(GURL("http://maps.google.com/"), browser(),
                 WindowOpenDisposition::CURRENT_TAB, true);

  // Navigate to a new window.
  Browser* browser1 = NavigateHelper(GURL("http://maps.google.com/"), browser(),
                                     WindowOpenDisposition::NEW_WINDOW, true);

  // Make yet another window.
  Browser* browser2 = NavigateHelper(GURL("http://maps.google.com/"), browser(),
                                     WindowOpenDisposition::NEW_WINDOW, true);

  // Navigate to the latest copy of the URL, in spite of specifying
  // the previous browser.
  Browser* test_browser =
      NavigateHelper(GURL("http://maps.google.com/"), browser1,
                     WindowOpenDisposition::SWITCH_TO_TAB, false);

  EXPECT_EQ(browser2, test_browser);
}

// Tests that a disposition of SINGLETON_TAB cannot see outside its
// window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SingletonWindowLeak) {
  // Navigate to a site.
  NavigateHelper(GURL("chrome://dino"), browser(),
                 WindowOpenDisposition::CURRENT_TAB, true);

  // Navigate to a new window.
  Browser* browser2 = NavigateHelper(GURL("chrome://about"), browser(),
                                     WindowOpenDisposition::NEW_WINDOW, true);

  // Make sure we open non-special URL here.
  Browser* test_browser =
      NavigateHelper(GURL("chrome://dino"), browser2,
                     WindowOpenDisposition::NEW_FOREGROUND_TAB, true);
  EXPECT_EQ(browser2, test_browser);
}

// Tests that a disposition of SINGLETON_TAB cannot see across anonymity,
// except for certain non-incognito affinity URLs (e.g. settings).
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SingletonIncognitoLeak) {
  Browser* orig_browser;

  // Navigate to a site.
  orig_browser = NavigateHelper(GURL(chrome::kChromeUIVersionURL), browser(),
                                WindowOpenDisposition::CURRENT_TAB, true);

  // Open about for (not) finding later.
  NavigateHelper(GURL(chrome::kChromeUIAboutURL), orig_browser,
                 WindowOpenDisposition::NEW_FOREGROUND_TAB, true);

  // Also open settings for finding later.
  NavigateHelper(GURL(chrome::kChromeUISettingsURL), orig_browser,
                 WindowOpenDisposition::NEW_FOREGROUND_TAB, false);

  EXPECT_EQ(3, browser()->tab_strip_model()->count());

  Browser* test_browser;

  {
    Browser* incognito_browser = CreateIncognitoBrowser();

    test_browser =
        NavigateHelper(GURL(chrome::kChromeUIDownloadsURL), incognito_browser,
                       WindowOpenDisposition::OFF_THE_RECORD, true);
    // Sanity check where OTR tab landed.
    EXPECT_EQ(incognito_browser, test_browser);

    // Sanity check that browser() always returns original.
    EXPECT_EQ(orig_browser, browser());

    // Open about singleton. Should not find in regular browser and
    // open locally.
    test_browser =
        NavigateHelper(GURL(chrome::kChromeUIAboutURL), incognito_browser,
                       WindowOpenDisposition::SINGLETON_TAB, true);
    EXPECT_NE(orig_browser, test_browser);

    // Open settings. Should switch to non-incognito profile to do so.
    test_browser =
        NavigateHelper(GURL(chrome::kChromeUISettingsURL), incognito_browser,
                       WindowOpenDisposition::SINGLETON_TAB, false);
    EXPECT_EQ(orig_browser, test_browser);
  }

  // Open downloads singleton. Should not search OTR browser and
  // should open in regular browser.
  test_browser =
      NavigateHelper(GURL(chrome::kChromeUIDownloadsURL), orig_browser,
                     WindowOpenDisposition::SINGLETON_TAB, true);
  EXPECT_EQ(browser(), test_browser);
}

// Tests that a disposition of SWITCH_TAB cannot see across anonymity,
// except for certain non-incognito affinity URLs (e.g. settings).
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SwitchToTabIncognitoLeak) {
  Browser* orig_browser;

  // Navigate to a site.
  orig_browser = NavigateHelper(GURL(chrome::kChromeUIVersionURL), browser(),
                                WindowOpenDisposition::CURRENT_TAB, true);

  // Also open settings for finding later.
  NavigateHelper(GURL(chrome::kChromeUISettingsURL), orig_browser,
                 WindowOpenDisposition::NEW_FOREGROUND_TAB, false);

  // Also open about for searching too.
  NavigateHelper(GURL(chrome::kChromeUIAboutURL), orig_browser,
                 WindowOpenDisposition::NEW_FOREGROUND_TAB, true);

  EXPECT_EQ(3, browser()->tab_strip_model()->count());

  Browser* test_browser;

  {
    Browser* incognito_browser = CreateIncognitoBrowser();

    test_browser =
        NavigateHelper(GURL(chrome::kChromeUIDownloadsURL), incognito_browser,
                       WindowOpenDisposition::OFF_THE_RECORD, true);
    // Sanity check where OTR tab landed.
    EXPECT_EQ(incognito_browser, test_browser);

    // Sanity check that browser() always returns original.
    EXPECT_EQ(orig_browser, browser());

    // Try to open the original chrome://about via switch-to-tab. Should not
    // find copy in regular browser, and open new tab in incognito.
    test_browser =
        NavigateHelper(GURL(chrome::kChromeUIAboutURL), incognito_browser,
                       WindowOpenDisposition::SWITCH_TO_TAB, true);
    EXPECT_EQ(incognito_browser, test_browser);

    // Open settings. Should switch to non-incognito profile to do so.
    test_browser =
        NavigateHelper(GURL(chrome::kChromeUISettingsURL), incognito_browser,
                       WindowOpenDisposition::SWITCH_TO_TAB, false);
    EXPECT_EQ(orig_browser, test_browser);
  }

  // Switch-to-tab shouldn't find the incognito tab, and open new one in
  // current browser.
  test_browser =
      NavigateHelper(GURL(chrome::kChromeUIDownloadsURL), orig_browser,
                     WindowOpenDisposition::SWITCH_TO_TAB, true);
  EXPECT_EQ(browser(), test_browser);
}

#if BUILDFLAG(IS_MAC) && defined(ADDRESS_SANITIZER)
// Flaky on ASAN on Mac. See https://crbug.com/674497.
#define MAYBE_Disposition_Incognito DISABLED_Disposition_Incognito
#else
#define MAYBE_Disposition_Incognito Disposition_Incognito
#endif
// This test verifies that navigating with WindowOpenDisposition = INCOGNITO
// opens a new incognito window if no existing incognito window is present.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, MAYBE_Disposition_Incognito) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::OFF_THE_RECORD;
  Navigate(&params);

  // Navigate() should have opened a new toplevel incognito window.
  EXPECT_NE(browser(), params.browser);
  EXPECT_EQ(
      browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true),
      params.browser->GetProfile());

  // |source_contents| should be set to NULL because the profile for the new
  // page is different from the originating page.
  EXPECT_FALSE(params.source_contents);

  // We should now have two windows, the browser() provided by the framework and
  // the new incognito window.
  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(
      1,
      params.browser->GetBrowserForMigrationOnly()->tab_strip_model()->count());
}

// This test verifies that navigating with WindowOpenDisposition = INCOGNITO
// reuses an existing incognito window when possible.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_IncognitoRefocus) {
  Browser* incognito_browser = CreateEmptyBrowserForType(
      Browser::TYPE_NORMAL,
      browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true));
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::OFF_THE_RECORD;
  Navigate(&params);

  // Navigate() should have opened a new tab in the existing incognito window.
  EXPECT_NE(browser(), params.browser);
  EXPECT_EQ(params.browser, incognito_browser);

  // We should now have two windows, the browser() provided by the framework and
  // the incognito window we opened earlier.
  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(2, incognito_browser->tab_strip_model()->count());
}

// This test verifies that no navigation action occurs when
// WindowOpenDisposition = SAVE_TO_DISK.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_SaveToDisk) {
  RunSuppressTest(WindowOpenDisposition::SAVE_TO_DISK);
}

// This test verifies that no navigation action occurs when
// WindowOpenDisposition = IGNORE_ACTION.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_IgnoreAction) {
  RunSuppressTest(WindowOpenDisposition::IGNORE_ACTION);
}

// This tests adding a foreground tab with a predefined WebContents.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, TargetContents_ForegroundTab) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  params.contents_to_insert = CreateWebContents(false);
  Navigate(&params);

  // Navigate() should have opened the contents in a new foreground tab in the
  // current Browser.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
            params.navigated_or_inserted_contents);

  // We should have one window, with two tabs.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
}

#if BUILDFLAG(IS_WIN)
// This tests adding a popup with a predefined WebContents.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, DISABLED_TargetContents_Popup) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_POPUP;
  params.contents_to_insert = CreateWebContents(false);
  params.window_features.bounds = gfx::Rect(10, 10, 500, 500);
  Navigate(&params);

  // Navigate() should have opened a new popup window.
  EXPECT_NE(browser(), params.browser);
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()->is_type_popup());
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()
                  ->window()
                  ->IsToolbarVisible());

  // The web platform is weird. The window bounds specified in
  // `params.window_features.bounds` are used as follows:
  // - the origin is used to position the window
  // - the size is used to size the WebContents of the window.
  // As such the position of the resulting window will always match
  // `params.window_features.bounds.origin()`, but its size will not. We need to
  // match the size against the selected tab's view's container size.
  // Only Windows positions the window according to
  // `params.window_features.bounds.origin()` - on Mac the window is offset from
  // the opener and on Linux it always opens at 0,0.
  EXPECT_EQ(params.window_features.bounds.origin(),
            params.browser->GetWindow()->GetRestoredBounds().origin());
  // All platforms should respect size however provided width > 400 (Mac has a
  // minimum window width of 400).
  EXPECT_EQ(params.window_features.bounds.size(),
            params.navigated_or_inserted_contents->GetContainerBounds().size());

  // We should have two windows, the new popup and the browser() provided by the
  // framework.
  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(
      1,
      params.browser->GetBrowserForMigrationOnly()->tab_strip_model()->count());
}
#endif

// This test checks that we can create WebContents with renderer process and
// RenderFrame without navigating it.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       CreateWebContentsWithRendererProcess) {
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  params.contents_to_insert = CreateWebContents(true);
  ASSERT_TRUE(params.contents_to_insert);

  // There is no navigation (to about:blank or something like that).
  EXPECT_FALSE(params.contents_to_insert->IsLoading());

  ASSERT_TRUE(params.contents_to_insert->GetPrimaryMainFrame());
  EXPECT_TRUE(
      params.contents_to_insert->GetPrimaryMainFrame()->IsRenderFrameLive());
  EXPECT_TRUE(
      params.contents_to_insert->GetController().IsInitialBlankNavigation());
  int renderer_id = params.contents_to_insert->GetPrimaryMainFrame()
                        ->GetProcess()
                        ->GetDeprecatedID();

  // We should have one window, with one tab of WebContents differ from
  // params.target_contents.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_NE(browser()->tab_strip_model()->GetActiveWebContents(),
            params.contents_to_insert.get());

  Navigate(&params);

  // Navigate() should have opened the contents in a new foreground tab in the
  // current Browser, without changing the renderer process of target_contents.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
            params.navigated_or_inserted_contents);
  EXPECT_EQ(renderer_id,
            params.navigated_or_inserted_contents->GetPrimaryMainFrame()
                ->GetProcess()
                ->GetDeprecatedID());

  // We should have one window, with two tabs.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
}

// This tests adding a tab at a specific index.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Tabstrip_InsertAtIndex) {
  // This is not meant to be a comprehensive test of whether or not the tab
  // implementation of the browser observes the insertion index. That is
  // covered by the unit tests for TabStripModel. This merely verifies that
  // insertion index preference is reflected in common cases.
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  params.tabstrip_index = 0;
  params.tabstrip_add_types = AddTabTypes::ADD_FORCE_INDEX;
  Navigate(&params);

  // Navigate() should have inserted a new tab at slot 0 in the tabstrip.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(0, browser()->tab_strip_model()->GetIndexOfWebContents(
                   static_cast<const WebContents*>(
                       params.navigated_or_inserted_contents)));

  // We should have one window - the browser() provided by the framework.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
}

// This test verifies that constructing params with disposition = SINGLETON_TAB
// and IGNORE_AND_NAVIGATE opens a new tab navigated to the specified URL if
// no previous tab with that URL (minus the path) exists.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_SingletonTabNew_IgnorePath) {
  chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
                                ui::PAGE_TRANSITION_LINK);

  // We should have one browser with 2 tabs, the 2nd selected.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());

  // Navigate to a new singleton tab with a sub-page.
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = GetContentSettingsURL();
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
  Navigate(&params);

  // The last tab should now be selected and navigated to the sub-page of the
  // URL.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(3, browser()->tab_strip_model()->count());
  EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
  EXPECT_EQ(GetContentSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// This test verifies that constructing params with disposition = SINGLETON_TAB
// and IGNORE_AND_NAVIGATE opens an existing tab with the matching URL (minus
// the path) which is navigated to the specified URL.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_SingletonTabExisting_IgnorePath) {
  const GURL singleton_url(GetSettingsURL());
  chrome::AddSelectedTabWithURL(browser(), singleton_url,
                                ui::PAGE_TRANSITION_LINK);
  chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
                                ui::PAGE_TRANSITION_LINK);

  // We should have one browser with 3 tabs, the 3rd selected.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(3, browser()->tab_strip_model()->count());
  EXPECT_EQ(2, browser()->tab_strip_model()->active_index());

  // Navigate to |singleton_url|.
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = GetContentSettingsURL();
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
  Navigate(&params);

  // The middle tab should now be selected and navigated to the sub-page of the
  // URL.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(3, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
  EXPECT_EQ(GetContentSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// This test verifies that constructing params with disposition = SINGLETON_TAB
// and IGNORE_AND_NAVIGATE opens an existing tab with the matching URL (minus
// the path) which is navigated to the specified URL.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_SingletonTabExistingSubPath_IgnorePath) {
  const GURL singleton_url(GetContentSettingsURL());
  chrome::AddSelectedTabWithURL(browser(), singleton_url,
                                ui::PAGE_TRANSITION_LINK);
  chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
                                ui::PAGE_TRANSITION_LINK);

  // We should have one browser with 3 tabs, the 3rd selected.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(3, browser()->tab_strip_model()->count());
  EXPECT_EQ(2, browser()->tab_strip_model()->active_index());

  // Navigate to |singleton_url|.
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = GetClearBrowsingDataURL();
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
  Navigate(&params);

  // The middle tab should now be selected and navigated to the sub-page of the
  // URL.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(3, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
  EXPECT_EQ(GetClearBrowsingDataURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// This test verifies that constructing params with disposition = SINGLETON_TAB
// and IGNORE_AND_NAVIGATE will update the current tab's URL if the currently
// selected tab is a match but has a different path.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_SingletonTabFocused_IgnorePath) {
  const GURL singleton_url_current(GetContentSettingsURL());
  chrome::AddSelectedTabWithURL(browser(), singleton_url_current,
                                ui::PAGE_TRANSITION_LINK);

  // We should have one browser with 2 tabs, the 2nd selected.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());

  // Navigate to a different settings path.
  const GURL singleton_url_target(GetClearBrowsingDataURL());
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = singleton_url_target;
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
  Navigate(&params);

  // The second tab should still be selected, but navigated to the new path.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
  EXPECT_EQ(singleton_url_target,
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// This test verifies that constructing params with disposition = SINGLETON_TAB
// and IGNORE_AND_NAVIGATE will open an existing matching tab with a different
// query.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_SingletonTabExisting_IgnoreQuery) {
  int initial_tab_count = browser()->tab_strip_model()->count();
  const GURL singleton_url_current(GetContentSettingsURL());
  chrome::AddSelectedTabWithURL(browser(), singleton_url_current,
                                ui::PAGE_TRANSITION_LINK);

  EXPECT_EQ(initial_tab_count + 1, browser()->tab_strip_model()->count());
  EXPECT_EQ(initial_tab_count, browser()->tab_strip_model()->active_index());

  // Navigate to a different settings path.
  const GURL singleton_url_target(GetClearBrowsingDataURL());
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = singleton_url_target;
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
  Navigate(&params);

  // Last tab should still be selected.
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(initial_tab_count + 1, browser()->tab_strip_model()->count());
  EXPECT_EQ(initial_tab_count, browser()->tab_strip_model()->active_index());
}

// This test verifies that the settings page isn't opened in the incognito
// window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_Settings_UseNonIncognitoWindow) {
  RunUseNonIncognitoWindowTest(
      GetSettingsURL(), ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK);
}

// This test verifies that the view-source settings page isn't opened in the
// incognito window.
IN_PROC_BROWSER_TEST_F(
    BrowserNavigatorTest,
    Disposition_ViewSource_Settings_DoNothingIfIncognitoForced) {
  std::string view_source(content::kViewSourceScheme);
  view_source.append(":");
  view_source.append(chrome::kChromeUISettingsURL);
  RunDoNothingIfIncognitoIsForcedTest(GURL(view_source));
}

// This test verifies that the view-source settings page isn't opened in the
// incognito window even if incognito mode is forced (does nothing in that
// case).
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_ViewSource_Settings_UseNonIncognitoWindow) {
  std::string view_source(content::kViewSourceScheme);
  view_source.append(":");
  view_source.append(chrome::kChromeUISettingsURL);
  RunUseNonIncognitoWindowTest(
      GURL(view_source), ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK);
}

// This test verifies that the settings page isn't opened in the incognito
// window from a non-incognito window (bookmark open-in-incognito trigger).
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_Settings_UseNonIncognitoWindowForBookmark) {
  NavigateParams params(browser(), GetSettingsURL(),
                        ui::PAGE_TRANSITION_AUTO_BOOKMARK);
  params.disposition = WindowOpenDisposition::OFF_THE_RECORD;
  {
    content::CreateAndLoadWebContentsObserver observer;
    Navigate(&params);
    observer.Wait();
  }

  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(GetSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// Settings page is expected to always open in normal mode regardless
// of whether the user is trying to open it in incognito mode or not.
// This test verifies that if incognito mode is forced (by policy), settings
// page doesn't open at all.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_Settings_DoNothingIfIncognitoIsForced) {
  RunDoNothingIfIncognitoIsForcedTest(GetSettingsURL());
}

// This test verifies that the bookmarks page can open in incognito windows.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_Bookmarks_UseIncognitoWindow) {
  Browser* const incognito_browser = CreateIncognitoBrowser();
  TabStripModel* const incognito_tab_strip_model =
      incognito_browser->tab_strip_model();

  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, incognito_tab_strip_model->count());

  // Navigate to the page.
  const GURL bookmarks_page = GURL(chrome::kChromeUIBookmarksURL);
  NavigateParams params(MakeNavigateParams(incognito_browser));
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = bookmarks_page;
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  params.transition = ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK;
  Navigate(&params);

  // This page should be opened in browser() window.
  EXPECT_EQ(incognito_browser, params.browser);
  EXPECT_NE(browser(), params.browser);
  EXPECT_EQ(2, incognito_tab_strip_model->count());
  EXPECT_EQ(bookmarks_page,
            incognito_tab_strip_model->GetActiveWebContents()->GetURL());
}

// This test makes sure a crashed singleton tab reloads from a new navigation.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, NavigateToCrashedSingletonTab) {
  const GURL singleton_url(GetContentSettingsURL());
  WebContents* web_contents = chrome::AddSelectedTabWithURL(
      browser(), singleton_url, ui::PAGE_TRANSITION_LINK);

  // We should have one browser with 2 tabs, the 2nd selected.
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());

  // Kill the singleton tab.
  {
    content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;

    content::RenderFrameDeletedObserver crash_observer(
        web_contents->GetPrimaryMainFrame());
    web_contents->GetPrimaryMainFrame()->GetProcess()->Shutdown(1);
    crash_observer.WaitUntilDeleted();
  }
  EXPECT_TRUE(web_contents->IsCrashed());

  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = singleton_url;
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
  ui_test_utils::NavigateToURL(&params);

  // The tab should not be sad anymore.
  EXPECT_FALSE(web_contents->IsCrashed());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromDefaultToOptionsInSameTab) {
  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    ShowSettings(browser());
    observer.Wait();
  }
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(GetSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// TODO(crbug.com/40107334): Timing out on linux-chromeos-dbg.
#if BUILDFLAG(IS_CHROMEOS)
#define MAYBE_NavigateFromBlankToOptionsInSameTab \
  DISABLED_NavigateFromBlankToOptionsInSameTab
#else
#define MAYBE_NavigateFromBlankToOptionsInSameTab \
  NavigateFromBlankToOptionsInSameTab
#endif
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       MAYBE_NavigateFromBlankToOptionsInSameTab) {
  NavigateParams params(MakeNavigateParams());
  params.url = GURL(url::kAboutBlankURL);
  ui_test_utils::NavigateToURL(&params);

  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    ShowSettings(browser());
    observer.Wait();
  }
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(GetSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// TODO(crbug.com/40107334): Timing out on linux-chromeos-dbg.
#if BUILDFLAG(IS_CHROMEOS)
#define MAYBE_NavigateFromNTPToOptionsInSameTab \
  DISABLED_NavigateFromNTPToOptionsInSameTab
#else
#define MAYBE_NavigateFromNTPToOptionsInSameTab \
  NavigateFromNTPToOptionsInSameTab
#endif
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       MAYBE_NavigateFromNTPToOptionsInSameTab) {
  NavigateParams params(MakeNavigateParams());
  params.url = GURL(chrome::kChromeUINewTabURL);
  ui_test_utils::NavigateToURL(&params);
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(ntp_test_utils::GetFinalNtpUrl(browser()->profile()),
            browser()
                ->tab_strip_model()
                ->GetActiveWebContents()
                ->GetLastCommittedURL());

  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    ShowSettings(browser());
    observer.Wait();
  }
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(GetSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromPageToOptionsInNewTab) {
  NavigateParams params(MakeNavigateParams());
  ui_test_utils::NavigateToURL(&params);
  EXPECT_EQ(GetGoogleURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());

  {
    content::CreateAndLoadWebContentsObserver observer;
    ShowSettings(browser());
    observer.Wait();
  }
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(GetSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromNTPToOptionsSingleton) {
  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    ShowSettings(browser());
    observer.Wait();
  }
  EXPECT_EQ(1, browser()->tab_strip_model()->count());

  chrome::NewTab(browser());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    ShowSettings(browser());
    observer.Wait();
  }
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(GetSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// TODO(crbug.com/40166082): This is disabled for Mac OS due to flakiness.
// TODO(crbug.com/40107334): Timing out on linux-chromeos-dbg.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
#define MAYBE_NavigateFromNTPToOptionsPageInSameTab \
  DISABLED_NavigateFromNTPToOptionsPageInSameTab
#else
#define MAYBE_NavigateFromNTPToOptionsPageInSameTab \
  NavigateFromNTPToOptionsPageInSameTab
#endif
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       MAYBE_NavigateFromNTPToOptionsPageInSameTab) {
  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    chrome::ShowSettingsSubPageInTabbedBrowser(
        browser(), chrome::kClearBrowserDataSubPage);
    observer.Wait();
  }
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(GetClearBrowsingDataURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());

  chrome::NewTab(browser());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    chrome::ShowSettingsSubPageInTabbedBrowser(
        browser(), chrome::kClearBrowserDataSubPage);
    observer.Wait();
  }
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(GetClearBrowsingDataURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromPageInfoToSiteSettingsInNewTab) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ChromePageInfoDelegate delegate(web_contents);
  delegate.ShowSiteSettings(web_contents->GetVisibleURL());
  content::LoadStopObserver observer(
      browser()->tab_strip_model()->GetActiveWebContents());
  observer.Wait();

  // Site settings opens in a new tab.
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(chrome::GetSettingsUrl(chrome::kContentSettingsSubPage),
            browser()
                ->tab_strip_model()
                ->GetActiveWebContents()
                ->GetLastCommittedURL());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromPageInfoToSiteSettingsFileSystemInNewTab) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ChromePageInfoDelegate delegate(web_contents);
  delegate.OpenContentSettingsExceptions(
      ContentSettingsType::FILE_SYSTEM_WRITE_GUARD);
  content::LoadStopObserver observer(
      browser()->tab_strip_model()->GetActiveWebContents());
  observer.Wait();

  // File system site settings opens in a new tab.
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(chrome::GetSettingsUrl(chrome::kFileSystemSettingsSubpage),
            browser()
                ->tab_strip_model()
                ->GetActiveWebContents()
                ->GetLastCommittedURL());
}
#endif

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromOtherTabToSingletonOptions) {
  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    ShowSettings(browser());
    observer.Wait();
  }
  {
    content::CreateAndLoadWebContentsObserver observer;
    chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
                                  ui::PAGE_TRANSITION_LINK);
    observer.Wait();
  }

  // This load should simply cause a tab switch.
  ShowSettings(browser());

  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(GetSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromNoTabStripWindowToOptions) {
  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    ShowSettings(browser());
    observer.Wait();
  }
  {
    content::CreateAndLoadWebContentsObserver observer;
    chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
                                  ui::PAGE_TRANSITION_LINK);
    observer.Wait();
  }
  Browser* app_browser = CreateBrowserForApp("TestApp", browser()->profile());

  // This load should cause a window and tab switch.
  ShowSingletonTab(app_browser, GetSettingsURL());

  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(GetSettingsURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

// TODO(crbug.com/40107334): Timing out on linux-chromeos-dbg.
#if BUILDFLAG(IS_CHROMEOS)
#define MAYBE_CloseSingletonTab DISABLED_CloseSingletonTab
#else
#define MAYBE_CloseSingletonTab CloseSingletonTab
#endif
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, MAYBE_CloseSingletonTab) {
  for (int i = 0; i < 2; ++i) {
    content::CreateAndLoadWebContentsObserver observer;
    chrome::AddSelectedTabWithURL(browser(), GetGoogleURL(),
                                  ui::PAGE_TRANSITION_TYPED);
    observer.Wait();
  }

  browser()->tab_strip_model()->ActivateTabAt(
      0, TabStripUserGestureDetails(
             TabStripUserGestureDetails::GestureType::kOther));

  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    ShowSettings(browser());
    observer.Wait();
  }

  int previous_tab_count = browser()->tab_strip_model()->count();
  browser()->tab_strip_model()->CloseWebContentsAt(
      2, TabCloseTypes::CLOSE_USER_GESTURE);
  EXPECT_EQ(previous_tab_count - 1, browser()->tab_strip_model()->count());
  EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromDefaultToHistoryInSameTab) {
  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    chrome::ShowHistory(browser());
    observer.Wait();
  }
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(GURL(chrome::kChromeUIHistoryURL),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromDefaultToTabsFromOtherDevicesInSameTab) {
  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    chrome::ShowHistorySubPage(browser(), chrome::kChromeUIHistorySyncedTabs);
    observer.Wait();
  }
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(GURL(chrome::kChromeUIHistoryURL)
                .Resolve(chrome::kChromeUIHistorySyncedTabs),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromDefaultToBookmarksInSameTab) {
  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    chrome::ShowBookmarkManager(browser());
    observer.Wait();
  }
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_TRUE(base::StartsWith(
      browser()->tab_strip_model()->GetActiveWebContents()->GetURL().spec(),
      chrome::kChromeUIBookmarksURL, base::CompareCase::SENSITIVE));
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateFromDefaultToDownloadsInSameTab) {
  {
    content::LoadStopObserver observer(
        browser()->tab_strip_model()->GetActiveWebContents());
    chrome::ShowDownloads(browser());
    observer.Wait();
  }
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(GURL(chrome::kChromeUIDownloadsURL),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, NavigateWithoutBrowser) {
  // First navigate using the profile of the existing browser window, and
  // check that the window is reused.
  NavigateParams params(browser()->profile(), GetGoogleURL(),
                        ui::PAGE_TRANSITION_LINK);
  ui_test_utils::NavigateToURL(&params);
  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());

  // Now navigate using the incognito profile and check that a new window
  // is created.
  NavigateParams params_incognito(
      browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true),
      GetGoogleURL(), ui::PAGE_TRANSITION_LINK);
  ui_test_utils::NavigateToURL(&params_incognito);
  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, ViewSourceIsntSingleton) {
  const std::string viewsource_ntp_url =
      std::string(content::kViewSourceScheme) + ":" +
      chrome::kChromeUIVersionURL;

  NavigateParams viewsource_params(browser(), GURL(viewsource_ntp_url),
                                   ui::PAGE_TRANSITION_LINK);
  ui_test_utils::NavigateToURL(&viewsource_params);

  NavigateParams singleton_params(browser(), GURL(chrome::kChromeUIVersionURL),
                                  ui::PAGE_TRANSITION_LINK);
  singleton_params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  EXPECT_EQ(-1, GetIndexOfExistingTab(browser(), singleton_params));
}

// Ensure that an incognito window invoking |view-source:| on a url forbidden in
// incognito loads the correct url in the non-incognito window.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, ViewSourceUrlMatching) {
  // Open chrome://settings in the main window.
  NavigateParams settings_params(browser(), GURL(chrome::kChromeUISettingsURL),
                                 ui::PAGE_TRANSITION_LINK);
  ui_test_utils::NavigateToURL(&settings_params);

  // Create a new incognito window.
  Browser* incognito_browser = CreateIncognitoBrowser();
  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  EXPECT_EQ(1, incognito_browser->tab_strip_model()->count());

  // In the Incognito window, start a navigation to the view-source page.
  const std::string viewsource_settings_url =
      std::string(content::kViewSourceScheme) + ":" +
      chrome::kChromeUISettingsURL;
  NavigateParams params(MakeNavigateParams(incognito_browser));
  params.disposition = WindowOpenDisposition::SINGLETON_TAB;
  params.url = GURL(viewsource_settings_url);
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  params.transition = ui::PAGE_TRANSITION_AUTO_BOOKMARK;
  Navigate(&params);

  // The view-source page should be opened as a new tab in the non-incognito
  // browser window.
  EXPECT_NE(incognito_browser, params.browser);
  EXPECT_EQ(browser(), params.browser);
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(viewsource_settings_url,
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
}

enum class SplitCacheTestCase {
  kEnabledTripleKeyed,
  kEnabledTriplePlusCrossSiteMainFrameNavBool,
};
const struct {
  const SplitCacheTestCase test_case;
  base::test::FeatureRef feature;
} kTestCaseToFeatureMapping[] = {
    {SplitCacheTestCase::kEnabledTriplePlusCrossSiteMainFrameNavBool,
     net::features::kSplitCacheByCrossSiteMainFrameNavigationBoolean}};

class BrowserNavigatorSplitHttpCacheTest
    : public BrowserNavigatorTest,
      public testing::WithParamInterface<SplitCacheTestCase> {
 protected:
  BrowserNavigatorSplitHttpCacheTest()
      : split_cache_experiment_feature_list_(GetParam(),
                                             kTestCaseToFeatureMapping) {
    split_cache_always_enabled_feature_list_.InitAndEnableFeature(
        net::features::kSplitCacheByNetworkIsolationKey);
  }

 private:
  net::test::ScopedMutuallyExclusiveFeatureList
      split_cache_experiment_feature_list_;
  base::test::ScopedFeatureList split_cache_always_enabled_feature_list_;
};

INSTANTIATE_TEST_SUITE_P(
    All,
    BrowserNavigatorSplitHttpCacheTest,
    testing::ValuesIn(
        {SplitCacheTestCase::kEnabledTripleKeyed,
         SplitCacheTestCase::kEnabledTriplePlusCrossSiteMainFrameNavBool}),
    [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
      switch (info.param) {
        case (SplitCacheTestCase::kEnabledTripleKeyed):
          return "TripleKeyed";
        case (SplitCacheTestCase::kEnabledTriplePlusCrossSiteMainFrameNavBool):
          return "TriplePlusCrossSiteMainFrameNavigationBool";
      }
    });

// This test verifies that browser initiated navigations can send requests
// using POST.
IN_PROC_BROWSER_TEST_P(BrowserNavigatorSplitHttpCacheTest,
                       SendBrowserInitiatedRequestUsingPOST) {
  // Uses a test sever to verify POST request.
  ASSERT_TRUE(embedded_test_server()->Start());

  // Open a browser initiated POST request in new foreground tab.
  std::u16string expected_title(kExpectedTitle16);
  std::string post_data = kExpectedTitle;
  std::u16string title;
  ASSERT_TRUE(OpenPOSTURLInNewForegroundTabAndGetTitle(
      embedded_test_server()->GetURL(kEchoTitleCommand), post_data, true,
      &title));
  EXPECT_EQ(expected_title, title);
}

// This test verifies that renderer initiated navigations can also send requests
// using POST.
IN_PROC_BROWSER_TEST_P(BrowserNavigatorSplitHttpCacheTest,
                       SendRendererInitiatedRequestUsingPOST) {
  // Uses a test sever to verify POST request.
  ASSERT_TRUE(embedded_test_server()->Start());

  // Open a renderer initiated POST request in new foreground tab.
  std::u16string expected_title(kExpectedTitle16);
  std::string post_data = kExpectedTitle;
  std::u16string title;
  ASSERT_TRUE(OpenPOSTURLInNewForegroundTabAndGetTitle(
      embedded_test_server()->GetURL(kEchoTitleCommand), post_data, false,
      &title));
  EXPECT_EQ(expected_title, title);
}

// This test navigates to a data URL that contains BiDi control
// characters. For security reasons, BiDi control chars should always be
// escaped in the URL but they should be unescaped in the loaded HTML.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       NavigateToDataURLWithBiDiControlChars) {
  // Text in Arabic.
  std::string text = "\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1";
  // Page title starts with RTL mark.
  std::string unescaped_title = "\xE2\x80\x8F" + text;
  std::string data_url = "data:text/html;charset=utf-8,<html><title>" +
                         unescaped_title + "</title></html>";
  // BiDi control chars in URLs are always escaped, so the expected URL should
  // have the title with the escaped RTL mark.
  std::string escaped_title = "%E2%80%8F" + text;
  std::string expected_url = "data:text/html;charset=utf-8,<html><title>" +
                             escaped_title + "</title></html>";

  // Navigate to the page.
  NavigateParams params(MakeNavigateParams());
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  params.url = GURL(data_url);
  params.window_action = NavigateParams::WindowAction::kShowWindow;
  ui_test_utils::NavigateToURL(&params);

  std::u16string expected_title(base::UTF8ToUTF16(unescaped_title));
  EXPECT_TRUE(params.navigated_or_inserted_contents);
  EXPECT_EQ(expected_title, params.navigated_or_inserted_contents->GetTitle());
  // GURL always keeps non-ASCII characters escaped, but check them anyways.
  EXPECT_EQ(GURL(expected_url).spec(),
            params.navigated_or_inserted_contents->GetURL().spec());
  // Check the omnibox text. It should have escaped RTL with unescaped text.
  LocationBar* location_bar = browser()->window()->GetLocationBar();
  OmniboxView* omnibox_view = location_bar->GetOmniboxView();
  EXPECT_EQ(base::UTF8ToUTF16(expected_url), omnibox_view->GetText());
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_PictureInPicture_Open) {
  // Create the params for the PiP request.
  auto pip_options = blink::mojom::PictureInPictureWindowOptions::New();

  // The WebContents holds the parameters from the PiP request.
  WebContents::CreateParams web_contents_params(browser()->profile());
  web_contents_params.picture_in_picture_options = *pip_options;

  // Opening a picture in picture window should create a new browser.
  NavigateParams params = MakeNavigateParams(browser());
  params.disposition = WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;

  // Navigate to https:// page
  // TODO: Extract the navigation logic to a helper function?
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  ASSERT_TRUE(https_server.Start());
  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
  const GURL url = https_server.GetURL("/simple.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  params.source_contents = tab;
  params.contents_to_insert = WebContents::Create(web_contents_params);
  Navigate(&params);

  // Should not re-use the browser.
  EXPECT_NE(browser(), params.browser);
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()
                  ->is_type_picture_in_picture());
  EXPECT_EQ(params.browser->GetBrowserForMigrationOnly()->app_name(),
            std::string());

  // The window should have respected the initial aspect ratio.
  const gfx::Rect override_bounds =
      params.browser->GetBrowserForMigrationOnly()->override_bounds();
  const double aspect_ratio = static_cast<double>(override_bounds.width()) /
                              static_cast<double>(override_bounds.height());
  EXPECT_DOUBLE_EQ(1.0, aspect_ratio);
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_PictureInPicture_OpenWithWidthAndHeight) {
  // Set width/height with equivalent aspect ratio of 1.0.
  auto pip_options = blink::mojom::PictureInPictureWindowOptions::New();
  pip_options->width = 500;
  pip_options->height = 500;
  WebContents::CreateParams web_contents_params(browser()->profile());
  web_contents_params.picture_in_picture_options = *pip_options;

  // Opening a picture in picture window should create a new browser.
  NavigateParams params = MakeNavigateParams(browser());
  params.disposition = WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;

  // Navigate to https:// page
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  ASSERT_TRUE(https_server.Start());
  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
  const GURL url = https_server.GetURL("/simple.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  params.source_contents = tab;
  params.contents_to_insert = WebContents::Create(web_contents_params);
  Navigate(&params);

  // The bounds may have small adjustments for window decorations, since the
  // requested size is the inner size.  We can't get the inner size easily here,
  // so just verify that the aspect ratio is closer to 1.0 than 0.5.
  const gfx::Rect override_bounds =
      params.browser->GetBrowserForMigrationOnly()->override_bounds();
  float expected_aspect_ratio =
      static_cast<float>(override_bounds.width()) / override_bounds.height();
  EXPECT_NEAR(expected_aspect_ratio, 1.0f, 0.2);
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_PictureInPicture_CantFromAnotherPip) {
  // Make sure that attempting to open a picture in picture window from a
  // picture in picture window fails.
  Browser* pip = CreateEmptyBrowserForType(Browser::TYPE_PICTURE_IN_PICTURE,
                                           browser()->profile());
  NavigateParams params = MakeNavigateParams(pip);
  params.disposition = WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;

  // Navigate to https:// page
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  ASSERT_TRUE(https_server.Start());
  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
  const GURL url = https_server.GetURL("/simple.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  params.source_contents = tab;
  Navigate(&params);

  EXPECT_EQ(params.browser, nullptr);
}

IN_PROC_BROWSER_TEST_F(
    BrowserNavigatorTest,
    Disposition_PictureInPicture_CantWithoutASourceContents) {
  // Opening a picture-in-picture window without a source contents should fail.
  Browser* pip = CreateEmptyBrowserForType(Browser::TYPE_PICTURE_IN_PICTURE,
                                           browser()->profile());
  NavigateParams params = MakeNavigateParams(pip);
  params.disposition = WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;
  params.source_contents = nullptr;

  EXPECT_EQ(nullptr, Navigate(&params));
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_PictureInPicture_CantFromAboutBlank) {
  // Disallow document PiP windows from opening from a window with about:blank
  // in the omnibox
  Browser* pip = CreateEmptyBrowserForType(Browser::TYPE_PICTURE_IN_PICTURE,
                                           browser()->profile());
  NavigateParams params = MakeNavigateParams(pip);
  params.disposition = WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;

  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(tab->GetLastCommittedURL().IsAboutBlank());
  params.source_contents = tab;
  EXPECT_EQ(nullptr, Navigate(&params));
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       Disposition_PictureInPicture_OpenFromWebApp) {
  // Create the params for the PiP request that looks like it's from an app.
  auto pip_options = blink::mojom::PictureInPictureWindowOptions::New();

  // The WebContents holds the parameters from the PiP request.
  WebContents::CreateParams web_contents_params(browser()->profile());
  web_contents_params.picture_in_picture_options = *pip_options;

  // Opening a picture in picture window should create a new browser.
  NavigateParams params = MakeNavigateParams(browser());
  params.disposition = WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;
  params.app_id = "extensionappid";

  // Navigate to https:// page
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  ASSERT_TRUE(https_server.Start());
  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
  const GURL url = https_server.GetURL("/simple.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  params.source_contents = tab;
  params.contents_to_insert = WebContents::Create(web_contents_params);
  Navigate(&params);

  // Should be PiP, with an app name.
  EXPECT_TRUE(params.browser->GetBrowserForMigrationOnly()
                  ->is_type_picture_in_picture());
  EXPECT_NE(params.browser->GetBrowserForMigrationOnly()->app_name(),
            std::string());
}

// Test typical popin UX flow.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Popin) {
  // Setup server.
  embedded_https_test_server().SetSSLConfig(
      net::EmbeddedTestServer::CERT_TEST_NAMES);
  embedded_https_test_server().RegisterRequestHandler(
      base::BindRepeating(&PopinRequestHandler));
  ASSERT_TRUE(embedded_https_test_server().Start());

  // Navigate to a.test.
  const GURL url = embedded_https_test_server().GetURL("a.test", "/empty.html");
  content::WebContents* tab_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
  chrome::AddTabAt(browser(), GURL("about:blank"), -1, false);

  // Open popin and verify it's visible.
  content::WebContentsAddedObserver new_tab_observer;
  EXPECT_TRUE(content::ExecJs(
      tab_web_contents,
      "window.open('" + url.spec() + "?popin_policy=*', '_blank', 'popin')"));
  content::WebContents* popin_web_contents = new_tab_observer.GetWebContents();
  BrowserWindow* popin_browser_window =
      BrowserWindow::FindBrowserWindowWithWebContents(popin_web_contents);
  EXPECT_NE(popin_browser_window, browser()->window());
  EXPECT_TRUE(popin_browser_window->IsVisible());

  // Focus new tab and verify popin is hidden.
  browser()->tab_strip_model()->ActivateTabAt(1);
  EXPECT_FALSE(popin_browser_window->IsVisible());

  // Switch back to original tab and verify popin is visible.
  browser()->tab_strip_model()->ActivateTabAt(0);
  EXPECT_TRUE(popin_browser_window->IsVisible());
}

// Verify that a popin must not be insecure nor opened from an insecure context.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, PopinContext) {
  // Setup servers.
  embedded_https_test_server().SetSSLConfig(
      net::EmbeddedTestServer::CERT_TEST_NAMES);
  embedded_https_test_server().RegisterRequestHandler(
      base::BindRepeating(&PopinRequestHandler));
  ASSERT_TRUE(embedded_https_test_server().Start());
  ASSERT_TRUE(embedded_test_server()->Start());

  // Navigate to a.test.
  const GURL secure_url =
      embedded_https_test_server().GetURL("a.test", "/empty.html");
  const GURL insecure_url =
      embedded_test_server()->GetURL("a.test", "/empty.html");
  content::WebContents* tab_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Insecure context and insecure popin fails.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), insecure_url));
  auto result = content::ExecJs(tab_web_contents,
                                "window.open('" + insecure_url.spec() +
                                    "?popin_policy=*', '_blank', 'popin')");
  UNSAFE_TODO(EXPECT_TRUE(strstr(
      result.message(), "Partitioned popins must be opened from https URLs.")));

  // Secure context and insecure popin fails.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), secure_url));
  result = content::ExecJs(tab_web_contents,
                           "window.open('" + insecure_url.spec() +
                               "?popin_policy=*', '_blank', 'popin')");
  UNSAFE_TODO(EXPECT_TRUE(strstr(
      result.message(), "Partitioned popins can only open https URLs.")));

  // Insecure context and secure popin fails.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), insecure_url));
  result = content::ExecJs(tab_web_contents,
                           "window.open('" + secure_url.spec() +
                               "?popin_policy=*', '_blank', 'popin')");
  UNSAFE_TODO(EXPECT_TRUE(strstr(
      result.message(), "Partitioned popins must be opened from https URLs.")));

  // Secure context and secure popin succeeds.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), secure_url));
  EXPECT_TRUE(content::ExecJs(tab_web_contents,
                              "window.open('" + secure_url.spec() +
                                  "?popin_policy=*', '_blank', 'popin')"));
}

// Test that a popin cannot be opened from a popin
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, PopinRecursion) {
  // Setup server.
  embedded_https_test_server().SetSSLConfig(
      net::EmbeddedTestServer::CERT_TEST_NAMES);
  embedded_https_test_server().RegisterRequestHandler(
      base::BindRepeating(&PopinRequestHandler));
  ASSERT_TRUE(embedded_https_test_server().Start());

  // Navigate to a.test.
  const GURL url = embedded_https_test_server().GetURL("a.test", "/empty.html");
  content::WebContents* tab_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  // Open popin and verify it's visible.
  content::WebContentsAddedObserver new_tab_observer;
  EXPECT_TRUE(content::ExecJs(
      tab_web_contents,
      "window.open('" + url.spec() + "?popin_policy=*', '_blank', 'popin')"));
  content::WebContents* popin_web_contents = new_tab_observer.GetWebContents();
  BrowserWindow* popin_browser_window =
      BrowserWindow::FindBrowserWindowWithWebContents(popin_web_contents);
  EXPECT_NE(popin_browser_window, browser()->window());
  EXPECT_TRUE(popin_browser_window->IsVisible());

  // Opening a popin from a popin fails.
  const auto& result = content::ExecJs(
      popin_web_contents,
      "window.open('" + url.spec() + "?popin_policy=*', '_blank', 'popin')");
  UNSAFE_TODO(EXPECT_TRUE(strstr(
      result.message(), "Partitioned popins cannot open their own popin.")));
}

// Test only one popin can be opened by a given context.
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, PopinLimit) {
  // Setup server.
  embedded_https_test_server().SetSSLConfig(
      net::EmbeddedTestServer::CERT_TEST_NAMES);
  embedded_https_test_server().RegisterRequestHandler(
      base::BindRepeating(&PopinRequestHandler));
  ASSERT_TRUE(embedded_https_test_server().Start());

  // Navigate to a.test.
  const GURL url = embedded_https_test_server().GetURL("a.test", "/empty.html");
  content::WebContents* tab_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  // Open popin and succeed.
  content::WebContents* popin_web_contents;
  {
    content::WebContentsAddedObserver new_tab_observer;
    EXPECT_TRUE(content::ExecJs(
        tab_web_contents,
        "window.open('" + url.spec() + "?popin_policy=*', '_blank', 'popin')"));
    popin_web_contents = new_tab_observer.GetWebContents();
    EXPECT_TRUE(popin_web_contents);
  }

  // Try to open second popin and fail.
  content::WebContentsConsoleObserver console_observer(tab_web_contents);
  console_observer.SetPattern(
      "Only one partitioned popin can be active at a time.");
  EXPECT_FALSE(
      content::EvalJs(tab_web_contents,
                      "window.open('" + url.spec() +
                          "?popin_policy=*', '_blank', 'popin') != null")
          .ExtractBool());
  ASSERT_TRUE(console_observer.Wait());

  // Close first popin and verify second can be opened.
  BrowserWindow::FindBrowserWindowWithWebContents(popin_web_contents)->Close();
  EXPECT_TRUE(
      content::EvalJs(tab_web_contents,
                      "window.open('" + url.spec() +
                          "?popin_policy=*', '_blank', 'popin') != null")
          .ExtractBool());
}

// Test that a popin cannot navigate to an HTTP page
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, PopinHttpNavigation) {
  // Setup servers.
  embedded_https_test_server().SetSSLConfig(
      net::EmbeddedTestServer::CERT_TEST_NAMES);
  embedded_https_test_server().RegisterRequestHandler(
      base::BindRepeating(&PopinRequestHandler));
  ASSERT_TRUE(embedded_https_test_server().Start());
  embedded_test_server()->RegisterRequestHandler(
      base::BindRepeating(&PopinRequestHandler));
  ASSERT_TRUE(embedded_test_server()->Start());

  // Navigate to a.test.
  const GURL secure_url =
      embedded_https_test_server().GetURL("a.test", "/empty.html");
  const GURL insecure_url =
      embedded_test_server()->GetURL("a.test", "/empty.html");
  content::WebContents* tab_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), secure_url));

  // Open popin and verify it's visible.
  content::WebContentsAddedObserver new_tab_observer;
  EXPECT_TRUE(content::ExecJs(tab_web_contents,
                              "window.open('" + secure_url.spec() +
                                  "?popin_policy=*', '_blank', 'popin')"));
  content::WebContents* popin_web_contents = new_tab_observer.GetWebContents();
  BrowserWindow* popin_browser_window =
      BrowserWindow::FindBrowserWindowWithWebContents(popin_web_contents);
  EXPECT_NE(popin_browser_window, browser()->window());
  EXPECT_TRUE(popin_browser_window->IsVisible());

  // Navigating to HTTP page fails.
  content::TestNavigationObserver nav_observer(popin_web_contents);
  EXPECT_TRUE(content::ExecJs(
      popin_web_contents,
      "window.location = '" + insecure_url.spec() + "?popin_policy=*';"));
  nav_observer.Wait();
  EXPECT_EQ("chrome-error://chromewebdata/",
            content::EvalJs(popin_web_contents, "window.location.href")
                .ExtractString());
}

struct PopinPolicyTestParams {
  std::string description;
  std::string relative_url;
  bool policy_allows;
};

class BrowserNavigatorPopinPolicyTest
    : public BrowserNavigatorTest,
      public testing::WithParamInterface<
          std::tuple<PopinPolicyTestParams, PopinPolicyTestParams>> {
 public:
  PopinPolicyTestParams redirect_case() { return std::get<0>(GetParam()); }
  PopinPolicyTestParams target_case() { return std::get<1>(GetParam()); }
};

// Test that the HTTP response header `Popin-Policy` is respected.
IN_PROC_BROWSER_TEST_P(BrowserNavigatorPopinPolicyTest, PopinPolicy) {
  // Setup server.
  embedded_https_test_server().SetSSLConfig(
      net::EmbeddedTestServer::CERT_TEST_NAMES);
  embedded_https_test_server().RegisterRequestHandler(
      base::BindRepeating(&PopinRequestHandler));
  ASSERT_TRUE(embedded_https_test_server().Start());

  // Navigate to a.test.
  const GURL url = embedded_https_test_server().GetURL("a.test", "/empty.html");
  content::WebContents* tab_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  // Open the popin and ensure the target page only loads if both the redirect
  // and the target policy permit it.
  SCOPED_TRACE(redirect_case().description + " -> " +
               target_case().description);
  content::WebContentsAddedObserver new_tab_observer;
  content::TestNavigationObserver nav_observer(nullptr);
  nav_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(content::ExecJs(
      tab_web_contents, "window.open('" +
                            embedded_https_test_server()
                                .GetURL("a.test", redirect_case().relative_url)
                                .spec() +
                            embedded_https_test_server()
                                .GetURL("a.test", target_case().relative_url)
                                .spec() +
                            "', '_blank', 'popin')"));
  content::WebContents* popin_web_contents = new_tab_observer.GetWebContents();
  EXPECT_TRUE(popin_web_contents);
  nav_observer.Wait();
  EXPECT_EQ((redirect_case().policy_allows && target_case().policy_allows)
                ? "a.test"
                : "chromewebdata",
            content::EvalJs(popin_web_contents, "window.location.hostname")
                .ExtractString());
  BrowserWindow::FindBrowserWindowWithWebContents(popin_web_contents)->Close();
}

// Test all policy combinations.
INSTANTIATE_TEST_SUITE_P(
    /*no prefix*/,
    BrowserNavigatorPopinPolicyTest,
    testing::Combine(
        testing::ValuesIn(std::vector<PopinPolicyTestParams>{
            {
                "unset policy",
                "/empty.html?redirect=",
                /*policy_allows*/ false,
            },
            {
                "wildcard policy",
                "/empty.html?popin_policy=*&redirect=",
                /*policy_allows*/ true,
            },
            {
                "none policy",
                "/empty.html?popin_policy=()&redirect=",
                /*policy_allows*/ false,
            },
            {
                "origin a policy",
                "/empty.html?popin_policy=(\"https://a.test/\")&redirect=",
                /*policy_allows*/ true,
            },
            {
                "origin b policy",
                "/empty.html?popin_policy=(\"https://b.test/\")&redirect=",
                /*policy_allows*/ false,
            },
            {
                "origins policy",
                "/empty.html?popin_policy=(\"https://a.test/\" "
                "\"https://b.test/\")&redirect=",
                /*policy_allows*/ true,
            },
        }),
        testing::ValuesIn(std::vector<PopinPolicyTestParams>{
            {
                "unset policy",
                "/empty.html",
                /*policy_allows*/ false,
            },
            {
                "wildcard policy",
                "/empty.html?popin_policy=*",
                /*policy_allows*/ true,
            },
            {
                "none policy",
                "/empty.html?popin_policy=()",
                /*policy_allows*/ false,
            },
            {
                "origin a policy",
                "/empty.html?popin_policy=(\"https://a.test/\")",
                /*policy_allows*/ true,
            },
            {
                "origin b policy",
                "/empty.html?popin_policy=(\"https://b.test/\")",
                /*policy_allows*/ false,
            },
            {
                "origins policy",
                "/empty.html?popin_policy=(\"https://a.test/\" "
                "\"https://b.test/\")",
                /*policy_allows*/ true,
            },
        })));

class BrowserNavigatorPopinPolicyBypassTest
    : public BrowserNavigatorTest,
      public testing::WithParamInterface<bool> {
 public:
  BrowserNavigatorPopinPolicyBypassTest() {
    scoped_feature_list_.InitWithFeatureStates({
        {blink::features::kPartitionedPopins, true},
        {features::kPartitionedPopinsHeaderPolicyBypass,
         PartitionedPopinsHeaderPolicyBypass()},
        {content_settings::features::kTrackingProtection3pcd, true},
    });
  }
  bool PartitionedPopinsHeaderPolicyBypass() const { return GetParam(); }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// kPartitionedPopinsHeaderPolicyBypass allows `Popin-Policy` to be bypassed.
IN_PROC_BROWSER_TEST_P(BrowserNavigatorPopinPolicyBypassTest,
                       PopinPolicyBypass) {
  // Setup server.
  embedded_https_test_server().SetSSLConfig(
      net::EmbeddedTestServer::CERT_TEST_NAMES);
  ASSERT_TRUE(embedded_https_test_server().Start());

  // Navigate to a.test.
  const GURL url = embedded_https_test_server().GetURL("a.test", "/empty.html");
  content::WebContents* tab_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  // Open the popin to a page without the policy and see it succeed if the
  // feature was enabled.
  content::WebContentsAddedObserver new_tab_observer;
  content::TestNavigationObserver nav_observer(nullptr);
  nav_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(content::ExecJs(tab_web_contents, "window.open('" + url.spec() +
                                                    "', '_blank', 'popin')"));
  content::WebContents* popin_web_contents = new_tab_observer.GetWebContents();
  EXPECT_TRUE(popin_web_contents);
  nav_observer.Wait();
  EXPECT_EQ(PartitionedPopinsHeaderPolicyBypass() ? "a.test" : "chromewebdata",
            content::EvalJs(popin_web_contents, "window.location.hostname")
                .ExtractString());
  BrowserWindow::FindBrowserWindowWithWebContents(popin_web_contents)->Close();
}

// Test all policy combinations.
INSTANTIATE_TEST_SUITE_P(
    /*no prefix*/,
    BrowserNavigatorPopinPolicyBypassTest,
    testing::Bool());

// Test that a popin cannot navigate to an HTTP page
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, PopinHttpRedirectNavigation) {
  // Setup servers.
  embedded_https_test_server().SetSSLConfig(
      net::EmbeddedTestServer::CERT_TEST_NAMES);
  embedded_https_test_server().RegisterRequestHandler(
      base::BindRepeating(&PopinRequestHandler));
  ASSERT_TRUE(embedded_https_test_server().Start());
  ASSERT_TRUE(embedded_test_server()->Start());

  // Navigate to a.test.
  const GURL secure_url =
      embedded_https_test_server().GetURL("a.test", "/empty.html");
  const GURL insecure_url =
      embedded_test_server()->GetURL("a.test", "/empty.html");
  content::WebContents* tab_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), secure_url));

  // Open popin and verify it's visible.
  content::WebContentsAddedObserver new_tab_observer;
  EXPECT_TRUE(content::ExecJs(tab_web_contents,
                              "window.open('" + secure_url.spec() +
                                  "?popin_policy=*', '_blank', 'popin')"));
  content::WebContents* popin_web_contents = new_tab_observer.GetWebContents();
  BrowserWindow* popin_browser_window =
      BrowserWindow::FindBrowserWindowWithWebContents(popin_web_contents);
  EXPECT_NE(popin_browser_window, browser()->window());
  EXPECT_TRUE(popin_browser_window->IsVisible());

  // Navigating to HTTPS page that redirects to HTTP which fails.
  content::TestNavigationObserver nav_observer(popin_web_contents);
  EXPECT_TRUE(content::ExecJs(
      popin_web_contents,
      "window.location = '" + secure_url.spec() +
          "?popin_policy=*&redirect=" + insecure_url.spec() + "';"));
  nav_observer.Wait();
  EXPECT_EQ("chrome-error://chromewebdata/",
            content::EvalJs(popin_web_contents, "window.location.href")
                .ExtractString());
}

// Verify that a popin cannot access third-party cookies when opened from a
// cross-site context. This scenario was crashing before crrev.com/c/5845330
IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                       PopinFromCrossSiteContextAccessCookies) {
  // Setup server.
  embedded_https_test_server().SetSSLConfig(
      net::EmbeddedTestServer::CERT_TEST_NAMES);
  embedded_https_test_server().ServeFilesFromSourceDirectory(
      "content/test/data");
  ASSERT_TRUE(embedded_https_test_server().Start());

  // Navigate to a.test.
  const GURL url_a = embedded_https_test_server().GetURL(
      "a.test", "/partitioned_popins/iframe_allow_popins.html");
  content::WebContents* tab_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));

  // Set a cookie for a.test.
  const GURL url_a_root = embedded_https_test_server().GetURL("a.test", "/");
  ASSERT_TRUE(content::SetCookie(tab_web_contents->GetBrowserContext(),
                                 url_a_root,
                                 "site_a=cookie;SameSite=None;Secure"));

  // Navigate the iframe to b.test and set a cookie.
  const GURL url_b =
      embedded_https_test_server().GetURL("b.test", "/empty.html");
  ASSERT_TRUE(NavigateIframeToURL(tab_web_contents, "test", url_b));
  const GURL url_b_root = embedded_https_test_server().GetURL("b.test", "/");
  ASSERT_TRUE(
      content::SetCookie(tab_web_contents->GetBrowserContext(), url_b_root,
                         "site_b=cookie;Partitioned;SameSite=None;Secure"));

  // Open popin from the iframe and succeed.
  content::RenderFrameHost* iframe =
      ChildFrameAt(tab_web_contents->GetPrimaryMainFrame(), 0);
  ASSERT_TRUE(iframe);
  content::WebContentsAddedObserver new_tab_observer;
  content::TestNavigationObserver nav_observer(nullptr);
  nav_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(content::ExecJs(
      iframe, "window.open('" + url_a.spec() + "', '_blank', 'popin')"));
  content::WebContents* popin_web_contents = new_tab_observer.GetWebContents();
  EXPECT_TRUE(popin_web_contents);
  nav_observer.Wait();

  // Read cookies from the popin. No cookies should be visible.
  EXPECT_EQ(content::EvalJs(popin_web_contents, "document.cookie"), "");
}

#if !BUILDFLAG(IS_CHROMEOS)
// This class extends the basic logic in display::ScreenBase to allow us to mock
// the call to `GetDisplayNearestWindow`. This provides a way to ensure that the
// opener window is on a specific display, since the display::ScreenBase
// implementation only ever returns the primary display. This is not needed on
// Ash since Ash uses DisplayManagerTestApi.
class MockScreen : public display::ScreenBase {
 public:
  MockScreen() = default;
  MockScreen(const MockScreen&) = delete;
  const MockScreen& operator=(const MockScreen&) = delete;
  ~MockScreen() override { display::Screen::SetScreenInstance(nullptr); }

  void Init() { display::Screen::SetScreenInstance(this); }

  // display::ScreenBase:
  display::Display GetDisplayNearestWindow(
      gfx::NativeWindow window) const override {
    return display_nearest_window_.value_or(
        display::ScreenBase::GetDisplayNearestWindow(window));
  }

  void set_display_nearest_window(display::Display display) {
    display_nearest_window_ = display;
  }

 private:
  std::optional<display::Display> display_nearest_window_;
};
#endif  // !BUILDFLAG(IS_CHROMEOS)

// Windows has assumptions that the screen is a ScreenWin, which causes a crash
// when we inject the MockScreen.
#if BUILDFLAG(IS_WIN)
#define MAYBE_BrowserNavigatorTestWithMockScreen \
  DISABLED_BrowserNavigatorTestWithMockScreen
#else
#define MAYBE_BrowserNavigatorTestWithMockScreen \
  BrowserNavigatorTestWithMockScreen
#endif
class MAYBE_BrowserNavigatorTestWithMockScreen : public BrowserNavigatorTest {
 public:
  void SetScreenInstance() override {
#if BUILDFLAG(IS_CHROMEOS)
    // Use the default. See `SetUpOnMainThread`.
    BrowserNavigatorTest::SetScreenInstance();
#else
    mock_screen_.Init();
    mock_screen_.display_list().AddDisplay({1, gfx::Rect(0, 0, 800, 700)},
                                           display::DisplayList::Type::PRIMARY);
    mock_screen_.display_list().AddDisplay(
        {2, gfx::Rect(800, 0, 800, 700)},
        display::DisplayList::Type::NOT_PRIMARY);
    ASSERT_EQ(2, display::Screen::Get()->GetNumDisplays());
#endif  // BUILDFLAG(IS_CHROMEOS)
  }

  void SetUpOnMainThread() override {
#if BUILDFLAG(IS_CHROMEOS)
    // This has to happen later than `SetScreenInstance` as the Ash shell does
    // not exist yet.
    display::test::DisplayManagerTestApi(ash::Shell::Get()->display_manager())
        .UpdateDisplay("0+0-800x700,800+0-800x700");
    ASSERT_EQ(2, display::Screen::Get()->GetNumDisplays());
#endif  // BUILDFLAG(IS_CHROMEOS)
  }

#if !BUILDFLAG(IS_CHROMEOS)
 protected:
  MockScreen& mock_screen() { return mock_screen_; }

 private:
  MockScreen mock_screen_;
#endif  // !BUILDFLAG(IS_CHROMEOS)
};

IN_PROC_BROWSER_TEST_F(MAYBE_BrowserNavigatorTestWithMockScreen,
                       Disposition_PictureInPicture_OpensInSameDisplay) {
  // Create the params for the PiP request.
  auto pip_options = blink::mojom::PictureInPictureWindowOptions::New();
  pip_options->width = 500;
  pip_options->height = 400;
  WebContents::CreateParams web_contents_params(browser()->profile());
  web_contents_params.picture_in_picture_options = *pip_options;

  // Ensure we have the two displays.
  ASSERT_EQ(2, display::Screen::Get()->GetNumDisplays());
  auto display1 = display::Screen::Get()->GetAllDisplays()[0];
  auto display2 = display::Screen::Get()->GetAllDisplays()[1];

  {
#if BUILDFLAG(IS_CHROMEOS)
    // Put the opener on display 1.
    browser()->window()->SetBounds(display1.work_area());
#else
    // Make the MockScreen report the opener as being on display 1.
    mock_screen().set_display_nearest_window(display1);
#endif  // BUILDFLAG(IS_CHROMEOS)

    // Ensure that the opener is on display 1.
    const auto opener_display = display::Screen::Get()->GetDisplayNearestWindow(
        browser()->window()->GetNativeWindow());
    ASSERT_EQ(display1.id(), opener_display.id());

    // Open the PiP window.
    NavigateParams params = MakeNavigateParams(browser());
    params.disposition = WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;

    // Navigate to https:// page
    net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
    ASSERT_TRUE(https_server.Start());
    WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
    const GURL url = https_server.GetURL("/simple.html");
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

    params.source_contents = tab;
    params.contents_to_insert = WebContents::Create(web_contents_params);
    Navigate(&params);

    // The PiP window should also be on display 1.
    EXPECT_TRUE(display1.work_area().Contains(
        params.browser->GetWindow()->GetBounds()));
  }

  {
#if BUILDFLAG(IS_CHROMEOS)
    // Put the opener on display 2.
    browser()->window()->SetBounds(display2.work_area());
#else
    // Make the MockScreen report the opener as being on display 2.
    mock_screen().set_display_nearest_window(display2);
#endif  // BUILDFLAG(IS_CHROMEOS)

    // Ensure that the opener is on display 2.
    const auto opener_display = display::Screen::Get()->GetDisplayNearestWindow(
        browser()->window()->GetNativeWindow());
    ASSERT_EQ(display2.id(), opener_display.id());

    // Open the PiP window.
    NavigateParams params = MakeNavigateParams(browser());
    params.disposition = WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;

    // Navigate to https:// page
    net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
    ASSERT_TRUE(https_server.Start());
    WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
    const GURL url = https_server.GetURL("/simple.html");
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

    params.source_contents = tab;
    params.contents_to_insert = WebContents::Create(web_contents_params);
    Navigate(&params);

    // The PiP window should also be on display 2.
#if BUILDFLAG(IS_OZONE)
    if (!ui::OzonePlatform::GetInstance()
             ->GetPlatformProperties()
             .supports_global_screen_coordinates) {
      // Since we cannot get the global coordinates of the window, check
      // if the window is in the correct display without relying on bounds.
      const auto pip_window_display =
          display::Screen::Get()->GetDisplayNearestWindow(
              params.browser->GetWindow()->GetNativeWindow());
      ASSERT_EQ(display2.id(), pip_window_display.id());
      return;
    }
#endif
    EXPECT_TRUE(display2.work_area().Contains(
        params.browser->GetWindow()->GetBounds()));
  }
}

IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, NavigateWithCallback) {
  // Set up navigation parameters.
  NavigateParams params = MakeNavigateParams();  // Uses GetGoogleURL()
  params.disposition = WindowOpenDisposition::CURRENT_TAB;

  // Set up an observer to wait for the navigation to complete.
  content::TestNavigationObserver navigation_observer(
      browser()->tab_strip_model()->GetActiveWebContents());

  // Call the new Navigate function overload.
  base::test::TestFuture<base::WeakPtr<content::NavigationHandle>> future;
  Navigate(&params, future.GetCallback());

  // Wait for the NavigationHandle
  base::WeakPtr<content::NavigationHandle> navigation_handle = future.Get();

  // Verify the handle from the callback matches the completed navigation.
  ASSERT_TRUE(navigation_handle);
  EXPECT_EQ(GetGoogleURL(), navigation_handle->GetURL());

  // Wait for "async". Observer checks NavigationHandle properties.
  navigation_observer.Wait();

  // Verify the navigation completed successfully.
  EXPECT_EQ(GetGoogleURL(),
            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
}

}  // namespace
