Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / browser_keyevents_browsertest.cc
blob724dbeacb4f1d18757f14d01b2e45ed3f42f49f5
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.
5 #include "build/build_config.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/test/base/in_process_browser_test.h"
18 #include "chrome/test/base/interactive_test_utils.h"
19 #include "chrome/test/base/ui_test_utils.h"
20 #include "content/public/browser/dom_operation_notification_details.h"
21 #include "content/public/browser/notification_registrar.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/render_view_host.h"
24 #include "content/public/browser/render_widget_host_view.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/browser/web_contents_view.h"
27 #include "content/public/test/browser_test_utils.h"
28 #include "net/test/embedded_test_server/embedded_test_server.h"
29 #include "ui/events/keycodes/keyboard_codes.h"
31 // TODO(kbr): remove: http://crbug.com/222296
32 #if defined(OS_MACOSX)
33 #import "base/mac/mac_util.h"
34 #endif
36 using content::DomOperationNotificationDetails;
37 using content::NavigationController;
38 using content::RenderViewHost;
40 namespace {
42 const char kTestingPage[] = "/keyevents_test.html";
43 const char kSuppressEventJS[] =
44 "window.domAutomationController.send(setDefaultAction('%ls', %ls));";
45 const char kGetResultJS[] =
46 "window.domAutomationController.send(keyEventResult[%d]);";
47 const char kGetResultLengthJS[] =
48 "window.domAutomationController.send(keyEventResult.length);";
49 const char kGetFocusedElementJS[] =
50 "window.domAutomationController.send(focusedElement);";
51 const char kSetFocusedElementJS[] =
52 "window.domAutomationController.send(setFocusedElement('%ls'));";
53 const char kGetTextBoxValueJS[] =
54 "window.domAutomationController.send("
55 " document.getElementById('%ls').value);";
56 const char kSetTextBoxValueJS[] =
57 "window.domAutomationController.send("
58 " document.getElementById('%ls').value = '%ls');";
59 const char kStartTestJS[] =
60 "window.domAutomationController.send(startTest(%d));";
62 // Maximum lenght of the result array in KeyEventTestData structure.
63 const size_t kMaxResultLength = 10;
65 // A structure holding test data of a keyboard event.
66 // Each keyboard event may generate multiple result strings representing
67 // the result of keydown, keypress, keyup and textInput events.
68 // For keydown, keypress and keyup events, the format of the result string is:
69 // <type> <keyCode> <charCode> <ctrlKey> <shiftKey> <altKey> <commandKey>
70 // where <type> may be 'D' (keydown), 'P' (keypress) or 'U' (keyup).
71 // <ctrlKey>, <shiftKey> <altKey> and <commandKey> are boolean value indicating
72 // the state of corresponding modifier key.
73 // For textInput event, the format is: T <text>, where <text> is the text to be
74 // input.
75 // Please refer to chrome/test/data/keyevents_test.html for details.
76 struct KeyEventTestData {
77 ui::KeyboardCode key;
78 bool ctrl;
79 bool shift;
80 bool alt;
81 bool command;
83 bool suppress_keydown;
84 bool suppress_keypress;
85 bool suppress_keyup;
86 bool suppress_textinput;
88 int result_length;
89 const char* const result[kMaxResultLength];
92 const wchar_t* GetBoolString(bool value) {
93 return value ? L"true" : L"false";
96 // A class to help wait for the finish of a key event test.
97 class TestFinishObserver : public content::NotificationObserver {
98 public:
99 explicit TestFinishObserver(RenderViewHost* render_view_host)
100 : finished_(false), waiting_(false) {
101 registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE,
102 content::Source<RenderViewHost>(render_view_host));
105 bool WaitForFinish() {
106 if (!finished_) {
107 waiting_ = true;
108 content::RunMessageLoop();
109 waiting_ = false;
111 return finished_;
114 virtual void Observe(int type,
115 const content::NotificationSource& source,
116 const content::NotificationDetails& details) OVERRIDE {
117 DCHECK(type == content::NOTIFICATION_DOM_OPERATION_RESPONSE);
118 content::Details<DomOperationNotificationDetails> dom_op_details(details);
119 // We might receive responses for other script execution, but we only
120 // care about the test finished message.
121 if (dom_op_details->json == "\"FINISHED\"") {
122 finished_ = true;
123 if (waiting_)
124 base::MessageLoopForUI::current()->Quit();
128 private:
129 bool finished_;
130 bool waiting_;
131 content::NotificationRegistrar registrar_;
133 DISALLOW_COPY_AND_ASSIGN(TestFinishObserver);
136 class BrowserKeyEventsTest : public InProcessBrowserTest {
137 public:
138 BrowserKeyEventsTest() {}
140 bool IsViewFocused(ViewID vid) {
141 return ui_test_utils::IsViewFocused(browser(), vid);
144 void ClickOnView(ViewID vid) {
145 ui_test_utils::ClickOnView(browser(), vid);
148 // Set the suppress flag of an event specified by |type|. If |suppress| is
149 // true then the web page will suppress all events with |type|. Following
150 // event types are supported: keydown, keypress, keyup and textInput.
151 void SuppressEventByType(int tab_index, const wchar_t* type, bool suppress) {
152 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
153 bool actual;
154 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
155 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
156 base::StringPrintf(kSuppressEventJS, type, GetBoolString(!suppress)),
157 &actual));
158 ASSERT_EQ(!suppress, actual);
161 void SuppressEvents(int tab_index, bool keydown, bool keypress,
162 bool keyup, bool textinput) {
163 ASSERT_NO_FATAL_FAILURE(
164 SuppressEventByType(tab_index, L"keydown", keydown));
165 ASSERT_NO_FATAL_FAILURE(
166 SuppressEventByType(tab_index, L"keypress", keypress));
167 ASSERT_NO_FATAL_FAILURE(
168 SuppressEventByType(tab_index, L"keyup", keyup));
169 ASSERT_NO_FATAL_FAILURE(
170 SuppressEventByType(tab_index, L"textInput", textinput));
173 void SuppressAllEvents(int tab_index, bool suppress) {
174 SuppressEvents(tab_index, suppress, suppress, suppress, suppress);
177 void GetResultLength(int tab_index, int* length) {
178 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
179 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
180 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
181 kGetResultLengthJS,
182 length));
185 void CheckResult(int tab_index, int length, const char* const result[]) {
186 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
187 int actual_length;
188 ASSERT_NO_FATAL_FAILURE(GetResultLength(tab_index, &actual_length));
189 ASSERT_GE(actual_length, length);
190 for (int i = 0; i < actual_length; ++i) {
191 std::string actual;
192 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
193 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
194 base::StringPrintf(kGetResultJS, i),
195 &actual));
197 // If more events were received than expected, then the additional events
198 // must be keyup events.
199 if (i < length)
200 ASSERT_STREQ(result[i], actual.c_str());
201 else
202 ASSERT_EQ('U', actual[0]);
206 void CheckFocusedElement(int tab_index, const wchar_t* focused) {
207 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
208 std::string actual;
209 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
210 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
211 kGetFocusedElementJS,
212 &actual));
213 ASSERT_EQ(base::WideToUTF8(focused), actual);
216 void SetFocusedElement(int tab_index, const wchar_t* focused) {
217 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
218 bool actual;
219 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
220 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
221 base::StringPrintf(kSetFocusedElementJS, focused),
222 &actual));
223 ASSERT_TRUE(actual);
226 void CheckTextBoxValue(int tab_index, const wchar_t* id,
227 const wchar_t* value) {
228 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
229 std::string actual;
230 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
231 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
232 base::StringPrintf(kGetTextBoxValueJS, id),
233 &actual));
234 ASSERT_EQ(base::WideToUTF8(value), actual);
237 void SetTextBoxValue(int tab_index, const wchar_t* id,
238 const wchar_t* value) {
239 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
240 std::string actual;
241 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
242 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
243 base::StringPrintf(kSetTextBoxValueJS, id, value),
244 &actual));
245 ASSERT_EQ(base::WideToUTF8(value), actual);
248 void StartTest(int tab_index, int result_length) {
249 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
250 bool actual;
251 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
252 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
253 base::StringPrintf(kStartTestJS, result_length),
254 &actual));
255 ASSERT_TRUE(actual);
258 void TestKeyEvent(int tab_index, const KeyEventTestData& test) {
259 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
260 ASSERT_EQ(tab_index, browser()->tab_strip_model()->active_index());
262 // Inform our testing web page that we are about to start testing a key
263 // event.
264 ASSERT_NO_FATAL_FAILURE(StartTest(tab_index, test.result_length));
265 ASSERT_NO_FATAL_FAILURE(SuppressEvents(
266 tab_index, test.suppress_keydown, test.suppress_keypress,
267 test.suppress_keyup, test.suppress_textinput));
269 // We need to create a finish observer before sending the key event,
270 // because the test finished message might be arrived before returning
271 // from the SendKeyPressSync() method.
272 TestFinishObserver finish_observer(
273 browser()->tab_strip_model()->GetWebContentsAt(tab_index)->
274 GetRenderViewHost());
276 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
277 browser(), test.key, test.ctrl, test.shift, test.alt, test.command));
278 ASSERT_TRUE(finish_observer.WaitForFinish());
279 ASSERT_NO_FATAL_FAILURE(CheckResult(
280 tab_index, test.result_length, test.result));
283 std::string GetTestDataDescription(const KeyEventTestData& data) {
284 std::string desc = base::StringPrintf(
285 " VKEY:0x%02x, ctrl:%d, shift:%d, alt:%d, command:%d\n"
286 " Suppress: keydown:%d, keypress:%d, keyup:%d, textInput:%d\n"
287 " Expected results(%d):\n",
288 data.key, data.ctrl, data.shift, data.alt, data.command,
289 data.suppress_keydown, data.suppress_keypress, data.suppress_keyup,
290 data.suppress_textinput, data.result_length);
291 for (int i = 0; i < data.result_length; ++i) {
292 desc.append(" ");
293 desc.append(data.result[i]);
294 desc.append("\n");
296 return desc;
300 // Flaky: http://crbug.com/129235, http://crbug.com/81451.
301 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, DISABLED_NormalKeyEvents) {
302 static const KeyEventTestData kTestNoInput[] = {
303 // a
304 { ui::VKEY_A, false, false, false, false,
305 false, false, false, false, 3,
306 { "D 65 0 false false false false",
307 "P 97 97 false false false false",
308 "U 65 0 false false false false" } },
309 // shift-a
310 { ui::VKEY_A, false, true, false, false,
311 false, false, false, false, 5,
312 { "D 16 0 false true false false",
313 "D 65 0 false true false false",
314 "P 65 65 false true false false",
315 "U 65 0 false true false false",
316 "U 16 0 false true false false" } },
317 // a, suppress keydown
318 { ui::VKEY_A, false, false, false, false,
319 true, false, false, false, 2,
320 { "D 65 0 false false false false",
321 "U 65 0 false false false false" } },
324 static const KeyEventTestData kTestWithInput[] = {
325 // a
326 { ui::VKEY_A, false, false, false, false,
327 false, false, false, false, 4,
328 { "D 65 0 false false false false",
329 "P 97 97 false false false false",
330 "T a",
331 "U 65 0 false false false false" } },
332 // shift-a
333 { ui::VKEY_A, false, true, false, false,
334 false, false, false, false, 6,
335 { "D 16 0 false true false false",
336 "D 65 0 false true false false",
337 "P 65 65 false true false false",
338 "T A",
339 "U 65 0 false true false false",
340 "U 16 0 false true false false" } },
341 // a, suppress keydown
342 { ui::VKEY_A, false, false, false, false,
343 true, false, false, false, 2,
344 { "D 65 0 false false false false",
345 "U 65 0 false false false false" } },
346 // a, suppress keypress
347 { ui::VKEY_A, false, false, false, false,
348 false, true, false, false, 3,
349 { "D 65 0 false false false false",
350 "P 97 97 false false false false",
351 "U 65 0 false false false false" } },
352 // a, suppress textInput
353 { ui::VKEY_A, false, false, false, false,
354 false, false, false, true, 4,
355 { "D 65 0 false false false false",
356 "P 97 97 false false false false",
357 "T a",
358 "U 65 0 false false false false" } },
361 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
363 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
364 GURL url = embedded_test_server()->GetURL(kTestingPage);
365 ui_test_utils::NavigateToURL(browser(), url);
367 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
368 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
370 int tab_index = browser()->tab_strip_model()->active_index();
371 for (size_t i = 0; i < arraysize(kTestNoInput); ++i) {
372 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestNoInput[i]))
373 << "kTestNoInput[" << i << "] failed:\n"
374 << GetTestDataDescription(kTestNoInput[i]);
377 // Input in normal text box.
378 ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
379 for (size_t i = 0; i < arraysize(kTestWithInput); ++i) {
380 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestWithInput[i]))
381 << "kTestWithInput[" << i << "] in text box failed:\n"
382 << GetTestDataDescription(kTestWithInput[i]);
384 EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"A", L"aA"));
386 // Input in password box.
387 ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"B"));
388 for (size_t i = 0; i < arraysize(kTestWithInput); ++i) {
389 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestWithInput[i]))
390 << "kTestWithInput[" << i << "] in password box failed:\n"
391 << GetTestDataDescription(kTestWithInput[i]);
393 EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"B", L"aA"));
396 #if defined(OS_WIN) || defined(OS_LINUX)
398 #if defined(OS_LINUX) || (defined(OS_WIN) && defined(USE_AURA))
399 // Linux: http://crbug.com/129235
400 // Win Aura: crbug.com/269564
401 #define MAYBE_CtrlKeyEvents DISABLED_CtrlKeyEvents
402 #else
403 #define MAYBE_CtrlKeyEvents CtrlKeyEvents
404 #endif
406 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, MAYBE_CtrlKeyEvents) {
407 static const KeyEventTestData kTestCtrlF = {
408 ui::VKEY_F, true, false, false, false,
409 false, false, false, false, 2,
410 { "D 17 0 true false false false",
411 "D 70 0 true false false false" }
414 static const KeyEventTestData kTestCtrlFSuppressKeyDown = {
415 ui::VKEY_F, true, false, false, false,
416 true, false, false, false, 4,
417 { "D 17 0 true false false false",
418 "D 70 0 true false false false",
419 "U 70 0 true false false false",
420 "U 17 0 true false false false" }
423 // Ctrl+Z doesn't bind to any accelerators, which then should generate a
424 // keypress event with charCode=26.
425 static const KeyEventTestData kTestCtrlZ = {
426 ui::VKEY_Z, true, false, false, false,
427 false, false, false, false, 5,
428 { "D 17 0 true false false false",
429 "D 90 0 true false false false",
430 "P 26 26 true false false false",
431 "U 90 0 true false false false",
432 "U 17 0 true false false false" }
435 static const KeyEventTestData kTestCtrlZSuppressKeyDown = {
436 ui::VKEY_Z, true, false, false, false,
437 true, false, false, false, 4,
438 { "D 17 0 true false false false",
439 "D 90 0 true false false false",
440 "U 90 0 true false false false",
441 "U 17 0 true false false false" }
444 // Ctrl+Enter shall generate a keypress event with charCode=10 (LF).
445 static const KeyEventTestData kTestCtrlEnter = {
446 ui::VKEY_RETURN, true, false, false, false,
447 false, false, false, false, 5,
448 { "D 17 0 true false false false",
449 "D 13 0 true false false false",
450 "P 10 10 true false false false",
451 "U 13 0 true false false false",
452 "U 17 0 true false false false" }
455 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
457 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
458 GURL url = embedded_test_server()->GetURL(kTestingPage);
459 ui_test_utils::NavigateToURL(browser(), url);
461 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
462 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
464 int tab_index = browser()->tab_strip_model()->active_index();
465 // Press Ctrl+F, which will make the Find box open and request focus.
466 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlF));
467 EXPECT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
469 // Press Escape to close the Find box and move the focus back to the web page.
470 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
471 browser(), ui::VKEY_ESCAPE, false, false, false, false));
472 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
474 // Press Ctrl+F with keydown suppressed shall not open the find box.
475 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlFSuppressKeyDown));
476 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
478 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlZ));
479 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlZSuppressKeyDown));
480 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlEnter));
482 #elif defined(OS_MACOSX)
483 // http://crbug.com/81451
484 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, DISABLED_CommandKeyEvents) {
485 static const KeyEventTestData kTestCmdF = {
486 ui::VKEY_F, false, false, false, true,
487 false, false, false, false, 2,
488 { "D 91 0 false false false true",
489 "D 70 0 false false false true" }
492 // On Mac we don't send key up events when command modifier is down.
493 static const KeyEventTestData kTestCmdFSuppressKeyDown = {
494 ui::VKEY_F, false, false, false, true,
495 true, false, false, false, 3,
496 { "D 91 0 false false false true",
497 "D 70 0 false false false true",
498 "U 91 0 false false false true" }
501 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
503 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
504 GURL url = embedded_test_server()->GetURL(kTestingPage);
505 ui_test_utils::NavigateToURL(browser(), url);
507 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
508 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
510 int tab_index = browser()->tab_strip_model()->active_index();
511 // Press Cmd+F, which will make the Find box open and request focus.
512 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCmdF));
513 EXPECT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
515 // Press Escape to close the Find box and move the focus back to the web page.
516 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
517 browser(), ui::VKEY_ESCAPE, false, false, false, false));
518 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
520 // Press Cmd+F with keydown suppressed shall not open the find box.
521 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCmdFSuppressKeyDown));
522 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
524 #endif
526 // Flaky: http://crbug.com/81451 , http://crbug.com/129235 ,
527 // also fails on Windows.
528 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, DISABLED_AccessKeys) {
529 #if defined(OS_MACOSX)
530 // On Mac, access keys use ctrl+alt modifiers.
531 static const KeyEventTestData kTestAccessA = {
532 ui::VKEY_A, true, false, true, false,
533 false, false, false, false, 6,
534 { "D 17 0 true false false false",
535 "D 18 0 true false true false",
536 "D 65 0 true false true false",
537 "U 65 0 true false true false",
538 "U 18 0 true false true false",
539 "U 17 0 true false false false" }
542 static const KeyEventTestData kTestAccessDSuppress = {
543 ui::VKEY_D, true, false, true, false,
544 true, true, true, false, 6,
545 { "D 17 0 true false false false",
546 "D 18 0 true false true false",
547 "D 68 0 true false true false",
548 "U 68 0 true false true false",
549 "U 18 0 true false true false",
550 "U 17 0 true false false false" }
553 static const KeyEventTestData kTestAccess1 = {
554 ui::VKEY_1, true, false, true, false,
555 false, false, false, false, 6,
556 { "D 17 0 true false false false",
557 "D 18 0 true false true false",
558 "D 49 0 true false true false",
559 "U 49 0 true false true false",
560 "U 18 0 true false true false",
561 "U 17 0 true false false false" }
563 #else
564 static const KeyEventTestData kTestAccessA = {
565 ui::VKEY_A, false, false, true, false,
566 false, false, false, false, 4,
567 { "D 18 0 false false true false",
568 "D 65 0 false false true false",
569 "U 65 0 false false true false",
570 "U 18 0 false false true false" }
573 static const KeyEventTestData kTestAccessD = {
574 ui::VKEY_D, false, false, true, false,
575 false, false, false, false, 2,
576 { "D 18 0 false false true false",
577 "D 68 0 false false true false" }
580 static const KeyEventTestData kTestAccessDSuppress = {
581 ui::VKEY_D, false, false, true, false,
582 true, true, true, false, 4,
583 { "D 18 0 false false true false",
584 "D 68 0 false false true false",
585 "U 68 0 false false true false",
586 "U 18 0 false false true false" }
589 #if !defined(USE_ASH)
590 static const KeyEventTestData kTestAccess1 = {
591 ui::VKEY_1, false, false, true, false,
592 false, false, false, false, 4,
593 { "D 18 0 false false true false",
594 "D 49 0 false false true false",
595 "U 49 0 false false true false",
596 "U 18 0 false false true false" }
598 #endif
599 #endif
601 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
603 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
604 GURL url = embedded_test_server()->GetURL(kTestingPage);
605 ui_test_utils::NavigateToURL(browser(), url);
607 content::RunAllPendingInMessageLoop();
608 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
609 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
611 int tab_index = browser()->tab_strip_model()->active_index();
612 // Make sure no element is focused.
613 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
614 // Alt+A should focus the element with accesskey = "A".
615 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccessA));
616 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L"A"));
618 // Blur the focused element.
619 EXPECT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L""));
620 // Make sure no element is focused.
621 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
623 #if !defined(OS_MACOSX)
624 // Alt+D should move the focus to the location entry.
625 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccessD));
627 // TODO(isherman): This is an experimental change to help diagnose
628 // http://crbug.com/55713
629 content::RunAllPendingInMessageLoop();
630 EXPECT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
631 // No element should be focused, as Alt+D was handled by the browser.
632 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
634 // Move the focus back to the web page.
635 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
636 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
638 // Make sure no element is focused.
639 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
640 #endif
642 // If the keydown event is suppressed, then Alt+D should be handled as an
643 // accesskey rather than an accelerator key. Activation of an accesskey is not
644 // a part of the default action of the key event, so it should not be
645 // suppressed at all.
646 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccessDSuppress));
647 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
648 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L"D"));
650 // Blur the focused element.
651 EXPECT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L""));
652 // Make sure no element is focused.
653 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
654 #if !defined(USE_ASH)
655 // On Ash, alt-1..9 are assigned as window selection global accelerators, so
656 // they can not be used as accesskeys.
657 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccess1));
658 #if defined(TOOLKIT_GTK)
659 // On GTK, alt-0..9 are assigned as tab selection accelerators, so they can
660 // not be used as accesskeys.
661 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
662 #else
663 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L"1"));
664 #endif
665 #endif
668 // Flaky, http://crbug.com/69475.
669 #if defined(OS_LINUX) || (defined(OS_WIN) && defined(USE_AURA))
670 #define MAYBE_ReservedAccelerators DISABLED_ReservedAccelerators
671 #else
672 #define MAYBE_ReservedAccelerators ReservedAccelerators
673 #endif
674 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, MAYBE_ReservedAccelerators) {
675 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
677 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
678 GURL url = embedded_test_server()->GetURL(kTestingPage);
679 ui_test_utils::NavigateToURL(browser(), url);
681 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
682 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
684 ASSERT_EQ(1, browser()->tab_strip_model()->count());
686 static const KeyEventTestData kTestCtrlOrCmdT = {
687 #if defined(OS_MACOSX)
688 ui::VKEY_T, false, false, false, true,
689 true, false, false, false, 1,
690 { "D 91 0 false false false true" }
691 #else
692 ui::VKEY_T, true, false, false, false,
693 true, false, false, false, 1,
694 { "D 17 0 true false false false" }
695 #endif
698 content::WindowedNotificationObserver wait_for_new_tab(
699 chrome::NOTIFICATION_TAB_PARENTED,
700 content::NotificationService::AllSources());
702 // Press Ctrl/Cmd+T, which will open a new tab. It cannot be suppressed.
703 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(0, kTestCtrlOrCmdT));
704 wait_for_new_tab.Wait();
706 int result_length;
707 ASSERT_NO_FATAL_FAILURE(GetResultLength(0, &result_length));
708 EXPECT_EQ(1, result_length);
710 EXPECT_EQ(2, browser()->tab_strip_model()->count());
711 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
713 // Because of issue <http://crbug.com/65375>, switching back to the first tab
714 // may cause the focus to be grabbed by omnibox. So instead, we load our
715 // testing page in the newly created tab and try Cmd-W here.
716 ui_test_utils::NavigateToURL(browser(), url);
718 // Make sure the focus is in the testing page.
719 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
720 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
722 // Reserved accelerators can't be suppressed.
723 ASSERT_NO_FATAL_FAILURE(SuppressAllEvents(1, true));
725 content::WebContentsDestroyedWatcher destroyed_watcher(
726 browser()->tab_strip_model()->GetWebContentsAt(1));
728 // Press Ctrl/Cmd+W, which will close the tab.
729 #if defined(OS_MACOSX)
730 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
731 browser(), ui::VKEY_W, false, false, false, true));
732 #else
733 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
734 browser(), ui::VKEY_W, true, false, false, false));
735 #endif
737 ASSERT_NO_FATAL_FAILURE(destroyed_watcher.Wait());
739 EXPECT_EQ(1, browser()->tab_strip_model()->count());
742 #if defined(OS_MACOSX)
743 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, EditorKeyBindings) {
744 // TODO(kbr): re-enable: http://crbug.com/222296
745 if (base::mac::IsOSMountainLionOrLater())
746 return;
748 static const KeyEventTestData kTestCtrlA = {
749 ui::VKEY_A, true, false, false, false,
750 false, false, false, false, 4,
751 { "D 17 0 true false false false",
752 "D 65 0 true false false false",
753 "U 65 0 true false false false",
754 "U 17 0 true false false false" }
757 static const KeyEventTestData kTestCtrlF = {
758 ui::VKEY_F, true, false, false, false,
759 false, false, false, false, 4,
760 { "D 17 0 true false false false",
761 "D 70 0 true false false false",
762 "U 70 0 true false false false",
763 "U 17 0 true false false false" }
766 static const KeyEventTestData kTestCtrlK = {
767 ui::VKEY_K, true, false, false, false,
768 false, false, false, false, 4,
769 { "D 17 0 true false false false",
770 "D 75 0 true false false false",
771 "U 75 0 true false false false",
772 "U 17 0 true false false false" }
775 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
777 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
778 GURL url = embedded_test_server()->GetURL(kTestingPage);
779 ui_test_utils::NavigateToURL(browser(), url);
781 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
782 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
784 int tab_index = browser()->tab_strip_model()->active_index();
785 ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
786 ASSERT_NO_FATAL_FAILURE(SetTextBoxValue(tab_index, L"A", L"Hello"));
787 // Move the caret to the beginning of the line.
788 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlA));
789 // Forward one character
790 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlF));
791 // Delete to the end of the line.
792 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlK));
793 EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"A", L"H"));
795 #endif
797 // See http://crbug.com/147579
798 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, DISABLED_PageUpDownKeys) {
799 static const KeyEventTestData kTestPageUp = {
800 ui::VKEY_PRIOR, false, false, false, false,
801 false, false, false, false, 2,
802 { "D 33 0 false false false false",
803 "U 33 0 false false false false" }
806 static const KeyEventTestData kTestPageDown = {
807 ui::VKEY_NEXT, false, false, false, false,
808 false, false, false, false, 2,
809 { "D 34 0 false false false false",
810 "U 34 0 false false false false" }
813 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
815 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
816 GURL url = embedded_test_server()->GetURL(kTestingPage);
817 ui_test_utils::NavigateToURL(browser(), url);
819 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
820 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
822 int tab_index = browser()->tab_strip_model()->active_index();
823 ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
824 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestPageUp));
825 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestPageDown));
826 EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"A", L""));
829 #if defined(OS_WIN)
830 // AltKey is enabled only on Windows. See crbug.com/114537.
831 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, FocusMenuBarByAltKey) {
832 static const KeyEventTestData kTestAltKey = {
833 ui::VKEY_MENU, false, false, false, false,
834 false, false, false, false, 2,
835 { "D 18 0 false false true false",
836 "U 18 0 false false true false" }
839 static const KeyEventTestData kTestAltKeySuppress = {
840 ui::VKEY_MENU, false, false, false, false,
841 true, false, false, false, 2,
842 { "D 18 0 false false true false",
843 "U 18 0 false false true false" }
846 static const KeyEventTestData kTestCtrlAltKey = {
847 ui::VKEY_MENU, true, false, false, false,
848 false, false, false, false, 4,
849 { "D 17 0 true false false false",
850 "D 18 0 true false true false",
851 "U 18 0 true false true false",
852 "U 17 0 true false false false" }
855 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
857 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
858 GURL url = embedded_test_server()->GetURL(kTestingPage);
859 ui_test_utils::NavigateToURL(browser(), url);
861 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
862 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
864 int tab_index = browser()->tab_strip_model()->active_index();
865 // Press and release Alt key to focus wrench menu button.
866 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAltKey));
867 EXPECT_TRUE(IsViewFocused(VIEW_ID_APP_MENU));
869 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
870 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
872 // Alt key can be suppressed.
873 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAltKeySuppress));
874 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
876 // Ctrl+Alt should have no effect.
877 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlAltKey));
878 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
880 #endif
882 } // namespace