#include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h"
#include <tuple>
#include "base/files/file_util.h"
#include "base/memory/raw_ptr.h"
#include "base/test/test_future.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h"
#include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_test_helper.h"
#include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h"
#include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
#include "chrome/browser/ui/web_applications/web_app_browsertest_base.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/color_utils.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/test/test_views.h"
#include "ui/views/view_utils.h"
#if BUILDFLAG(IS_LINUX)
#include "ui/linux/linux_ui.h"
#include "ui/linux/linux_ui_factory.h"
#include "ui/linux/linux_ui_getter.h"
class FakeLinuxUiGetter : public ui::LinuxUiGetter { … };
#endif
class WebAppOpaqueBrowserFrameViewTest : public web_app::WebAppBrowserTestBase { … };
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, NoThemeColor) { … }
#if BUILDFLAG(IS_LINUX)
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, SystemThemeColor) { … }
#endif
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, LightThemeColor) { … }
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, DarkThemeColor) { … }
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, MediumThemeColor) { … }
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, StaticTitleBarHeight) { … }
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, Fullscreen) { … }
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, AccessibleProperties) { … }
#if BUILDFLAG(IS_WIN)
class WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest
: public InProcessBrowserTest {
public:
WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest() = default;
WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest(
const WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest&) = delete;
WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest& operator=(
const WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest&) = delete;
~WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest() override = default;
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
embedded_test_server()->ServeFilesFromDirectory(temp_dir_.GetPath());
ASSERT_TRUE(embedded_test_server()->Start());
InProcessBrowserTest::SetUp();
}
bool InstallAndLaunchWebAppWithWindowControlsOverlay() {
GURL start_url = web_app_frame_toolbar_helper_
.LoadWindowControlsOverlayTestPageWithDataAndGetURL(
embedded_test_server(), &temp_dir_);
auto web_app_info =
web_app::WebAppInstallInfo::CreateWithStartUrlForTesting(start_url);
web_app_info->scope = start_url.GetWithoutFilename();
web_app_info->display_mode = blink::mojom::DisplayMode::kStandalone;
web_app_info->user_display_mode =
web_app::mojom::UserDisplayMode::kStandalone;
web_app_info->title = u"A Web App";
web_app_info->display_override = {
blink::mojom::DisplayMode::kWindowControlsOverlay};
webapps::AppId app_id = web_app::test::InstallWebApp(
browser()->profile(), std::move(web_app_info));
Browser* app_browser =
web_app::LaunchWebAppBrowser(browser()->profile(), app_id);
web_app::NavigateViaLinkClickToURLAndWait(app_browser, start_url);
browser_view_ = BrowserView::GetBrowserViewForBrowser(app_browser);
views::NonClientFrameView* frame_view =
browser_view_->GetWidget()->non_client_view()->frame_view();
bool is_opaque_browser_frame_view =
views::IsViewClass<OpaqueBrowserFrameView>(frame_view);
if (!is_opaque_browser_frame_view)
return false;
opaque_browser_frame_view_ =
static_cast<OpaqueBrowserFrameView*>(frame_view);
auto* web_app_frame_toolbar =
browser_view_->web_app_frame_toolbar_for_testing();
DCHECK(web_app_frame_toolbar);
DCHECK(web_app_frame_toolbar->GetVisible());
return true;
}
void ToggleWindowControlsOverlayEnabledAndWait() {
auto* web_contents = browser_view_->GetActiveWebContents();
web_app_frame_toolbar_helper_.SetupGeometryChangeCallback(web_contents);
base::test::TestFuture<void> future;
browser_view_->ToggleWindowControlsOverlayEnabled(future.GetCallback());
EXPECT_TRUE(future.Wait());
content::TitleWatcher title_watcher(web_contents, u"ongeometrychange");
std::ignore = title_watcher.WaitAndGetTitle();
}
raw_ptr<BrowserView, AcrossTasksDanglingUntriaged> browser_view_ = nullptr;
raw_ptr<OpaqueBrowserFrameView, AcrossTasksDanglingUntriaged>
opaque_browser_frame_view_ = nullptr;
WebAppFrameToolbarTestHelper web_app_frame_toolbar_helper_;
private:
web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_;
base::ScopedTempDir temp_dir_;
};
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest,
CaptionButtonsTooltip) {
if (!InstallAndLaunchWebAppWithWindowControlsOverlay())
GTEST_SKIP() << "Skip test if it is not a OpaqueBrowserFrameView";
auto* minimize_button = static_cast<const views::Button*>(
opaque_browser_frame_view_->GetViewByID(VIEW_ID_MINIMIZE_BUTTON));
auto* maximize_button = static_cast<const views::Button*>(
opaque_browser_frame_view_->GetViewByID(VIEW_ID_MAXIMIZE_BUTTON));
auto* restore_button = static_cast<const views::Button*>(
opaque_browser_frame_view_->GetViewByID(VIEW_ID_RESTORE_BUTTON));
auto* close_button = static_cast<const views::Button*>(
opaque_browser_frame_view_->GetViewByID(VIEW_ID_CLOSE_BUTTON));
EXPECT_EQ(minimize_button->GetTooltipText(), u"");
EXPECT_EQ(maximize_button->GetTooltipText(), u"");
EXPECT_EQ(restore_button->GetTooltipText(), u"");
EXPECT_EQ(close_button->GetTooltipText(), u"");
ToggleWindowControlsOverlayEnabledAndWait();
EXPECT_EQ(minimize_button->GetTooltipText(),
minimize_button->GetViewAccessibility().GetCachedName());
EXPECT_EQ(maximize_button->GetTooltipText(),
maximize_button->GetViewAccessibility().GetCachedName());
EXPECT_EQ(restore_button->GetTooltipText(),
restore_button->GetViewAccessibility().GetCachedName());
EXPECT_EQ(close_button->GetTooltipText(),
close_button->GetViewAccessibility().GetCachedName());
ToggleWindowControlsOverlayEnabledAndWait();
EXPECT_EQ(minimize_button->GetTooltipText(), u"");
EXPECT_EQ(maximize_button->GetTooltipText(), u"");
EXPECT_EQ(restore_button->GetTooltipText(), u"");
EXPECT_EQ(close_button->GetTooltipText(), u"");
}
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest,
CaptionButtonHitTest) {
if (!InstallAndLaunchWebAppWithWindowControlsOverlay())
GTEST_SKIP() << "Skip test if it is not a OpaqueBrowserFrameView";
opaque_browser_frame_view_->GetWidget()->LayoutRootViewIfNecessary();
constexpr int kInset = 10;
const gfx::Point kPoint(opaque_browser_frame_view_->width() - kInset, kInset);
EXPECT_EQ(opaque_browser_frame_view_->NonClientHitTest(kPoint), HTCLOSE);
ToggleWindowControlsOverlayEnabledAndWait();
EXPECT_EQ(opaque_browser_frame_view_->NonClientHitTest(kPoint), HTCLIENT);
ToggleWindowControlsOverlayEnabledAndWait();
EXPECT_EQ(opaque_browser_frame_view_->NonClientHitTest(kPoint), HTCLOSE);
}
#endif