chromium/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc

// Copyright 2013 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/views/location_bar/zoom_bubble_view.h"

#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/test/test_browser_dialog.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/zoom/zoom_controller.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/extension_zoom_request_client.h"
#include "extensions/common/extension_builder.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h"
#include "ui/events/base_event_utils.h"
#include "ui/views/test/test_widget_observer.h"
#include "ui/views/test/widget_test.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ui/views/frame/immersive_mode_controller_chromeos.h"
#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h"
#endif

#if BUILDFLAG(IS_MAC)
#include "chrome/browser/ui/browser_commands_mac.h"
#include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
#include "ui/views/test/button_test_api.h"
#endif

ZoomBubbleBrowserTest;

namespace {

void ShowInActiveTab(Browser* browser) {}

}  // namespace

// Test whether the zoom bubble is anchored and whether it is visible when in
// content fullscreen.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, ContentFullscreen) {}

// Immersive fullscreen is either/or on Mac. Base class for tests that only
// apply to non-immersive.
#if BUILDFLAG(IS_MAC)
class ZoomBubbleImmersiveDisabledBrowserTest : public ZoomBubbleBrowserTest {
 public:
  ZoomBubbleImmersiveDisabledBrowserTest() {
    scoped_feature_list_.InitAndDisableFeature(features::kImmersiveFullscreen);
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};
#else
ZoomBubbleImmersiveDisabledBrowserTest;
#endif

// Test whether the zoom bubble is anchored to the same location if the toolbar
// shows in fullscreen. And when the toolbar hides in fullscreen, the zoom
// bubble should close and re-show in a new un-anchored position.
//
// TODO(crbug.com/40727884): Fails on Lacros bots.
// TODO(lgrey): Disable this test for Mac or delete it when immersive is the
// only code path. This was originally added for a Mac bug that is impossible
// to trigger in immersive mode, and is very implementation-coupled.
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#define MAYBE_AnchorPositionsInFullscreen
#else
#define MAYBE_AnchorPositionsInFullscreen
#endif
IN_PROC_BROWSER_TEST_F(ZoomBubbleImmersiveDisabledBrowserTest,
                       MAYBE_AnchorPositionsInFullscreen) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
// Test whether the zoom bubble is anchored and whether it is visible when in
// immersive fullscreen.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, ImmersiveFullscreen) {
  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
  content::WebContents* web_contents = browser_view->GetActiveWebContents();

  ImmersiveModeController* immersive_controller =
      browser_view->immersive_mode_controller();
  chromeos::ImmersiveFullscreenControllerTestApi(
      static_cast<ImmersiveModeControllerChromeos*>(immersive_controller)
          ->controller())
      .SetupForTest();

  // Enter immersive fullscreen.
  ui_test_utils::ToggleFullscreenModeAndWait(browser());
  ASSERT_TRUE(immersive_controller->IsEnabled());
  ASSERT_FALSE(immersive_controller->IsRevealed());

  // The zoom bubble should not be anchored when it is shown in immersive
  // fullscreen and the top-of-window views are not revealed.
  ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC);
  ASSERT_TRUE(ZoomBubbleView::GetZoomBubble());
  const ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubble();
  EXPECT_FALSE(zoom_bubble->GetAnchorView());

  // An immersive reveal should hide the zoom bubble.
  std::unique_ptr<ImmersiveRevealedLock> immersive_reveal_lock =
      immersive_controller->GetRevealedLock(
          ImmersiveModeController::ANIMATE_REVEAL_NO);
  ASSERT_TRUE(immersive_controller->IsRevealed());
  EXPECT_EQ(nullptr, ZoomBubbleView::zoom_bubble_);

  // The zoom bubble should be anchored when it is shown in immersive fullscreen
  // and the top-of-window views are revealed.
  ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC);
  zoom_bubble = ZoomBubbleView::GetZoomBubble();
  ASSERT_TRUE(zoom_bubble);
  EXPECT_TRUE(zoom_bubble->GetAnchorView());

  // The top-of-window views should not hide till the zoom bubble hides. (It
  // would be weird if the view to which the zoom bubble is anchored hid while
  // the zoom bubble was still visible.)
  immersive_reveal_lock.reset();
  EXPECT_TRUE(immersive_controller->IsRevealed());
  ZoomBubbleView::CloseCurrentBubble();
  // The zoom bubble is deleted on a task.
  content::RunAllPendingInMessageLoop();
  EXPECT_FALSE(immersive_controller->IsRevealed());

  // Exit fullscreen before ending the test for the sake of sanity.
  ui_test_utils::ToggleFullscreenModeAndWait(browser());
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

// Tests that trying to open zoom bubble with stale WebContents is safe.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, NoWebContentsIsSafe) {}

// Ensure a tab switch closes the bubble.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, TabSwitchCloses) {}

// Ensure the bubble is dismissed on tab closure and doesn't reference a
// destroyed WebContents.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, DestroyedWebContents) {}

namespace {

class TestZoomRequestClient : public extensions::ExtensionZoomRequestClient {};

}  // namespace

// Extensions may be allowlisted to not show a bubble when they perform a zoom
// change. However, if a zoom bubble is already showing, zoom changes performed
// by the extension should update the bubble.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest,
                       BubbleSuppressingExtensionRefreshesExistingBubble) {}

class ZoomBubbleReuseTest : public ZoomBubbleBrowserTest {};

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, BothUserInitiated) {}

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, SameExtension) {}

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, DifferentExtension) {}

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, ExtensionThenUser) {}

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, UserThenExtension) {}

class ZoomBubbleDialogTest : public DialogBrowserTest {};

// Test that calls ShowUi("default").
IN_PROC_BROWSER_TEST_F(ZoomBubbleDialogTest, InvokeUi_default) {}

// If a key event causes the zoom bubble to gain focus, it shouldn't close
// automatically. This allows keyboard-only users to interact with the bubble.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, FocusPreventsClose) {}