spoken_feedback_browsertest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1// Copyright 2014 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 <queue>
6
7#include "ash/shell.h"
8#include "ash/system/tray/system_tray.h"
9#include "base/command_line.h"
10#include "base/strings/string_util.h"
11#include "chrome/app/chrome_command_ids.h"
12#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
13#include "chrome/browser/chromeos/accessibility/speech_monitor.h"
14#include "chrome/browser/chromeos/login/ui/login_display_host.h"
15#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
16#include "chrome/browser/chromeos/login/ui/webui_login_view.h"
17#include "chrome/browser/chromeos/profiles/profile_helper.h"
18#include "chrome/browser/extensions/api/braille_display_private/stub_braille_controller.h"
19#include "chrome/browser/speech/tts_controller.h"
20#include "chrome/browser/speech/tts_platform.h"
21#include "chrome/browser/ui/browser.h"
22#include "chrome/browser/ui/browser_commands.h"
23#include "chrome/browser/ui/browser_window.h"
24#include "chrome/common/chrome_switches.h"
25#include "chrome/common/extensions/extension_constants.h"
26#include "chrome/test/base/in_process_browser_test.h"
27#include "chrome/test/base/interactive_test_utils.h"
28#include "chrome/test/base/testing_profile.h"
29#include "chrome/test/base/ui_test_utils.h"
30#include "chromeos/chromeos_switches.h"
31#include "chromeos/login/user_names.h"
32#include "content/public/common/url_constants.h"
33#include "content/public/test/browser_test_utils.h"
34#include "content/public/test/test_utils.h"
35#include "extensions/browser/extension_host.h"
36#include "extensions/browser/process_manager.h"
37#include "testing/gtest/include/gtest/gtest.h"
38#include "ui/base/test/ui_controls.h"
39#include "ui/views/widget/widget.h"
40
41using extensions::api::braille_display_private::StubBrailleController;
42
43namespace chromeos {
44
45//
46// Spoken feedback tests only in a logged in user's window.
47//
48
49class LoggedInSpokenFeedbackTest : public InProcessBrowserTest {
50 protected:
51  LoggedInSpokenFeedbackTest() {}
52  virtual ~LoggedInSpokenFeedbackTest() {}
53
54  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
55    AccessibilityManager::SetBrailleControllerForTest(&braille_controller_);
56  }
57
58  virtual void TearDownOnMainThread() OVERRIDE {
59    AccessibilityManager::SetBrailleControllerForTest(NULL);
60  }
61
62  void SendKeyPress(ui::KeyboardCode key) {
63    gfx::NativeWindow root_window =
64        ash::Shell::GetInstance()->GetPrimaryRootWindow();
65    ASSERT_TRUE(
66        ui_test_utils::SendKeyPressToWindowSync(
67            root_window, key, false, false, false, false));
68  }
69
70  void SimulateTouchScreenInChromeVox() {
71    // ChromeVox looks at whether 'ontouchstart' exists to know whether
72    // or not it should respond to hover events. Fake it so that touch
73    // exploration events get spoken.
74    extensions::ExtensionHost* host =
75        extensions::ExtensionSystem::Get(browser()->profile())->
76        process_manager()->GetBackgroundHostForExtension(
77            extension_misc::kChromeVoxExtensionId);
78    CHECK(content::ExecuteScript(
79        host->host_contents(),
80        "window.ontouchstart = function() {};"));
81  }
82
83 private:
84  StubBrailleController braille_controller_;
85  DISALLOW_COPY_AND_ASSIGN(LoggedInSpokenFeedbackTest);
86};
87
88// http://crbug.com/396507
89IN_PROC_BROWSER_TEST_F(LoggedInSpokenFeedbackTest, DISABLED_AddBookmark) {
90  EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
91
92  SpeechMonitor monitor;
93  AccessibilityManager::Get()->EnableSpokenFeedback(
94      true, ash::A11Y_NOTIFICATION_NONE);
95  EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
96
97  chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR);
98
99  // Create a bookmark with title "foo".
100  chrome::ExecuteCommand(browser(), IDC_BOOKMARK_PAGE);
101  EXPECT_EQ("Bookmark added!,", monitor.GetNextUtterance());
102  EXPECT_EQ("about blank,", monitor.GetNextUtterance());
103  EXPECT_EQ("Bookmark name,", monitor.GetNextUtterance());
104  EXPECT_EQ("text box", monitor.GetNextUtterance());
105
106  SendKeyPress(ui::VKEY_F);
107  EXPECT_EQ("f", monitor.GetNextUtterance());
108  SendKeyPress(ui::VKEY_O);
109  EXPECT_EQ("o", monitor.GetNextUtterance());
110  SendKeyPress(ui::VKEY_O);
111  EXPECT_EQ("o", monitor.GetNextUtterance());
112
113  SendKeyPress(ui::VKEY_TAB);
114  EXPECT_EQ("Bookmarks bar,", monitor.GetNextUtterance());
115  EXPECT_EQ("Bookmark folder,", monitor.GetNextUtterance());
116  EXPECT_TRUE(MatchPattern(monitor.GetNextUtterance(), "combo box*"));
117
118  SendKeyPress(ui::VKEY_RETURN);
119
120  EXPECT_TRUE(MatchPattern(monitor.GetNextUtterance(), "*oolbar*"));
121  // Wait for active window change to be announced to avoid interference from
122  // that below.
123  while (monitor.GetNextUtterance() != "window about blank tab") {
124    // Do nothing.
125  }
126
127  // Focus bookmarks bar and listen for "foo".
128  chrome::ExecuteCommand(browser(), IDC_FOCUS_BOOKMARKS);
129  while (true) {
130    std::string utterance = monitor.GetNextUtterance();
131    VLOG(0) << "Got utterance: " << utterance;
132    if (utterance == "Bookmarks,")
133      break;
134  }
135  EXPECT_EQ("foo,", monitor.GetNextUtterance());
136  EXPECT_EQ("button", monitor.GetNextUtterance());
137}
138
139//
140// Spoken feedback tests in both a logged in browser window and guest mode.
141//
142
143enum SpokenFeedbackTestVariant {
144  kTestAsNormalUser,
145  kTestAsGuestUser
146};
147
148class SpokenFeedbackTest
149    : public LoggedInSpokenFeedbackTest,
150      public ::testing::WithParamInterface<SpokenFeedbackTestVariant> {
151 protected:
152  SpokenFeedbackTest() {}
153  virtual ~SpokenFeedbackTest() {}
154
155  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
156    if (GetParam() == kTestAsGuestUser) {
157      command_line->AppendSwitch(chromeos::switches::kGuestSession);
158      command_line->AppendSwitch(::switches::kIncognito);
159      command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
160                                      "user");
161      command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
162                                      chromeos::login::kGuestUserName);
163    }
164  }
165};
166
167INSTANTIATE_TEST_CASE_P(
168    TestAsNormalAndGuestUser,
169    SpokenFeedbackTest,
170    ::testing::Values(kTestAsNormalUser,
171                      kTestAsGuestUser));
172
173IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, EnableSpokenFeedback) {
174  EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
175
176  SpeechMonitor monitor;
177  AccessibilityManager::Get()->EnableSpokenFeedback(
178      true, ash::A11Y_NOTIFICATION_NONE);
179  EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
180}
181
182IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, FocusToolbar) {
183  EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
184
185  SpeechMonitor monitor;
186  AccessibilityManager::Get()->EnableSpokenFeedback(
187      true, ash::A11Y_NOTIFICATION_NONE);
188  EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
189
190  chrome::ExecuteCommand(browser(), IDC_FOCUS_TOOLBAR);
191  // Might be "Google Chrome Toolbar" or "Chromium Toolbar".
192  EXPECT_TRUE(MatchPattern(monitor.GetNextUtterance(), "*oolbar*"));
193  EXPECT_EQ("Reload,", monitor.GetNextUtterance());
194  EXPECT_EQ("button", monitor.GetNextUtterance());
195}
196
197IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, TypeInOmnibox) {
198  EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
199
200  SpeechMonitor monitor;
201  AccessibilityManager::Get()->EnableSpokenFeedback(
202      true, ash::A11Y_NOTIFICATION_NONE);
203  EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
204
205  // Wait for ChromeVox to finish speaking.
206  chrome::ExecuteCommand(browser(), IDC_FOCUS_LOCATION);
207  while (true) {
208    std::string utterance = monitor.GetNextUtterance();
209    VLOG(0) << "Got utterance: " << utterance;
210    if (utterance == "text box")
211      break;
212  }
213
214  SendKeyPress(ui::VKEY_X);
215  EXPECT_EQ("x", monitor.GetNextUtterance());
216
217  SendKeyPress(ui::VKEY_Y);
218  EXPECT_EQ("y", monitor.GetNextUtterance());
219
220  SendKeyPress(ui::VKEY_Z);
221  EXPECT_EQ("z", monitor.GetNextUtterance());
222
223  SendKeyPress(ui::VKEY_BACK);
224  EXPECT_EQ("z", monitor.GetNextUtterance());
225}
226
227IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, TouchExploreStatusTray) {
228  EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
229
230  SpeechMonitor monitor;
231  AccessibilityManager::Get()->EnableSpokenFeedback(
232      true, ash::A11Y_NOTIFICATION_NONE);
233  EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
234
235  SimulateTouchScreenInChromeVox();
236
237  // Send an accessibility hover event on the system tray, which is
238  // what we get when you tap it on a touch screen when ChromeVox is on.
239  ash::SystemTray* tray = ash::Shell::GetInstance()->GetPrimarySystemTray();
240  tray->NotifyAccessibilityEvent(ui::AX_EVENT_HOVER, true);
241
242  EXPECT_EQ("Status tray,", monitor.GetNextUtterance());
243  EXPECT_TRUE(MatchPattern(monitor.GetNextUtterance(), "time*,"));
244  EXPECT_TRUE(MatchPattern(monitor.GetNextUtterance(), "Battery*,"));
245  EXPECT_EQ("button", monitor.GetNextUtterance());
246}
247
248//
249// Spoken feedback tests that run only in guest mode.
250//
251
252class GuestSpokenFeedbackTest : public LoggedInSpokenFeedbackTest {
253 protected:
254  GuestSpokenFeedbackTest() {}
255  virtual ~GuestSpokenFeedbackTest() {}
256
257  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
258    command_line->AppendSwitch(chromeos::switches::kGuestSession);
259    command_line->AppendSwitch(::switches::kIncognito);
260    command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user");
261    command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
262                                    chromeos::login::kGuestUserName);
263  }
264
265 private:
266  DISALLOW_COPY_AND_ASSIGN(GuestSpokenFeedbackTest);
267};
268
269IN_PROC_BROWSER_TEST_F(GuestSpokenFeedbackTest, FocusToolbar) {
270  EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
271
272  SpeechMonitor monitor;
273  AccessibilityManager::Get()->EnableSpokenFeedback(
274      true, ash::A11Y_NOTIFICATION_NONE);
275  EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
276
277  chrome::ExecuteCommand(browser(), IDC_FOCUS_TOOLBAR);
278  // Might be "Google Chrome Toolbar" or "Chromium Toolbar".
279  EXPECT_TRUE(MatchPattern(monitor.GetNextUtterance(), "*oolbar*"));
280  EXPECT_EQ("Reload,", monitor.GetNextUtterance());
281  EXPECT_EQ("button", monitor.GetNextUtterance());
282}
283
284//
285// Spoken feedback tests of the out-of-box experience.
286//
287
288class OobeSpokenFeedbackTest : public InProcessBrowserTest {
289 protected:
290  OobeSpokenFeedbackTest() {}
291  virtual ~OobeSpokenFeedbackTest() {}
292
293  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
294    command_line->AppendSwitch(chromeos::switches::kLoginManager);
295    command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
296    command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user");
297  }
298
299  virtual void SetUpOnMainThread() OVERRIDE {
300    AccessibilityManager::Get()->
301        SetProfileForTest(ProfileHelper::GetSigninProfile());
302  }
303
304 private:
305  DISALLOW_COPY_AND_ASSIGN(OobeSpokenFeedbackTest);
306};
307
308// Test is flaky: http://crbug.com/346797
309IN_PROC_BROWSER_TEST_F(OobeSpokenFeedbackTest, DISABLED_SpokenFeedbackInOobe) {
310  ui_controls::EnableUIControls();
311  EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
312
313  LoginDisplayHost* login_display_host = LoginDisplayHostImpl::default_host();
314  WebUILoginView* web_ui_login_view = login_display_host->GetWebUILoginView();
315  views::Widget* widget = web_ui_login_view->GetWidget();
316  gfx::NativeWindow window = widget->GetNativeWindow();
317
318  SpeechMonitor monitor;
319  AccessibilityManager::Get()->EnableSpokenFeedback(
320      true, ash::A11Y_NOTIFICATION_NONE);
321  EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
322
323  EXPECT_EQ("Select your language:", monitor.GetNextUtterance());
324  EXPECT_EQ("English ( United States)", monitor.GetNextUtterance());
325  EXPECT_TRUE(MatchPattern(monitor.GetNextUtterance(), "Combo box * of *"));
326  ASSERT_TRUE(
327      ui_test_utils::SendKeyPressToWindowSync(
328          window, ui::VKEY_TAB, false, false, false, false));
329  EXPECT_EQ("Select your keyboard:", monitor.GetNextUtterance());
330}
331
332}  // namespace chromeos
333