1 // Copyright 2013 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.
6 #include "ash/sticky_keys/sticky_keys_controller.h"
7 #include "ash/sticky_keys/sticky_keys_overlay.h"
8 #include "ash/system/tray/system_tray.h"
9 #include "base/command_line.h"
10 #include "base/prefs/pref_service.h"
11 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_window.h"
15 #include "chrome/browser/ui/location_bar/location_bar.h"
16 #include "chrome/browser/ui/omnibox/omnibox_view.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/browser/ui/view_ids.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "chrome/test/base/interactive_test_utils.h"
22 #include "ui/aura/window_event_dispatcher.h"
23 #include "ui/events/keycodes/keyboard_codes.h"
24 #include "ui/gfx/native_widget_types.h"
28 class StickyKeysBrowserTest : public InProcessBrowserTest {
30 StickyKeysBrowserTest() {}
31 virtual ~StickyKeysBrowserTest() {}
33 void EnableStickyKeys() {
34 AccessibilityManager::Get()->EnableStickyKeys(true);
37 void DisableStickyKeys() {
38 AccessibilityManager::Get()->EnableStickyKeys(false);
41 ash::SystemTray* GetSystemTray() {
42 return ash::Shell::GetInstance()->GetPrimarySystemTray();
45 void SendKeyPress(ui::KeyboardCode key) {
46 gfx::NativeWindow root_window =
47 ash::Shell::GetInstance()->GetPrimaryRootWindow();
49 ui_test_utils::SendKeyPressToWindowSync(root_window,
57 content::NotificationRegistrar registrar_;
59 DISALLOW_COPY_AND_ASSIGN(StickyKeysBrowserTest);
62 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest, OpenTrayMenu) {
65 // Open system tray bubble with shortcut.
66 SendKeyPress(ui::VKEY_MENU); // alt key.
67 SendKeyPress(ui::VKEY_SHIFT);
68 SendKeyPress(ui::VKEY_S);
69 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
71 // Hide system bubble.
72 GetSystemTray()->CloseSystemBubble();
73 EXPECT_FALSE(GetSystemTray()->HasSystemBubble());
75 // Pressing S again should not reopen the bubble.
76 SendKeyPress(ui::VKEY_S);
77 EXPECT_FALSE(GetSystemTray()->HasSystemBubble());
79 // With sticky keys disabled, we will fail to perform the shortcut.
81 SendKeyPress(ui::VKEY_MENU); // alt key.
82 SendKeyPress(ui::VKEY_SHIFT);
83 SendKeyPress(ui::VKEY_S);
84 EXPECT_FALSE(GetSystemTray()->HasSystemBubble());
87 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest, OpenNewTabs) {
88 // Lock the modifier key.
90 SendKeyPress(ui::VKEY_CONTROL);
91 SendKeyPress(ui::VKEY_CONTROL);
93 // In the locked state, pressing 't' should open a new tab each time.
94 TabStripModel* tab_strip_model = browser()->tab_strip_model();
96 for (; tab_count < 5; ++tab_count) {
97 EXPECT_EQ(tab_count, tab_strip_model->count());
98 SendKeyPress(ui::VKEY_T);
101 // Unlock the modifier key and shortcut should no longer activate.
102 SendKeyPress(ui::VKEY_CONTROL);
103 SendKeyPress(ui::VKEY_T);
104 EXPECT_EQ(tab_count, tab_strip_model->count());
106 // Shortcut should not work after disabling sticky keys.
108 SendKeyPress(ui::VKEY_CONTROL);
109 SendKeyPress(ui::VKEY_CONTROL);
110 SendKeyPress(ui::VKEY_T);
111 EXPECT_EQ(tab_count, tab_strip_model->count());
114 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest, CtrlClickHomeButton) {
115 // Show home page button.
116 browser()->profile()->GetPrefs()->SetBoolean(prefs::kShowHomeButton, true);
117 TabStripModel* tab_strip_model = browser()->tab_strip_model();
119 EXPECT_EQ(tab_count, tab_strip_model->count());
121 // Test sticky keys with modified mouse click action.
123 SendKeyPress(ui::VKEY_CONTROL);
124 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
125 EXPECT_EQ(++tab_count, tab_strip_model->count());
126 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
127 EXPECT_EQ(tab_count, tab_strip_model->count());
129 // Test locked modifier key with mouse click.
130 SendKeyPress(ui::VKEY_CONTROL);
131 SendKeyPress(ui::VKEY_CONTROL);
132 for (; tab_count < 5; ++tab_count) {
133 EXPECT_EQ(tab_count, tab_strip_model->count());
134 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
136 SendKeyPress(ui::VKEY_CONTROL);
137 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
138 EXPECT_EQ(tab_count, tab_strip_model->count());
140 // Test disabling sticky keys prevent modified mouse click.
142 SendKeyPress(ui::VKEY_CONTROL);
143 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
144 EXPECT_EQ(tab_count, tab_strip_model->count());
147 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest, SearchLeftOmnibox) {
150 OmniboxView* omnibox =
151 browser()->window()->GetLocationBar()->GetOmniboxView();
153 // Give the omnibox focus.
157 SendKeyPress(ui::VKEY_F);
158 SendKeyPress(ui::VKEY_O);
159 SendKeyPress(ui::VKEY_O);
161 // Verify the location of the caret.
163 omnibox->GetSelectionBounds(&start, &end);
164 ASSERT_EQ(3U, start);
167 // Hit Home by sequencing Search (left Windows) and Left (arrow).
168 SendKeyPress(ui::VKEY_LWIN);
169 SendKeyPress(ui::VKEY_LEFT);
171 // Verify caret moved to the beginning.
172 omnibox->GetSelectionBounds(&start, &end);
173 ASSERT_EQ(0U, start);
177 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest, OverlayShown) {
178 const ui::KeyboardCode modifier_keys[] = { ui::VKEY_CONTROL,
183 // Overlay should not be visible if sticky keys is not enabled.
184 ash::StickyKeysController* controller =
185 ash::Shell::GetInstance()->sticky_keys_controller();
186 EXPECT_FALSE(controller->GetOverlayForTest());
187 for (auto key_code : modifier_keys) {
188 SendKeyPress(key_code);
189 EXPECT_FALSE(controller->GetOverlayForTest());
192 // Cycle through the modifier keys and make sure each gets shown.
194 ash::StickyKeysOverlay* sticky_keys_overlay = controller->GetOverlayForTest();
195 for (auto key_code : modifier_keys) {
196 SendKeyPress(key_code);
197 EXPECT_TRUE(sticky_keys_overlay->is_visible());
198 SendKeyPress(key_code);
199 EXPECT_TRUE(sticky_keys_overlay->is_visible());
200 SendKeyPress(key_code);
201 EXPECT_FALSE(sticky_keys_overlay->is_visible());
204 // Disabling sticky keys should hide the overlay.
205 SendKeyPress(ui::VKEY_CONTROL);
206 EXPECT_TRUE(sticky_keys_overlay->is_visible());
208 EXPECT_FALSE(controller->GetOverlayForTest());
209 for (auto key_code : modifier_keys) {
210 SendKeyPress(key_code);
211 EXPECT_FALSE(controller->GetOverlayForTest());
215 } // namespace chromeos