Override server-side simple-cache trial with commandline switches.
[chromium-blink-merge.git] / chrome / browser / browser_keyevents_browsertest.cc
blob3641cc17823197985732e5dcac01f88875aaaddf
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.h"
10 #include "base/stringprintf.h"
11 #include "base/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/common/chrome_notification_types.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/spawned_test_server/spawned_test_server.h"
29 #include "ui/base/keycodes/keyboard_codes.h"
30 #include "ui/views/controls/textfield/textfield.h"
32 // TODO(kbr): remove: http://crbug.com/222296
33 #if defined(OS_MACOSX)
34 #import "base/mac/mac_util.h"
35 #endif
37 using content::DomOperationNotificationDetails;
38 using content::NavigationController;
39 using content::RenderViewHost;
41 namespace {
43 const char kTestingPage[] = "files/keyevents_test.html";
44 const char kSuppressEventJS[] =
45 "window.domAutomationController.send(setDefaultAction('%ls', %ls));";
46 const char kGetResultJS[] =
47 "window.domAutomationController.send(keyEventResult[%d]);";
48 const char kGetResultLengthJS[] =
49 "window.domAutomationController.send(keyEventResult.length);";
50 const char kGetFocusedElementJS[] =
51 "window.domAutomationController.send(focusedElement);";
52 const char kSetFocusedElementJS[] =
53 "window.domAutomationController.send(setFocusedElement('%ls'));";
54 const char kGetTextBoxValueJS[] =
55 "window.domAutomationController.send("
56 " document.getElementById('%ls').value);";
57 const char kSetTextBoxValueJS[] =
58 "window.domAutomationController.send("
59 " document.getElementById('%ls').value = '%ls');";
60 const char kStartTestJS[] =
61 "window.domAutomationController.send(startTest(%d));";
63 // Maximum lenght of the result array in KeyEventTestData structure.
64 const size_t kMaxResultLength = 10;
66 // A structure holding test data of a keyboard event.
67 // Each keyboard event may generate multiple result strings representing
68 // the result of keydown, keypress, keyup and textInput events.
69 // For keydown, keypress and keyup events, the format of the result string is:
70 // <type> <keyCode> <charCode> <ctrlKey> <shiftKey> <altKey> <commandKey>
71 // where <type> may be 'D' (keydown), 'P' (keypress) or 'U' (keyup).
72 // <ctrlKey>, <shiftKey> <altKey> and <commandKey> are boolean value indicating
73 // the state of corresponding modifier key.
74 // For textInput event, the format is: T <text>, where <text> is the text to be
75 // input.
76 // Please refer to chrome/test/data/keyevents_test.html for details.
77 struct KeyEventTestData {
78 ui::KeyboardCode key;
79 bool ctrl;
80 bool shift;
81 bool alt;
82 bool command;
84 bool suppress_keydown;
85 bool suppress_keypress;
86 bool suppress_keyup;
87 bool suppress_textinput;
89 int result_length;
90 const char* const result[kMaxResultLength];
93 const wchar_t* GetBoolString(bool value) {
94 return value ? L"true" : L"false";
97 // A class to help wait for the finish of a key event test.
98 class TestFinishObserver : public content::NotificationObserver {
99 public:
100 explicit TestFinishObserver(RenderViewHost* render_view_host)
101 : finished_(false), waiting_(false) {
102 registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE,
103 content::Source<RenderViewHost>(render_view_host));
106 bool WaitForFinish() {
107 if (!finished_) {
108 waiting_ = true;
109 content::RunMessageLoop();
110 waiting_ = false;
112 return finished_;
115 virtual void Observe(int type,
116 const content::NotificationSource& source,
117 const content::NotificationDetails& details) OVERRIDE {
118 DCHECK(type == content::NOTIFICATION_DOM_OPERATION_RESPONSE);
119 content::Details<DomOperationNotificationDetails> dom_op_details(details);
120 // We might receive responses for other script execution, but we only
121 // care about the test finished message.
122 if (dom_op_details->json == "\"FINISHED\"") {
123 finished_ = true;
124 if (waiting_)
125 MessageLoopForUI::current()->Quit();
129 private:
130 bool finished_;
131 bool waiting_;
132 content::NotificationRegistrar registrar_;
134 DISALLOW_COPY_AND_ASSIGN(TestFinishObserver);
137 class BrowserKeyEventsTest : public InProcessBrowserTest {
138 public:
139 BrowserKeyEventsTest() {}
141 bool IsViewFocused(ViewID vid) {
142 return ui_test_utils::IsViewFocused(browser(), vid);
145 void ClickOnView(ViewID vid) {
146 ui_test_utils::ClickOnView(browser(), vid);
149 // Set the suppress flag of an event specified by |type|. If |suppress| is
150 // true then the web page will suppress all events with |type|. Following
151 // event types are supported: keydown, keypress, keyup and textInput.
152 void SuppressEventByType(int tab_index, const wchar_t* type, bool suppress) {
153 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
154 bool actual;
155 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
156 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
157 base::StringPrintf(kSuppressEventJS, type, GetBoolString(!suppress)),
158 &actual));
159 ASSERT_EQ(!suppress, actual);
162 void SuppressEvents(int tab_index, bool keydown, bool keypress,
163 bool keyup, bool textinput) {
164 ASSERT_NO_FATAL_FAILURE(
165 SuppressEventByType(tab_index, L"keydown", keydown));
166 ASSERT_NO_FATAL_FAILURE(
167 SuppressEventByType(tab_index, L"keypress", keypress));
168 ASSERT_NO_FATAL_FAILURE(
169 SuppressEventByType(tab_index, L"keyup", keyup));
170 ASSERT_NO_FATAL_FAILURE(
171 SuppressEventByType(tab_index, L"textInput", textinput));
174 void SuppressAllEvents(int tab_index, bool suppress) {
175 SuppressEvents(tab_index, suppress, suppress, suppress, suppress);
178 void GetResultLength(int tab_index, int* length) {
179 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
180 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
181 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
182 kGetResultLengthJS,
183 length));
186 void CheckResult(int tab_index, int length, const char* const result[]) {
187 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
188 int actual_length;
189 ASSERT_NO_FATAL_FAILURE(GetResultLength(tab_index, &actual_length));
190 ASSERT_GE(actual_length, length);
191 for (int i = 0; i < actual_length; ++i) {
192 std::string actual;
193 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
194 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
195 base::StringPrintf(kGetResultJS, i),
196 &actual));
198 // If more events were received than expected, then the additional events
199 // must be keyup events.
200 if (i < length)
201 ASSERT_STREQ(result[i], actual.c_str());
202 else
203 ASSERT_EQ('U', actual[0]);
207 void CheckFocusedElement(int tab_index, const wchar_t* focused) {
208 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
209 std::string actual;
210 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
211 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
212 kGetFocusedElementJS,
213 &actual));
214 ASSERT_EQ(WideToUTF8(focused), actual);
217 void SetFocusedElement(int tab_index, const wchar_t* focused) {
218 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
219 bool actual;
220 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
221 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
222 base::StringPrintf(kSetFocusedElementJS, focused),
223 &actual));
224 ASSERT_TRUE(actual);
227 void CheckTextBoxValue(int tab_index, const wchar_t* id,
228 const wchar_t* value) {
229 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
230 std::string actual;
231 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
232 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
233 base::StringPrintf(kGetTextBoxValueJS, id),
234 &actual));
235 ASSERT_EQ(WideToUTF8(value), actual);
238 void SetTextBoxValue(int tab_index, const wchar_t* id,
239 const wchar_t* value) {
240 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
241 std::string actual;
242 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
243 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
244 base::StringPrintf(kSetTextBoxValueJS, id, value),
245 &actual));
246 ASSERT_EQ(WideToUTF8(value), actual);
249 void StartTest(int tab_index, int result_length) {
250 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
251 bool actual;
252 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
253 browser()->tab_strip_model()->GetWebContentsAt(tab_index),
254 base::StringPrintf(kStartTestJS, result_length),
255 &actual));
256 ASSERT_TRUE(actual);
259 void TestKeyEvent(int tab_index, const KeyEventTestData& test) {
260 ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
261 ASSERT_EQ(tab_index, browser()->tab_strip_model()->active_index());
263 // Inform our testing web page that we are about to start testing a key
264 // event.
265 ASSERT_NO_FATAL_FAILURE(StartTest(tab_index, test.result_length));
266 ASSERT_NO_FATAL_FAILURE(SuppressEvents(
267 tab_index, test.suppress_keydown, test.suppress_keypress,
268 test.suppress_keyup, test.suppress_textinput));
270 // We need to create a finish observer before sending the key event,
271 // because the test finished message might be arrived before returning
272 // from the SendKeyPressSync() method.
273 TestFinishObserver finish_observer(
274 browser()->tab_strip_model()->GetWebContentsAt(tab_index)->
275 GetRenderViewHost());
277 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
278 browser(), test.key, test.ctrl, test.shift, test.alt, test.command));
279 ASSERT_TRUE(finish_observer.WaitForFinish());
280 ASSERT_NO_FATAL_FAILURE(CheckResult(
281 tab_index, test.result_length, test.result));
284 std::string GetTestDataDescription(const KeyEventTestData& data) {
285 std::string desc = base::StringPrintf(
286 " VKEY:0x%02x, ctrl:%d, shift:%d, alt:%d, command:%d\n"
287 " Suppress: keydown:%d, keypress:%d, keyup:%d, textInput:%d\n"
288 " Expected results(%d):\n",
289 data.key, data.ctrl, data.shift, data.alt, data.command,
290 data.suppress_keydown, data.suppress_keypress, data.suppress_keyup,
291 data.suppress_textinput, data.result_length);
292 for (int i = 0; i < data.result_length; ++i) {
293 desc.append(" ");
294 desc.append(data.result[i]);
295 desc.append("\n");
297 return desc;
301 #if defined(OS_MACOSX)
302 // http://crbug.com/81451
303 #define MAYBE_NormalKeyEvents DISABLED_NormalKeyEvents
304 #elif defined(OS_LINUX)
305 // http://crbug.com/129235
306 #define MAYBE_NormalKeyEvents DISABLED_NormalKeyEvents
307 #else
308 #define MAYBE_NormalKeyEvents NormalKeyEvents
309 #endif
311 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, MAYBE_NormalKeyEvents) {
312 static const KeyEventTestData kTestNoInput[] = {
313 // a
314 { ui::VKEY_A, false, false, false, false,
315 false, false, false, false, 3,
316 { "D 65 0 false false false false",
317 "P 97 97 false false false false",
318 "U 65 0 false false false false" } },
319 // shift-a
320 { ui::VKEY_A, false, true, false, false,
321 false, false, false, false, 5,
322 { "D 16 0 false true false false",
323 "D 65 0 false true false false",
324 "P 65 65 false true false false",
325 "U 65 0 false true false false",
326 "U 16 0 false true false false" } },
327 // a, suppress keydown
328 { ui::VKEY_A, false, false, false, false,
329 true, false, false, false, 2,
330 { "D 65 0 false false false false",
331 "U 65 0 false false false false" } },
334 static const KeyEventTestData kTestWithInput[] = {
335 // a
336 { ui::VKEY_A, false, false, false, false,
337 false, false, false, false, 4,
338 { "D 65 0 false false false false",
339 "P 97 97 false false false false",
340 "T a",
341 "U 65 0 false false false false" } },
342 // shift-a
343 { ui::VKEY_A, false, true, false, false,
344 false, false, false, false, 6,
345 { "D 16 0 false true false false",
346 "D 65 0 false true false false",
347 "P 65 65 false true false false",
348 "T A",
349 "U 65 0 false true false false",
350 "U 16 0 false true false false" } },
351 // a, suppress keydown
352 { ui::VKEY_A, false, false, false, false,
353 true, false, false, false, 2,
354 { "D 65 0 false false false false",
355 "U 65 0 false false false false" } },
356 // a, suppress keypress
357 { ui::VKEY_A, false, false, false, false,
358 false, true, false, false, 3,
359 { "D 65 0 false false false false",
360 "P 97 97 false false false false",
361 "U 65 0 false false false false" } },
362 // a, suppress textInput
363 { ui::VKEY_A, false, false, false, false,
364 false, false, false, true, 4,
365 { "D 65 0 false false false false",
366 "P 97 97 false false false false",
367 "T a",
368 "U 65 0 false false false false" } },
371 ASSERT_TRUE(test_server()->Start());
373 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
374 GURL url = test_server()->GetURL(kTestingPage);
375 ui_test_utils::NavigateToURL(browser(), url);
377 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
378 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
380 int tab_index = browser()->tab_strip_model()->active_index();
381 for (size_t i = 0; i < arraysize(kTestNoInput); ++i) {
382 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestNoInput[i]))
383 << "kTestNoInput[" << i << "] failed:\n"
384 << GetTestDataDescription(kTestNoInput[i]);
387 // Input in normal text box.
388 ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
389 for (size_t i = 0; i < arraysize(kTestWithInput); ++i) {
390 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestWithInput[i]))
391 << "kTestWithInput[" << i << "] in text box failed:\n"
392 << GetTestDataDescription(kTestWithInput[i]);
394 EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"A", L"aA"));
396 // Input in password box.
397 ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"B"));
398 for (size_t i = 0; i < arraysize(kTestWithInput); ++i) {
399 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestWithInput[i]))
400 << "kTestWithInput[" << i << "] in password box failed:\n"
401 << GetTestDataDescription(kTestWithInput[i]);
403 EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"B", L"aA"));
406 #if defined(OS_WIN) || defined(OS_LINUX)
408 #if defined(OS_LINUX)
409 // http://crbug.com/129235
410 #define MAYBE_CtrlKeyEvents DISABLED_CtrlKeyEvents
411 #else
412 #define MAYBE_CtrlKeyEvents CtrlKeyEvents
413 #endif
415 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, MAYBE_CtrlKeyEvents) {
416 static const KeyEventTestData kTestCtrlF = {
417 ui::VKEY_F, true, false, false, false,
418 false, false, false, false, 2,
419 { "D 17 0 true false false false",
420 "D 70 0 true false false false" }
423 static const KeyEventTestData kTestCtrlFSuppressKeyDown = {
424 ui::VKEY_F, true, false, false, false,
425 true, false, false, false, 4,
426 { "D 17 0 true false false false",
427 "D 70 0 true false false false",
428 "U 70 0 true false false false",
429 "U 17 0 true false false false" }
432 // Ctrl+Z doesn't bind to any accelerators, which then should generate a
433 // keypress event with charCode=26.
434 static const KeyEventTestData kTestCtrlZ = {
435 ui::VKEY_Z, true, false, false, false,
436 false, false, false, false, 5,
437 { "D 17 0 true false false false",
438 "D 90 0 true false false false",
439 "P 26 26 true false false false",
440 "U 90 0 true false false false",
441 "U 17 0 true false false false" }
444 static const KeyEventTestData kTestCtrlZSuppressKeyDown = {
445 ui::VKEY_Z, true, false, false, false,
446 true, false, false, false, 4,
447 { "D 17 0 true false false false",
448 "D 90 0 true false false false",
449 "U 90 0 true false false false",
450 "U 17 0 true false false false" }
453 // Ctrl+Enter shall generate a keypress event with charCode=10 (LF).
454 static const KeyEventTestData kTestCtrlEnter = {
455 ui::VKEY_RETURN, true, false, false, false,
456 false, false, false, false, 5,
457 { "D 17 0 true false false false",
458 "D 13 0 true false false false",
459 "P 10 10 true false false false",
460 "U 13 0 true false false false",
461 "U 17 0 true false false false" }
464 ASSERT_TRUE(test_server()->Start());
466 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
467 GURL url = test_server()->GetURL(kTestingPage);
468 ui_test_utils::NavigateToURL(browser(), url);
470 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
471 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
473 int tab_index = browser()->tab_strip_model()->active_index();
474 // Press Ctrl+F, which will make the Find box open and request focus.
475 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlF));
476 EXPECT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
478 // Press Escape to close the Find box and move the focus back to the web page.
479 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
480 browser(), ui::VKEY_ESCAPE, false, false, false, false));
481 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
483 // Press Ctrl+F with keydown suppressed shall not open the find box.
484 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlFSuppressKeyDown));
485 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
487 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlZ));
488 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlZSuppressKeyDown));
489 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlEnter));
491 #elif defined(OS_MACOSX)
492 // http://crbug.com/81451
493 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, DISABLED_CommandKeyEvents) {
494 static const KeyEventTestData kTestCmdF = {
495 ui::VKEY_F, false, false, false, true,
496 false, false, false, false, 2,
497 { "D 91 0 false false false true",
498 "D 70 0 false false false true" }
501 // On Mac we don't send key up events when command modifier is down.
502 static const KeyEventTestData kTestCmdFSuppressKeyDown = {
503 ui::VKEY_F, false, false, false, true,
504 true, false, false, false, 3,
505 { "D 91 0 false false false true",
506 "D 70 0 false false false true",
507 "U 91 0 false false false true" }
510 ASSERT_TRUE(test_server()->Start());
512 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
513 GURL url = test_server()->GetURL(kTestingPage);
514 ui_test_utils::NavigateToURL(browser(), url);
516 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
517 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
519 int tab_index = browser()->tab_strip_model()->active_index();
520 // Press Cmd+F, which will make the Find box open and request focus.
521 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCmdF));
522 EXPECT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
524 // Press Escape to close the Find box and move the focus back to the web page.
525 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
526 browser(), ui::VKEY_ESCAPE, false, false, false, false));
527 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
529 // Press Cmd+F with keydown suppressed shall not open the find box.
530 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCmdFSuppressKeyDown));
531 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
533 #endif
535 #if defined(OS_MACOSX)
536 // http://crbug.com/81451 for mac
537 #define MAYBE_AccessKeys DISABLED_AccessKeys
538 #elif defined(OS_LINUX)
539 // http://crbug.com/129235
540 #define MAYBE_AccessKeys DISABLED_AccessKeys
541 #else
542 #define MAYBE_AccessKeys AccessKeys
543 #endif
545 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, MAYBE_AccessKeys) {
546 #if defined(OS_MACOSX)
547 // On Mac, access keys use ctrl+alt modifiers.
548 static const KeyEventTestData kTestAccessA = {
549 ui::VKEY_A, true, false, true, false,
550 false, false, false, false, 6,
551 { "D 17 0 true false false false",
552 "D 18 0 true false true false",
553 "D 65 0 true false true false",
554 "U 65 0 true false true false",
555 "U 18 0 true false true false",
556 "U 17 0 true false false false" }
559 static const KeyEventTestData kTestAccessDSuppress = {
560 ui::VKEY_D, true, false, true, false,
561 true, true, true, false, 6,
562 { "D 17 0 true false false false",
563 "D 18 0 true false true false",
564 "D 68 0 true false true false",
565 "U 68 0 true false true false",
566 "U 18 0 true false true false",
567 "U 17 0 true false false false" }
570 static const KeyEventTestData kTestAccess1 = {
571 ui::VKEY_1, true, false, true, false,
572 false, false, false, false, 6,
573 { "D 17 0 true false false false",
574 "D 18 0 true false true false",
575 "D 49 0 true false true false",
576 "U 49 0 true false true false",
577 "U 18 0 true false true false",
578 "U 17 0 true false false false" }
580 #else
581 static const KeyEventTestData kTestAccessA = {
582 ui::VKEY_A, false, false, true, false,
583 false, false, false, false, 4,
584 { "D 18 0 false false true false",
585 "D 65 0 false false true false",
586 "U 65 0 false false true false",
587 "U 18 0 false false true false" }
590 static const KeyEventTestData kTestAccessD = {
591 ui::VKEY_D, false, false, true, false,
592 false, false, false, false, 2,
593 { "D 18 0 false false true false",
594 "D 68 0 false false true false" }
597 static const KeyEventTestData kTestAccessDSuppress = {
598 ui::VKEY_D, false, false, true, false,
599 true, true, true, false, 4,
600 { "D 18 0 false false true false",
601 "D 68 0 false false true false",
602 "U 68 0 false false true false",
603 "U 18 0 false false true false" }
606 #if !defined(USE_ASH)
607 static const KeyEventTestData kTestAccess1 = {
608 ui::VKEY_1, false, false, true, false,
609 false, false, false, false, 4,
610 { "D 18 0 false false true false",
611 "D 49 0 false false true false",
612 "U 49 0 false false true false",
613 "U 18 0 false false true false" }
615 #endif
616 #endif
618 ASSERT_TRUE(test_server()->Start());
620 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
621 GURL url = test_server()->GetURL(kTestingPage);
622 ui_test_utils::NavigateToURL(browser(), url);
624 content::RunAllPendingInMessageLoop();
625 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
626 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
628 int tab_index = browser()->tab_strip_model()->active_index();
629 // Make sure no element is focused.
630 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
631 // Alt+A should focus the element with accesskey = "A".
632 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccessA));
633 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L"A"));
635 // Blur the focused element.
636 EXPECT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L""));
637 // Make sure no element is focused.
638 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
640 #if !defined(OS_MACOSX)
641 // Alt+D should move the focus to the location entry.
642 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccessD));
644 // TODO(isherman): This is an experimental change to help diagnose
645 // http://crbug.com/55713
646 content::RunAllPendingInMessageLoop();
647 EXPECT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
648 // No element should be focused, as Alt+D was handled by the browser.
649 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
651 // Move the focus back to the web page.
652 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
653 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
655 // Make sure no element is focused.
656 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
657 #endif
659 // If the keydown event is suppressed, then Alt+D should be handled as an
660 // accesskey rather than an accelerator key. Activation of an accesskey is not
661 // a part of the default action of the key event, so it should not be
662 // suppressed at all.
663 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccessDSuppress));
664 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
665 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L"D"));
667 // Blur the focused element.
668 EXPECT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L""));
669 // Make sure no element is focused.
670 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
671 #if !defined(USE_ASH)
672 // On Ash, alt-1..9 are assigned as window selection global accelerators, so
673 // they can not be used as accesskeys.
674 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccess1));
675 #if defined(TOOLKIT_GTK)
676 // On GTK, alt-0..9 are assigned as tab selection accelerators, so they can
677 // not be used as accesskeys.
678 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
679 #else
680 EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L"1"));
681 #endif
682 #endif
685 // Flaky, http://crbug.com/69475.
686 #if defined(OS_LINUX)
687 #define MAYBE_ReservedAccelerators DISABLED_ReservedAccelerators
688 #else
689 #define MAYBE_ReservedAccelerators ReservedAccelerators
690 #endif
691 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, MAYBE_ReservedAccelerators) {
692 ASSERT_TRUE(test_server()->Start());
694 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
695 GURL url = test_server()->GetURL(kTestingPage);
696 ui_test_utils::NavigateToURL(browser(), url);
698 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
699 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
701 ASSERT_EQ(1, browser()->tab_strip_model()->count());
703 static const KeyEventTestData kTestCtrlOrCmdT = {
704 #if defined(OS_MACOSX)
705 ui::VKEY_T, false, false, false, true,
706 true, false, false, false, 1,
707 { "D 91 0 false false false true" }
708 #else
709 ui::VKEY_T, true, false, false, false,
710 true, false, false, false, 1,
711 { "D 17 0 true false false false" }
712 #endif
715 content::WindowedNotificationObserver wait_for_new_tab(
716 chrome::NOTIFICATION_TAB_PARENTED,
717 content::NotificationService::AllSources());
719 // Press Ctrl/Cmd+T, which will open a new tab. It cannot be suppressed.
720 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(0, kTestCtrlOrCmdT));
721 wait_for_new_tab.Wait();
723 int result_length;
724 ASSERT_NO_FATAL_FAILURE(GetResultLength(0, &result_length));
725 EXPECT_EQ(1, result_length);
727 EXPECT_EQ(2, browser()->tab_strip_model()->count());
728 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
730 // Because of issue <http://crbug.com/65375>, switching back to the first tab
731 // may cause the focus to be grabbed by omnibox. So instead, we load our
732 // testing page in the newly created tab and try Cmd-W here.
733 ui_test_utils::NavigateToURL(browser(), url);
735 // Make sure the focus is in the testing page.
736 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
737 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
739 // Reserved accelerators can't be suppressed.
740 ASSERT_NO_FATAL_FAILURE(SuppressAllEvents(1, true));
742 content::WindowedNotificationObserver wait_for_tab_closed(
743 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
744 content::Source<content::WebContents>(
745 browser()->tab_strip_model()->GetWebContentsAt(1)));
747 // Press Ctrl/Cmd+W, which will close the tab.
748 #if defined(OS_MACOSX)
749 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
750 browser(), ui::VKEY_W, false, false, false, true));
751 #else
752 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
753 browser(), ui::VKEY_W, true, false, false, false));
754 #endif
756 ASSERT_NO_FATAL_FAILURE(wait_for_tab_closed.Wait());
758 EXPECT_EQ(1, browser()->tab_strip_model()->count());
761 #if defined(OS_MACOSX)
762 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, EditorKeyBindings) {
763 // TODO(kbr): re-enable: http://crbug.com/222296
764 if (base::mac::IsOSMountainLionOrLater())
765 return;
767 static const KeyEventTestData kTestCtrlA = {
768 ui::VKEY_A, true, false, false, false,
769 false, false, false, false, 4,
770 { "D 17 0 true false false false",
771 "D 65 0 true false false false",
772 "U 65 0 true false false false",
773 "U 17 0 true false false false" }
776 static const KeyEventTestData kTestCtrlF = {
777 ui::VKEY_F, true, false, false, false,
778 false, false, false, false, 4,
779 { "D 17 0 true false false false",
780 "D 70 0 true false false false",
781 "U 70 0 true false false false",
782 "U 17 0 true false false false" }
785 static const KeyEventTestData kTestCtrlK = {
786 ui::VKEY_K, true, false, false, false,
787 false, false, false, false, 4,
788 { "D 17 0 true false false false",
789 "D 75 0 true false false false",
790 "U 75 0 true false false false",
791 "U 17 0 true false false false" }
794 ASSERT_TRUE(test_server()->Start());
796 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
797 GURL url = test_server()->GetURL(kTestingPage);
798 ui_test_utils::NavigateToURL(browser(), url);
800 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
801 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
803 int tab_index = browser()->tab_strip_model()->active_index();
804 ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
805 ASSERT_NO_FATAL_FAILURE(SetTextBoxValue(tab_index, L"A", L"Hello"));
806 // Move the caret to the beginning of the line.
807 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlA));
808 // Forward one character
809 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlF));
810 // Delete to the end of the line.
811 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlK));
812 EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"A", L"H"));
814 #endif
816 // See http://crbug.com/147579
817 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, DISABLED_PageUpDownKeys) {
818 static const KeyEventTestData kTestPageUp = {
819 ui::VKEY_PRIOR, false, false, false, false,
820 false, false, false, false, 2,
821 { "D 33 0 false false false false",
822 "U 33 0 false false false false" }
825 static const KeyEventTestData kTestPageDown = {
826 ui::VKEY_NEXT, false, false, false, false,
827 false, false, false, false, 2,
828 { "D 34 0 false false false false",
829 "U 34 0 false false false false" }
832 ASSERT_TRUE(test_server()->Start());
834 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
835 GURL url = test_server()->GetURL(kTestingPage);
836 ui_test_utils::NavigateToURL(browser(), url);
838 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
839 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
841 int tab_index = browser()->tab_strip_model()->active_index();
842 ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
843 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestPageUp));
844 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestPageDown));
845 EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"A", L""));
848 #if defined(OS_WIN)
849 // AltKey is enabled only on Windows. See crbug.com/114537.
850 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, FocusMenuBarByAltKey) {
851 static const KeyEventTestData kTestAltKey = {
852 ui::VKEY_MENU, false, false, false, false,
853 false, false, false, false, 2,
854 { "D 18 0 false false true false",
855 "U 18 0 false false true false" }
858 static const KeyEventTestData kTestAltKeySuppress = {
859 ui::VKEY_MENU, false, false, false, false,
860 true, false, false, false, 2,
861 { "D 18 0 false false true false",
862 "U 18 0 false false true false" }
865 static const KeyEventTestData kTestCtrlAltKey = {
866 ui::VKEY_MENU, true, false, false, false,
867 false, false, false, false, 4,
868 { "D 17 0 true false false false",
869 "D 18 0 true false true false",
870 "U 18 0 true false true false",
871 "U 17 0 true false false false" }
874 ASSERT_TRUE(test_server()->Start());
876 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
877 GURL url = test_server()->GetURL(kTestingPage);
878 ui_test_utils::NavigateToURL(browser(), url);
880 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
881 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
883 int tab_index = browser()->tab_strip_model()->active_index();
884 // Press and release Alt key to focus wrench menu button.
885 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAltKey));
886 EXPECT_TRUE(IsViewFocused(VIEW_ID_APP_MENU));
888 ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
889 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
891 // Alt key can be suppressed.
892 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAltKeySuppress));
893 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
895 // Ctrl+Alt should have no effect.
896 EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlAltKey));
897 ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
899 #endif
901 } // namespace