1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/active_tab_permission_granter.h"
6#include "chrome/browser/extensions/browser_action_test_util.h"
7#include "chrome/browser/extensions/extension_action.h"
8#include "chrome/browser/extensions/extension_action_manager.h"
9#include "chrome/browser/extensions/extension_apitest.h"
10#include "chrome/browser/extensions/tab_helper.h"
11#include "chrome/browser/sessions/session_tab_helper.h"
12#include "chrome/browser/ui/browser.h"
13#include "chrome/browser/ui/tabs/tab_strip_model.h"
14#include "chrome/common/chrome_switches.h"
15#include "chrome/common/extensions/extension.h"
16#include "chrome/test/base/interactive_test_utils.h"
17#include "chrome/test/base/ui_test_utils.h"
18#include "content/public/browser/notification_service.h"
19#include "content/public/browser/web_contents.h"
20#include "content/public/test/browser_test_utils.h"
21
22using content::WebContents;
23
24namespace extensions {
25
26class CommandsApiTest : public ExtensionApiTest {
27 public:
28  CommandsApiTest() {}
29  virtual ~CommandsApiTest() {}
30
31 protected:
32  BrowserActionTestUtil GetBrowserActionsBar() {
33    return BrowserActionTestUtil(browser());
34  }
35};
36
37class ScriptBadgesCommandsApiTest : public ExtensionApiTest {
38 public:
39  ScriptBadgesCommandsApiTest() {
40    // We cannot add this to CommandsApiTest because then PageActions get
41    // treated like BrowserActions and the PageAction test starts failing.
42    CommandLine::ForCurrentProcess()->AppendSwitchASCII(
43        switches::kScriptBadges, "1");
44  }
45  virtual ~ScriptBadgesCommandsApiTest() {}
46};
47
48// Test the basic functionality of the Keybinding API:
49// - That pressing the shortcut keys should perform actions (activate the
50//   browser action or send an event).
51// - Note: Page action keybindings are tested in PageAction test below.
52// - The shortcut keys taken by one extension are not overwritten by the last
53//   installed extension.
54IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) {
55  ASSERT_TRUE(test_server()->Start());
56  ASSERT_TRUE(RunExtensionTest("keybinding/basics")) << message_;
57  const Extension* extension = GetSingleLoadedExtension();
58  ASSERT_TRUE(extension) << message_;
59
60  // Load this extension, which uses the same keybindings but sets the page
61  // to different colors. This is so we can see that it doesn't interfere. We
62  // don't test this extension in any other way (it should otherwise be
63  // immaterial to this test).
64  ASSERT_TRUE(RunExtensionTest("keybinding/conflicting")) << message_;
65
66  // Test that there are two browser actions in the toolbar.
67  ASSERT_EQ(2, GetBrowserActionsBar().NumberOfBrowserActions());
68
69  ui_test_utils::NavigateToURL(browser(),
70      test_server()->GetURL("files/extensions/test_file.txt"));
71
72  // activeTab shouldn't have been granted yet.
73  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
74  ASSERT_TRUE(tab);
75
76  ActiveTabPermissionGranter* granter =
77      TabHelper::FromWebContents(tab)->active_tab_permission_granter();
78  EXPECT_FALSE(granter->IsGranted(extension));
79
80  // Activate the shortcut (Ctrl+Shift+F).
81  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
82      browser(), ui::VKEY_F, true, true, false, false));
83
84  // activeTab should now be granted.
85  EXPECT_TRUE(granter->IsGranted(extension));
86
87  // Verify the command worked.
88  bool result = false;
89  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
90      tab,
91      "setInterval(function(){"
92      "  if(document.body.bgColor == 'red'){"
93      "    window.domAutomationController.send(true)}}, 100)",
94      &result));
95  ASSERT_TRUE(result);
96
97  // Activate the shortcut (Ctrl+Shift+Y).
98  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
99      browser(), ui::VKEY_Y, true, true, false, false));
100
101  result = false;
102  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
103      tab,
104      "setInterval(function(){"
105      "  if(document.body.bgColor == 'blue'){"
106      "    window.domAutomationController.send(true)}}, 100)",
107      &result));
108  ASSERT_TRUE(result);
109}
110
111// Flaky on linux and chromeos, http://crbug.com/165825
112#if defined(OS_MACOSX) || defined(OS_WIN)
113#define MAYBE_PageAction PageAction
114#else
115#define MAYBE_PageAction DISABLED_PageAction
116#endif
117IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_PageAction) {
118  ASSERT_TRUE(test_server()->Start());
119  ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_;
120  const Extension* extension = GetSingleLoadedExtension();
121  ASSERT_TRUE(extension) << message_;
122
123  {
124    // Load a page, the extension will detect the navigation and request to show
125    // the page action icon.
126    ResultCatcher catcher;
127    ui_test_utils::NavigateToURL(browser(),
128        test_server()->GetURL("files/extensions/test_file.txt"));
129    ASSERT_TRUE(catcher.GetNextResult());
130  }
131
132  // Make sure it appears and is the right one.
133  ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
134  int tab_id = SessionTabHelper::FromWebContents(
135      browser()->tab_strip_model()->GetActiveWebContents())->session_id().id();
136  ExtensionAction* action =
137      ExtensionActionManager::Get(browser()->profile())->
138      GetPageAction(*extension);
139  ASSERT_TRUE(action);
140  EXPECT_EQ("Make this page red", action->GetTitle(tab_id));
141
142  // Activate the shortcut (Alt+Shift+F).
143  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
144      browser(), ui::VKEY_F, false, true, true, false));
145
146  // Verify the command worked (the page action turns the page red).
147  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
148  bool result = false;
149  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
150      tab,
151      "setInterval(function(){"
152      "  if(document.body.bgColor == 'red'){"
153      "    window.domAutomationController.send(true)}}, 100)",
154      &result));
155  ASSERT_TRUE(result);
156}
157
158// Checked-in in a disabled state, because the necessary functionality to
159// automatically verify that the test works hasn't been implemented for the
160// script badges yet (see http://crbug.com/140016). The test results, can be
161// verified manually by running the test and verifying that the synthesized
162// popup for script badges appear. When bug 140016 has been fixed, the popup
163// code can signal to the test that the test passed.
164// TODO(finnur): Enable this test once the bug is fixed.
165IN_PROC_BROWSER_TEST_F(ScriptBadgesCommandsApiTest, DISABLED_ScriptBadge) {
166  ASSERT_TRUE(test_server()->Start());
167  ASSERT_TRUE(RunExtensionTest("keybinding/script_badge")) << message_;
168  const Extension* extension = GetSingleLoadedExtension();
169  ASSERT_TRUE(extension) << message_;
170
171  {
172    ResultCatcher catcher;
173    // Tell the extension to update the script badge state.
174    ui_test_utils::NavigateToURL(
175        browser(), GURL(extension->GetResourceURL("show.html")));
176    ASSERT_TRUE(catcher.GetNextResult());
177  }
178
179  {
180    ResultCatcher catcher;
181    // Activate the shortcut (Ctrl+Shift+F).
182    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
183        browser(), ui::VKEY_F, true, true, false, false));
184    ASSERT_TRUE(catcher.GetNextResult());
185  }
186}
187
188// This test validates that the getAll query API function returns registered
189// commands as well as synthesized ones and that inactive commands (like the
190// synthesized ones are in nature) have no shortcuts.
191IN_PROC_BROWSER_TEST_F(CommandsApiTest, SynthesizedCommand) {
192  ASSERT_TRUE(test_server()->Start());
193  ASSERT_TRUE(RunExtensionTest("keybinding/synthesized")) << message_;
194}
195
196}  // namespace extensions
197