chromium/chrome/browser/ui/browser_focus_uitest.cc

// 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.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include <stddef.h>

#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sharing_hub/sharing_hub_features.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.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/find_bar/find_bar_host_unittest_util.h"
#include "chrome/browser/ui/frame/window_frame_util.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/chrome_test_utils.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/omnibox/browser/autocomplete_match_type.h"
#include "components/omnibox/browser/omnibox_client.h"
#include "components/omnibox/browser/omnibox_controller.h"
#include "components/omnibox/browser/omnibox_view.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/focus_changed_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/blink/public/common/switches.h"
#include "ui/base/test/ui_controls.h"
#include "ui/base/ui_base_features.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/test/widget_activation_waiter.h"
#include "ui/views/widget/widget.h"

#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#endif

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_LACROS)
#include "base/test/scoped_feature_list.h"
#endif

namespace {

constexpr char kGetFocusedElementJS[] =;

// Listens to UI and DOM element focus changes.
class FocusChangeObserver : public views::FocusChangeListener,
                            public content::WebContentsObserver {};

}  // namespace

namespace base {

template <>
struct ScopedObservationTraits<views::FocusManager, FocusChangeObserver> {};

}  // namespace base

namespace {

RenderViewHost;
WebContents;

#if BUILDFLAG(IS_POSIX)
// The delay waited in some cases where we don't have a notifications for an
// action we take.
const int kActionDelayMs =;
#endif

const char kSimplePage[] =;
const char kStealFocusPage[] =;
const char kTypicalPage[] =;

class BrowserFocusBasicTest : public InProcessBrowserTest {};

// A basic test to check that a newly opened browser window has focus and the
// focus is on the omnibox.
IN_PROC_BROWSER_TEST_F(BrowserFocusBasicTest, BrowserFocusedOnCreation) {}

class BrowserFocusTest : public InProcessBrowserTest {};

// Flaky on Mac (http://crbug.com/67301).
#if BUILDFLAG(IS_MAC)
#define MAYBE_ClickingMovesFocus
#else
// If this flakes, disable and log details in http://crbug.com/523255.
#define MAYBE_ClickingMovesFocus
#endif
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_ClickingMovesFocus) {}

IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) {}

// Tabs remember focus.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) {}

// Tabs remember focus with find-in-page box.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocusFindInPage) {}

// Background window does not steal focus.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) {}

// Page cannot steal focus when focus is on location bar.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) {}

// Test forward and reverse focus traversal on a typical page.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {}

// Test that find-in-page UI can request focus, even when it is already open.
#if BUILDFLAG(IS_MAC)
#define MAYBE_FindFocusTest
#else
// If this flakes, disable and log details in http://crbug.com/523255.
#define MAYBE_FindFocusTest
#endif
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FindFocusTest) {}

// Makes sure the focus is in the right location when opening the different
// types of tabs.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {}

// Tests that focus goes where expected when using reload.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReload) {}

// Tests that focus goes where expected when using reload on a crashed tab.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
// Hangy, http://crbug.com/50025.
#define MAYBE_FocusOnReloadCrashedTab
#else
#define MAYBE_FocusOnReloadCrashedTab
#endif
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusOnReloadCrashedTab) {}

// Tests that focus goes to frame after crashed tab.
// TODO(shrikant): Find out where the focus should be deterministically.
// Currently focused_view after crash seem to be non null in debug mode
// (invalidated pointer 0xcccccc).
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_FocusAfterCrashedTab) {}

// Tests that when omnibox triggers a navigation, then the focus is moved into
// the current tab.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, NavigateFromOmnibox) {}

// Tests that when a new tab is opened from the omnibox, the focus is moved from
// the omnibox for the current tab.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, NavigateFromOmniboxIntoNewTab) {}

// Flaky on all platforms (http://crbug.com/665296).
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_FocusOnNavigate) {}

// Ensure that crbug.com/567445 does not regress. This test checks that the
// Omnibox does not get focused when loading about:blank in a case where it's
// not the startup URL, e.g. when a page opens a popup to about:blank, with a
// null opener, and then navigates it. This is a potential security issue; see
// comments in |WebContentsImpl::FocusLocationBarByDefault|.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, AboutBlankNavigationLocationTest) {}

// Regression test for https://crbug.com/677716.  This ensures that the omnibox
// does not get focused if another tab in the same window navigates to the New
// Tab Page, since that can scroll the origin of the selected tab out of view.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, NoFocusForBackgroundNTP) {}

// Tests that the location bar is focusable when showing, which is the case in
// popup windows.
// TODO(crbug.com/40794922): Flaky on Linux.
// TODO(crbug/1520655): Broken since CR2023.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_PopupLocationBar) {}

// Tests that the location bar is not focusable when hidden, which is the case
// in app windows.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, AppLocationBar) {}

}  // namespace