chromium/chrome/browser/ui/views/extensions/extension_popup_interactive_uitest.cc

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

#include "base/strings/strcat.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_view_host.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/extensions/extension_action_test_helper.h"
#include "chrome/browser/ui/views/extensions/extension_popup.h"
#include "chrome/browser/ui/views/extensions/security_dialog_tracker.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/permissions/permission_request_manager_test_api.h"
#include "components/constrained_window/constrained_window_views.h"
#include "components/javascript_dialogs/app_modal_dialog_controller.h"
#include "components/javascript_dialogs/app_modal_dialog_queue.h"
#include "components/permissions/request_type.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_host_test_helper.h"
#include "extensions/common/mojom/view_type.mojom.h"
#include "extensions/test/test_extension_dir.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
#include "ui/events/base_event_utils.h"
#include "ui/views/test/button_test_api.h"
#include "ui/views/test/widget_activation_waiter.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/widget/unique_widget_ptr.h"
#include "ui/views/window/dialog_delegate.h"

ExtensionPopupInteractiveUiTest;

namespace {

// A helper class for waiting until the devtools is attached to the given
// WebContents.
class DevToolsAttachWaiter : public content::DevToolsAgentHostObserver {};

views::UniqueWidgetPtr CreateTestTopLevelWidget() {}

// Create a dialog widget as a child of `parent` widget.
views::UniqueWidgetPtr CreateTestDialogWidget(views::Widget* parent) {}

void ExpectWidgetDestroy(base::WeakPtr<views::Widget> widget) {}

base::WeakPtr<views::Widget> WaitForLastExtensionPopupVisible() {}

base::WeakPtr<views::Widget> OpenExtensionPopup(
    Browser* browser,
    const extensions::Extension* extension) {}

}  // namespace

// Tests unloading an extension while its popup is actively under inspection.
// Regression test for https://crbug.com/1304499.
IN_PROC_BROWSER_TEST_F(ExtensionPopupInteractiveUiTest,
                       UnloadExtensionWhileInspectingPopup) {}

// Tests that the extension popup does not render over an anchored permissions
// bubble. Regression test for https://crbug.com/1300006.
IN_PROC_BROWSER_TEST_F(ExtensionPopupInteractiveUiTest,
                       ExtensionPopupOverPermissions) {}

// Tests that an extension popup does not close on deactivation while it is
// under inspection.
IN_PROC_BROWSER_TEST_F(ExtensionPopupInteractiveUiTest,
                       ExtensionPopupDoesNotCloseWhileInpsecting) {}

// Tests that an extension popup does not close on deactivation when it shows
// a JS alert dialog.
IN_PROC_BROWSER_TEST_F(ExtensionPopupInteractiveUiTest,
                       ExtensionPopupDoesNotCloseWhileShowingJSAlert) {}

// Tests that an extension popup is closed when a web dialog is shown as active.
// In this test the web dialog is not initiated by the extension popup (see
// ExtensionPopupDoesNotCloseWhileShowingJSAlert for showing an extension-owned
// dialog).
// This prevents the extension from occluding the web dialog, which can be
// dangerous when the web dialog is a security-related dialog (e.g. screen
// sharing dialog, webauthn attestation dialog).
IN_PROC_BROWSER_TEST_F(ExtensionPopupInteractiveUiTest,
                       ExtensionPopupClosesOnShowingWebDialog) {}

// Tests that an extension popup closes when activating the browser window.
IN_PROC_BROWSER_TEST_F(ExtensionPopupInteractiveUiTest,
                       ExtensionPopupClosesOnActivatingBrowserWindow) {}

#if BUILDFLAG(IS_MAC)
// Tests that an extension popup closes when activating the browser window
// in macOS fullscreen.
IN_PROC_BROWSER_TEST_F(
    ExtensionPopupInteractiveUiTest,
    ExtensionPopupClosesOnActivatingBrowserWindowMacFullscreen) {
  // Install a test extension.
  static constexpr char kManifest[] =
      R"({
           "name": "Test Extension",
           "manifest_version": 3,
           "action": { "default_popup": "popup.html" },
           "version": "0.1"
         })";

  extensions::TestExtensionDir test_dir;
  test_dir.WriteManifest(kManifest);
  test_dir.WriteFile(FILE_PATH_LITERAL("popup.html"),
                     "<html>Hello, world!</html>");
  const extensions::Extension* extension =
      LoadExtension(test_dir.UnpackedPath());
  ASSERT_TRUE(extension);

  ui_test_utils::ToggleFullscreenModeAndWait(browser());

  base::WeakPtr<views::Widget> extension_popup_widget =
      OpenExtensionPopup(browser(), extension);

  // Activate the browser window should close the extension popup.
  browser()->window()->Activate();
  ExpectWidgetDestroy(extension_popup_widget);
}
#endif

// Tests that an extension popup does not close when activating an unrelated
// top-level widget. This behavior is useful for users who want to keep the
// popup open to look at the info there while working on other apps or browser
// windows.
IN_PROC_BROWSER_TEST_F(
    ExtensionPopupInteractiveUiTest,
    ExtensionPopupDoesNotClosesOnActivatingOtherTopLevelWindow) {}

// Tests that an API-triggered extenion popup does not show if a security dialog
// is visible. This extension loads a slow image that completes loading only
// after a security dialog is shown.
IN_PROC_BROWSER_TEST_F(ExtensionPopupInteractiveUiTest,
                       APITriggeredPopupIsBlockedBySecurityDialog) {}

// Tests that a user-triggered extenion popup is blocked by visible security
// dialogs.
IN_PROC_BROWSER_TEST_F(ExtensionPopupInteractiveUiTest,
                       UserTriggeredPopupIsBlockedBySecurityUI) {}