chromium/chrome/browser/extensions/extension_keybinding_apitest.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.

#include "base/containers/contains.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/commands/command_service.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/permissions/active_tab_permission_granter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/extensions/extensions_container.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
#include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/sessions/content/session_tab_helper.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/javascript_test_observer.h"
#include "extensions/browser/extension_action.h"
#include "extensions/browser/extension_action_manager.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/test_event_router_observer.h"
#include "extensions/common/api/extension_action/action_info.h"
#include "extensions/common/api/extension_action/action_info_test_util.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "extensions/test/test_extension_dir.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/blink/public/common/switches.h"

WebContents;

namespace extensions {

namespace {

// This extension ID is used for tests require a stable ID over multiple
// extension installs.
const char kId[] =;

// Default keybinding to use for emulating user-defined shortcut overrides. The
// test extensions use Alt+Shift+F and Alt+Shift+H.
const char kAltShiftG[] =;

// Name of the command for the "basics" test extension.
const char kBasicsShortcutCommandName[] =;

#if BUILDFLAG(IS_MAC)
const char kBookmarkKeybinding[] = "Command+D";
#else
const char kBookmarkKeybinding[] =;
#endif  // BUILDFLAG(IS_MAC)

bool SendBookmarkKeyPressSync(Browser* browser) {}

// Named command for media key overwrite test.
const char kMediaKeyTestCommand[] =;

// A scoped observer that listens for dom automation messages.
class DomMessageListener : public content::TestMessageHandler {};

DomMessageListener::DomMessageListener(content::WebContents* web_contents)
    :{}

DomMessageListener::~DomMessageListener() {}

void DomMessageListener::Wait() {}

void DomMessageListener::Clear() {}

content::TestMessageHandler::MessageResponse DomMessageListener::HandleMessage(
    const std::string& json) {}

void DomMessageListener::Reset() {}

// Programmatically (from the extension) sets the action of |extension| to be
// visible on the tab with the given |tab_id|. Expects the action is *not*
// visible to start.
void SetActionVisibleOnTab(Profile* profile,
                           const Extension& extension,
                           int tab_id) {}

// Sends a keypress with the given |keyboard_code| to the specified |extension|.
// If |expect_dispatch| is true, expects pageAction.onClicked to be dispatched
// to the extension. Otherwise, expects it is not sent.
void SendKeyPressToAction(Browser* browser,
                          const Extension& extension,
                          ui::KeyboardCode keyboard_code,
                          const char* event_name,
                          bool expect_dispatch) {}

// Given an |action_type|, returns the corresponding command key.
const char* GetCommandKeyForActionType(ActionInfo::Type action_type) {}

}  // namespace

class CommandsApiTest : public ExtensionApiTest {};

class IncognitoCommandsApiTest : public CommandsApiTest,
                                 public testing::WithParamInterface<bool> {};

// A parameterized version to allow testing with different action types.
class ActionCommandsApiTest
    : public CommandsApiTest,
      public testing::WithParamInterface<ActionInfo::Type> {};

// Test the basic functionality of the Keybinding API:
// - That pressing the shortcut keys should perform actions (activate the
//   browser action or send an event).
// - Note: Page action keybindings are tested in PageAction test below.
// - The shortcut keys taken by one extension are not overwritten by the last
//   installed extension.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) {}

IN_PROC_BROWSER_TEST_F(CommandsApiTest, InactivePageActionDoesntTrigger) {}

// Tests that a page action that is unpinned and only shown within the
// extensions menu will still properly trigger when the keybinding is used.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, UnpinnedPageActionTriggers) {}

IN_PROC_BROWSER_TEST_F(CommandsApiTest, PageActionKeyUpdated) {}

// Verify that keyboard shortcut takes effect without reloading the extension.
// Regression test for https://crbug.com/1190476.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, ActionKeyUpdated) {}

IN_PROC_BROWSER_TEST_F(CommandsApiTest, PageActionOverrideChromeShortcut) {}

// This test validates that the getAll query API function returns registered
// commands as well as synthesized ones and that inactive commands (like the
// synthesized ones are in nature) have no shortcuts.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, SynthesizedCommand) {}

// This test validates that an extension cannot request a shortcut that is
// already in use by Chrome.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, DontOverwriteSystemShortcuts) {}

// This test validates that user-set override of the Chrome bookmark shortcut in
// an extension that does not request it does supersede the same keybinding by
// web pages.
IN_PROC_BROWSER_TEST_F(CommandsApiTest,
                       OverwriteBookmarkShortcutByUserOverridesWebKeybinding) {}

#if BUILDFLAG(IS_WIN)
// Currently this feature is implemented on Windows only.
#define MAYBE_AllowDuplicatedMediaKeys
#else
#define MAYBE_AllowDuplicatedMediaKeys
#endif

// Test that media keys go to all extensions that register for them.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_AllowDuplicatedMediaKeys) {}

IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutAddedOnUpdate) {}

IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutChangedOnUpdate) {}

IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutRemovedOnUpdate) {}

IN_PROC_BROWSER_TEST_F(CommandsApiTest,
                       ShortcutAddedOnUpdateAfterBeingAssignedByUser) {}

IN_PROC_BROWSER_TEST_F(CommandsApiTest,
                       ShortcutChangedOnUpdateAfterBeingReassignedByUser) {}

// Test that Media keys do not overwrite previous settings.
IN_PROC_BROWSER_TEST_F(CommandsApiTest,
    MediaKeyShortcutChangedOnUpdateAfterBeingReassignedByUser) {}

IN_PROC_BROWSER_TEST_F(CommandsApiTest,
                       ShortcutRemovedOnUpdateAfterBeingReassignedByUser) {}

//
#if BUILDFLAG(IS_CHROMEOS_ASH) && !defined(NDEBUG)
// TODO(dtseng): Test times out on Chrome OS debug. See http://crbug.com/412456.
#define MAYBE_ContinuePropagation
#else
#define MAYBE_ContinuePropagation
#endif

IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_ContinuePropagation) {}

// Test is only applicable on Chrome OS.
#if BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(CommandsApiTest, ChromeOSConversions) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(RunExtensionTest("keybinding/chromeos_conversions")) << message_;
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/extensions/test_file.txt")));

  ResultCatcher catcher;

  // Send all expected keys (Search+Shift+{Left, Up, Right, Down}).
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_LEFT, false,
                                              true, false, true));
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_UP, false,
                                              true, false, true));
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_RIGHT, false,
                                              true, false, true));
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_DOWN, false,
                                              true, false, true));

  ASSERT_TRUE(catcher.GetNextResult());
}
#endif  // BUILDFLAG(IS_CHROMEOS)

// Make sure component extensions retain keybindings after removal then
// re-adding.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, AddRemoveAddComponentExtension) {}

// Validate parameters sent along with an extension event, in response to
// command being triggered.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, TabParameter) {}

// Test Keybinding in incognito mode.
IN_PROC_BROWSER_TEST_P(IncognitoCommandsApiTest, IncognitoMode) {}

IN_PROC_BROWSER_TEST_P(ActionCommandsApiTest,
                       TriggeringCommandTriggersListener) {}

// This test validates that commands.getAll() returns commands associated with
// a registered [page/browser] action.
IN_PROC_BROWSER_TEST_P(ActionCommandsApiTest, GetAllReturnsActionCommand) {}

// Tests that triggering a command associated with an action opens an
// extension's popup.
IN_PROC_BROWSER_TEST_P(ActionCommandsApiTest, TriggeringCommandTriggersPopup) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace extensions