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/tabs/tab_strip_model.h"
17 #include "chrome/browser/ui/view_ids.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/interactive_test_utils.h"
21 #include "components/omnibox/browser/omnibox_view.h"
22 #include "ui/aura/window_event_dispatcher.h"
23 #include "ui/events/keycodes/keyboard_codes.h"
24 #include "ui/events/test/event_generator.h"
25 #include "ui/gfx/native_widget_types.h"
29 class StickyKeysBrowserTest
: public InProcessBrowserTest
{
31 void SetUpOnMainThread() override
{
32 content::BrowserTestBase::SetUpOnMainThread();
33 event_generator_
.reset(
34 new ui::test::EventGenerator(browser()->window()->GetNativeWindow()));
38 StickyKeysBrowserTest() {}
39 ~StickyKeysBrowserTest() override
{}
41 void EnableStickyKeys() {
42 AccessibilityManager::Get()->EnableStickyKeys(true);
45 void DisableStickyKeys() {
46 AccessibilityManager::Get()->EnableStickyKeys(false);
49 ash::SystemTray
* GetSystemTray() {
50 return ash::Shell::GetInstance()->GetPrimarySystemTray();
53 void SendKeyPress(ui::KeyboardCode key
) {
54 event_generator_
->PressKey(key
, ui::EF_NONE
);
55 event_generator_
->ReleaseKey(key
, ui::EF_NONE
);
58 content::NotificationRegistrar registrar_
;
59 scoped_ptr
<ui::test::EventGenerator
> event_generator_
;
61 DISALLOW_COPY_AND_ASSIGN(StickyKeysBrowserTest
);
64 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest
, OpenTrayMenu
) {
67 // Open system tray bubble with shortcut.
68 SendKeyPress(ui::VKEY_MENU
); // alt key.
69 SendKeyPress(ui::VKEY_SHIFT
);
70 SendKeyPress(ui::VKEY_S
);
71 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
73 // Hide system bubble.
74 GetSystemTray()->CloseSystemBubble();
75 EXPECT_FALSE(GetSystemTray()->HasSystemBubble());
77 // Pressing S again should not reopen the bubble.
78 SendKeyPress(ui::VKEY_S
);
79 EXPECT_FALSE(GetSystemTray()->HasSystemBubble());
81 // With sticky keys disabled, we will fail to perform the shortcut.
83 SendKeyPress(ui::VKEY_MENU
); // alt key.
84 SendKeyPress(ui::VKEY_SHIFT
);
85 SendKeyPress(ui::VKEY_S
);
86 EXPECT_FALSE(GetSystemTray()->HasSystemBubble());
89 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest
, OpenNewTabs
) {
90 // Lock the modifier key.
92 SendKeyPress(ui::VKEY_CONTROL
);
93 SendKeyPress(ui::VKEY_CONTROL
);
95 // In the locked state, pressing 't' should open a new tab each time.
96 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
98 for (; tab_count
< 5; ++tab_count
) {
99 EXPECT_EQ(tab_count
, tab_strip_model
->count());
100 SendKeyPress(ui::VKEY_T
);
103 // Unlock the modifier key and shortcut should no longer activate.
104 SendKeyPress(ui::VKEY_CONTROL
);
105 SendKeyPress(ui::VKEY_T
);
106 EXPECT_EQ(tab_count
, tab_strip_model
->count());
108 // Shortcut should not work after disabling sticky keys.
110 SendKeyPress(ui::VKEY_CONTROL
);
111 SendKeyPress(ui::VKEY_CONTROL
);
112 SendKeyPress(ui::VKEY_T
);
113 EXPECT_EQ(tab_count
, tab_strip_model
->count());
116 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest
, CtrlClickHomeButton
) {
117 // Show home page button.
118 browser()->profile()->GetPrefs()->SetBoolean(prefs::kShowHomeButton
, true);
119 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
121 EXPECT_EQ(tab_count
, tab_strip_model
->count());
123 // Test sticky keys with modified mouse click action.
125 SendKeyPress(ui::VKEY_CONTROL
);
126 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON
);
127 EXPECT_EQ(++tab_count
, tab_strip_model
->count());
128 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON
);
129 EXPECT_EQ(tab_count
, tab_strip_model
->count());
131 // Test locked modifier key with mouse click.
132 SendKeyPress(ui::VKEY_CONTROL
);
133 SendKeyPress(ui::VKEY_CONTROL
);
134 for (; tab_count
< 5; ++tab_count
) {
135 EXPECT_EQ(tab_count
, tab_strip_model
->count());
136 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON
);
138 SendKeyPress(ui::VKEY_CONTROL
);
139 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON
);
140 EXPECT_EQ(tab_count
, tab_strip_model
->count());
142 // Test disabling sticky keys prevent modified mouse click.
144 SendKeyPress(ui::VKEY_CONTROL
);
145 ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON
);
146 EXPECT_EQ(tab_count
, tab_strip_model
->count());
149 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest
, SearchLeftOmnibox
) {
152 OmniboxView
* omnibox
=
153 browser()->window()->GetLocationBar()->GetOmniboxView();
155 // Give the omnibox focus.
158 // Make sure that the AppList is not erronously displayed and the omnibox
159 // doesn't lost focus
160 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
161 EXPECT_TRUE(omnibox
->GetNativeView()->HasFocus());
164 SendKeyPress(ui::VKEY_F
);
165 SendKeyPress(ui::VKEY_O
);
166 SendKeyPress(ui::VKEY_O
);
168 // Verify the location of the caret.
170 omnibox
->GetSelectionBounds(&start
, &end
);
171 ASSERT_EQ(3U, start
);
174 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
175 EXPECT_TRUE(omnibox
->GetNativeView()->HasFocus());
177 // Hit Home by sequencing Search (left Windows) and Left (arrow).
178 SendKeyPress(ui::VKEY_LWIN
);
179 SendKeyPress(ui::VKEY_LEFT
);
181 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
182 EXPECT_TRUE(omnibox
->GetNativeView()->HasFocus());
184 // Verify caret moved to the beginning.
185 omnibox
->GetSelectionBounds(&start
, &end
);
186 ASSERT_EQ(0U, start
);
190 IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest
, OverlayShown
) {
191 const ui::KeyboardCode modifier_keys
[] = { ui::VKEY_CONTROL
,
196 // Overlay should not be visible if sticky keys is not enabled.
197 ash::StickyKeysController
* controller
=
198 ash::Shell::GetInstance()->sticky_keys_controller();
199 EXPECT_FALSE(controller
->GetOverlayForTest());
200 for (auto key_code
: modifier_keys
) {
201 SendKeyPress(key_code
);
202 EXPECT_FALSE(controller
->GetOverlayForTest());
205 // Cycle through the modifier keys and make sure each gets shown.
207 ash::StickyKeysOverlay
* sticky_keys_overlay
= controller
->GetOverlayForTest();
208 for (auto key_code
: modifier_keys
) {
209 SendKeyPress(key_code
);
210 EXPECT_TRUE(sticky_keys_overlay
->is_visible());
211 SendKeyPress(key_code
);
212 EXPECT_TRUE(sticky_keys_overlay
->is_visible());
213 SendKeyPress(key_code
);
214 EXPECT_FALSE(sticky_keys_overlay
->is_visible());
217 // Disabling sticky keys should hide the overlay.
218 SendKeyPress(ui::VKEY_CONTROL
);
219 EXPECT_TRUE(sticky_keys_overlay
->is_visible());
221 EXPECT_FALSE(controller
->GetOverlayForTest());
222 for (auto key_code
: modifier_keys
) {
223 SendKeyPress(key_code
);
224 EXPECT_FALSE(controller
->GetOverlayForTest());
228 } // namespace chromeos