Roll src/third_party/WebKit bf18a82:a9cee16 (svn 185297:185304)
[chromium-blink-merge.git] / chrome / test / chromedriver / key_converter_unittest.cc
blob7cfcb52eb6ad8b39b7612f67b3622789d133218a
1 // Copyright (c) 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.
5 #include <list>
6 #include <string>
8 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/test/chromedriver/chrome/status.h"
11 #include "chrome/test/chromedriver/chrome/ui_events.h"
12 #include "chrome/test/chromedriver/key_converter.h"
13 #include "chrome/test/chromedriver/test_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace {
18 void CheckEvents(const base::string16& keys,
19 KeyEvent expected_events[],
20 bool release_modifiers,
21 size_t expected_size,
22 int expected_modifiers) {
23 int modifiers = 0;
24 std::list<KeyEvent> events;
25 EXPECT_EQ(kOk, ConvertKeysToKeyEvents(keys, release_modifiers,
26 &modifiers, &events).code());
27 EXPECT_EQ(expected_size, events.size());
28 size_t i = 0;
29 std::list<KeyEvent>::const_iterator it = events.begin();
30 while (i < expected_size && it != events.end()) {
31 EXPECT_EQ(expected_events[i].type, it->type);
32 EXPECT_EQ(expected_events[i].modifiers, it->modifiers);
33 EXPECT_EQ(expected_events[i].modified_text, it->modified_text);
34 EXPECT_EQ(expected_events[i].unmodified_text, it->unmodified_text);
35 EXPECT_EQ(expected_events[i].key_code, it->key_code);
37 ++i;
38 ++it;
40 EXPECT_EQ(expected_modifiers, modifiers);
43 void CheckEventsReleaseModifiers(const base::string16& keys,
44 KeyEvent expected_events[],
45 size_t expected_size) {
46 CheckEvents(keys, expected_events, true /* release_modifier */,
47 expected_size, 0 /* expected_modifiers */);
50 void CheckEventsReleaseModifiers(const std::string& keys,
51 KeyEvent expected_events[],
52 size_t expected_size) {
53 CheckEventsReleaseModifiers(base::UTF8ToUTF16(keys),
54 expected_events, expected_size);
57 void CheckNonShiftChar(ui::KeyboardCode key_code, char character) {
58 int modifiers = 0;
59 std::string char_string;
60 char_string.push_back(character);
61 std::list<KeyEvent> events;
62 EXPECT_EQ(kOk, ConvertKeysToKeyEvents(base::ASCIIToUTF16(char_string),
63 true /* release_modifiers*/,
64 &modifiers, &events).code());
65 ASSERT_EQ(3u, events.size()) << "Char: " << character;
66 std::list<KeyEvent>::const_iterator it = events.begin();
67 EXPECT_EQ(key_code, it->key_code) << "Char: " << character;
68 ++it; // Move to the second event.
69 ASSERT_EQ(1u, it->modified_text.length()) << "Char: " << character;
70 ASSERT_EQ(1u, it->unmodified_text.length()) << "Char: " << character;
71 EXPECT_EQ(character, it->modified_text[0]) << "Char: " << character;
72 EXPECT_EQ(character, it->unmodified_text[0]) << "Char: " << character;
73 ++it; // Move to the third event.
74 EXPECT_EQ(key_code, it->key_code) << "Char: " << character;
77 void CheckShiftChar(ui::KeyboardCode key_code, char character, char lower) {
78 int modifiers = 0;
79 std::string char_string;
80 char_string.push_back(character);
81 std::list<KeyEvent> events;
82 EXPECT_EQ(kOk, ConvertKeysToKeyEvents(base::ASCIIToUTF16(char_string),
83 true /* release_modifiers*/,
84 &modifiers, &events).code());
85 ASSERT_EQ(5u, events.size()) << "Char: " << character;
86 std::list<KeyEvent>::const_iterator it = events.begin();
87 EXPECT_EQ(ui::VKEY_SHIFT, it->key_code) << "Char: " << character;
88 ++it; // Move to second event.
89 EXPECT_EQ(key_code, it->key_code) << "Char: " << character;
90 ++it; // Move to third event.
91 ASSERT_EQ(1u, it->modified_text.length()) << "Char: " << character;
92 ASSERT_EQ(1u, it->unmodified_text.length()) << "Char: " << character;
93 EXPECT_EQ(character, it->modified_text[0]) << "Char: " << character;
94 EXPECT_EQ(lower, it->unmodified_text[0]) << "Char: " << character;
95 ++it; // Move to fourth event.
96 EXPECT_EQ(key_code, it->key_code) << "Char: " << character;
97 ++it; // Move to fifth event.
98 EXPECT_EQ(ui::VKEY_SHIFT, it->key_code) << "Char: " << character;
101 } // namespace
103 TEST(KeyConverter, SingleChar) {
104 KeyEvent event_array[] = {
105 CreateKeyDownEvent(ui::VKEY_H, 0),
106 CreateCharEvent("h", "h", 0),
107 CreateKeyUpEvent(ui::VKEY_H, 0)};
108 CheckEventsReleaseModifiers("h", event_array, arraysize(event_array));
111 TEST(KeyConverter, SingleNumber) {
112 KeyEvent event_array[] = {
113 CreateKeyDownEvent(ui::VKEY_1, 0),
114 CreateCharEvent("1", "1", 0),
115 CreateKeyUpEvent(ui::VKEY_1, 0)};
116 CheckEventsReleaseModifiers("1", event_array, arraysize(event_array));
119 TEST(KeyConverter, MultipleChars) {
120 KeyEvent event_array[] = {
121 CreateKeyDownEvent(ui::VKEY_H, 0),
122 CreateCharEvent("h", "h", 0),
123 CreateKeyUpEvent(ui::VKEY_H, 0),
124 CreateKeyDownEvent(ui::VKEY_E, 0),
125 CreateCharEvent("e", "e", 0),
126 CreateKeyUpEvent(ui::VKEY_E, 0),
127 CreateKeyDownEvent(ui::VKEY_Y, 0),
128 CreateCharEvent("y", "y", 0),
129 CreateKeyUpEvent(ui::VKEY_Y, 0)};
130 CheckEventsReleaseModifiers("hey", event_array, arraysize(event_array));
133 TEST(KeyConverter, WebDriverSpecialChar) {
134 KeyEvent event_array[] = {
135 CreateKeyDownEvent(ui::VKEY_SPACE, 0),
136 CreateCharEvent(" ", " ", 0),
137 CreateKeyUpEvent(ui::VKEY_SPACE, 0)};
138 base::string16 keys;
139 keys.push_back(static_cast<base::char16>(0xE00DU));
140 CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array));
143 TEST(KeyConverter, WebDriverSpecialNonCharKey) {
144 KeyEvent event_array[] = {
145 CreateKeyDownEvent(ui::VKEY_F1, 0),
146 CreateKeyUpEvent(ui::VKEY_F1, 0)};
147 base::string16 keys;
148 keys.push_back(static_cast<base::char16>(0xE031U));
149 CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array));
152 TEST(KeyConverter, FrenchKeyOnEnglishLayout) {
153 KeyEvent event_array[] = {
154 CreateKeyDownEvent(ui::VKEY_UNKNOWN, 0),
155 CreateCharEvent(base::WideToUTF8(L"\u00E9"),
156 base::WideToUTF8(L"\u00E9"), 0),
157 CreateKeyUpEvent(ui::VKEY_UNKNOWN, 0)};
158 CheckEventsReleaseModifiers(base::WideToUTF16(L"\u00E9"),
159 event_array, arraysize(event_array));
162 #if defined(OS_WIN)
163 TEST(KeyConverter, NeedsCtrlAndAlt) {
164 RestoreKeyboardLayoutOnDestruct restore;
165 int ctrl_and_alt = kControlKeyModifierMask | kAltKeyModifierMask;
166 KeyEvent event_array[] = {
167 CreateKeyDownEvent(ui::VKEY_CONTROL, 0),
168 CreateKeyDownEvent(ui::VKEY_MENU, 0),
169 CreateKeyDownEvent(ui::VKEY_Q, ctrl_and_alt),
170 CreateCharEvent("q", "@", ctrl_and_alt),
171 CreateKeyUpEvent(ui::VKEY_Q, ctrl_and_alt),
172 CreateKeyUpEvent(ui::VKEY_MENU, 0),
173 CreateKeyUpEvent(ui::VKEY_CONTROL, 0)};
174 ASSERT_TRUE(SwitchKeyboardLayout("00000407"));
175 CheckEventsReleaseModifiers("@", event_array, arraysize(event_array));
177 #endif
179 TEST(KeyConverter, UppercaseCharDoesShift) {
180 KeyEvent event_array[] = {
181 CreateKeyDownEvent(ui::VKEY_SHIFT, 0),
182 CreateKeyDownEvent(ui::VKEY_A, kShiftKeyModifierMask),
183 CreateCharEvent("a", "A", kShiftKeyModifierMask),
184 CreateKeyUpEvent(ui::VKEY_A, kShiftKeyModifierMask),
185 CreateKeyUpEvent(ui::VKEY_SHIFT, 0)};
186 CheckEventsReleaseModifiers("A", event_array, arraysize(event_array));
189 TEST(KeyConverter, UppercaseSymbolCharDoesShift) {
190 KeyEvent event_array[] = {
191 CreateKeyDownEvent(ui::VKEY_SHIFT, 0),
192 CreateKeyDownEvent(ui::VKEY_1, kShiftKeyModifierMask),
193 CreateCharEvent("1", "!", kShiftKeyModifierMask),
194 CreateKeyUpEvent(ui::VKEY_1, kShiftKeyModifierMask),
195 CreateKeyUpEvent(ui::VKEY_SHIFT, 0)};
196 CheckEventsReleaseModifiers("!", event_array, arraysize(event_array));
199 TEST(KeyConverter, UppercaseCharUsesShiftOnlyIfNecessary) {
200 KeyEvent event_array[] = {
201 CreateKeyDownEvent(ui::VKEY_SHIFT, kShiftKeyModifierMask),
202 CreateKeyDownEvent(ui::VKEY_A, kShiftKeyModifierMask),
203 CreateCharEvent("a", "A", kShiftKeyModifierMask),
204 CreateKeyUpEvent(ui::VKEY_A, kShiftKeyModifierMask),
205 CreateKeyDownEvent(ui::VKEY_B, kShiftKeyModifierMask),
206 CreateCharEvent("b", "B", kShiftKeyModifierMask),
207 CreateKeyUpEvent(ui::VKEY_B, kShiftKeyModifierMask),
208 CreateKeyDownEvent(ui::VKEY_C, kShiftKeyModifierMask),
209 CreateCharEvent("c", "C", kShiftKeyModifierMask),
210 CreateKeyUpEvent(ui::VKEY_C, kShiftKeyModifierMask),
211 CreateKeyUpEvent(ui::VKEY_SHIFT, 0)};
212 base::string16 keys;
213 keys.push_back(static_cast<base::char16>(0xE008U));
214 keys.append(base::UTF8ToUTF16("aBc"));
215 CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array));
218 TEST(KeyConverter, ToggleModifiers) {
219 KeyEvent event_array[] = {
220 CreateKeyDownEvent(ui::VKEY_SHIFT, kShiftKeyModifierMask),
221 CreateKeyUpEvent(ui::VKEY_SHIFT, 0),
222 CreateKeyDownEvent(ui::VKEY_CONTROL, kControlKeyModifierMask),
223 CreateKeyUpEvent(ui::VKEY_CONTROL, 0),
224 CreateKeyDownEvent(ui::VKEY_MENU, kAltKeyModifierMask),
225 CreateKeyUpEvent(ui::VKEY_MENU, 0),
226 CreateKeyDownEvent(ui::VKEY_COMMAND, kMetaKeyModifierMask),
227 CreateKeyUpEvent(ui::VKEY_COMMAND, 0)};
228 base::string16 keys;
229 keys.push_back(static_cast<base::char16>(0xE008U));
230 keys.push_back(static_cast<base::char16>(0xE008U));
231 keys.push_back(static_cast<base::char16>(0xE009U));
232 keys.push_back(static_cast<base::char16>(0xE009U));
233 keys.push_back(static_cast<base::char16>(0xE00AU));
234 keys.push_back(static_cast<base::char16>(0xE00AU));
235 keys.push_back(static_cast<base::char16>(0xE03DU));
236 keys.push_back(static_cast<base::char16>(0xE03DU));
237 CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array));
240 #if defined(OS_WIN)
241 // https://code.google.com/p/chromedriver/issues/detail?id=546
242 #define MAYBE_AllShorthandKeys DISABLED_AllShorthandKeys
243 #else
244 #define MAYBE_AllShorthandKeys AllShorthandKeys
245 #endif
247 TEST(KeyConverter, MAYBE_AllShorthandKeys) {
248 KeyEvent event_array[] = {
249 CreateKeyDownEvent(ui::VKEY_RETURN, 0),
250 CreateCharEvent("\r", "\r", 0),
251 CreateKeyUpEvent(ui::VKEY_RETURN, 0),
252 CreateKeyDownEvent(ui::VKEY_RETURN, 0),
253 CreateCharEvent("\r", "\r", 0),
254 CreateKeyUpEvent(ui::VKEY_RETURN, 0),
255 CreateKeyDownEvent(ui::VKEY_TAB, 0),
256 #if defined(USE_AURA) || defined(OS_LINUX)
257 CreateCharEvent("\t", "\t", 0),
258 #endif
259 CreateKeyUpEvent(ui::VKEY_TAB, 0),
260 CreateKeyDownEvent(ui::VKEY_BACK, 0),
261 #if defined(USE_AURA) || defined(OS_LINUX)
262 CreateCharEvent("\b", "\b", 0),
263 #endif
264 CreateKeyUpEvent(ui::VKEY_BACK, 0),
265 CreateKeyDownEvent(ui::VKEY_SPACE, 0),
266 CreateCharEvent(" ", " ", 0),
267 CreateKeyUpEvent(ui::VKEY_SPACE, 0)};
268 CheckEventsReleaseModifiers("\n\r\n\t\b ",
269 event_array,arraysize(event_array));
272 #if defined(OS_LINUX)
273 // Fails on bots: crbug.com/174962
274 #define MAYBE_AllEnglishKeyboardSymbols DISABLED_AllEnglishKeyboardSymbols
275 #else
276 #define MAYBE_AllEnglishKeyboardSymbols AllEnglishKeyboardSymbols
277 #endif
279 TEST(KeyConverter, MAYBE_AllEnglishKeyboardSymbols) {
280 base::string16 keys;
281 const ui::KeyboardCode kSymbolKeyCodes[] = {
282 ui::VKEY_OEM_3,
283 ui::VKEY_OEM_MINUS,
284 ui::VKEY_OEM_PLUS,
285 ui::VKEY_OEM_4,
286 ui::VKEY_OEM_6,
287 ui::VKEY_OEM_5,
288 ui::VKEY_OEM_1,
289 ui::VKEY_OEM_7,
290 ui::VKEY_OEM_COMMA,
291 ui::VKEY_OEM_PERIOD,
292 ui::VKEY_OEM_2};
293 std::string kLowerSymbols = "`-=[]\\;',./";
294 std::string kUpperSymbols = "~_+{}|:\"<>?";
295 for (size_t i = 0; i < kLowerSymbols.length(); ++i)
296 CheckNonShiftChar(kSymbolKeyCodes[i], kLowerSymbols[i]);
297 for (size_t i = 0; i < kUpperSymbols.length(); ++i)
298 CheckShiftChar(kSymbolKeyCodes[i], kUpperSymbols[i], kLowerSymbols[i]);
301 TEST(KeyConverter, AllEnglishKeyboardTextChars) {
302 std::string kLowerChars = "0123456789abcdefghijklmnopqrstuvwxyz";
303 std::string kUpperChars = ")!@#$%^&*(ABCDEFGHIJKLMNOPQRSTUVWXYZ";
304 for (size_t i = 0; i < kLowerChars.length(); ++i) {
305 int offset = 0;
306 if (i < 10)
307 offset = ui::VKEY_0;
308 else
309 offset = ui::VKEY_0 + 7;
310 ui::KeyboardCode expected_code = static_cast<ui::KeyboardCode>(offset + i);
311 CheckNonShiftChar(expected_code, kLowerChars[i]);
313 for (size_t i = 0; i < kUpperChars.length(); ++i) {
314 int offset = 0;
315 if (i < 10)
316 offset = ui::VKEY_0;
317 else
318 offset = ui::VKEY_0 + 7;
319 ui::KeyboardCode expected_code = static_cast<ui::KeyboardCode>(offset + i);
320 CheckShiftChar(expected_code, kUpperChars[i], kLowerChars[i]);
324 #if defined(OS_LINUX) || defined(OS_WIN)
325 // https://code.google.com/p/chromedriver/issues/detail?id=240
326 // https://code.google.com/p/chromedriver/issues/detail?id=546
327 #define MAYBE_AllSpecialWebDriverKeysOnEnglishKeyboard \
328 DISABLED_AllSpecialWebDriverKeysOnEnglishKeyboard
329 #else
330 #define MAYBE_AllSpecialWebDriverKeysOnEnglishKeyboard \
331 AllSpecialWebDriverKeysOnEnglishKeyboard
332 #endif
334 TEST(KeyConverter, MAYBE_AllSpecialWebDriverKeysOnEnglishKeyboard) {
335 const char kTextForKeys[] = {
336 #if defined(USE_AURA) || defined(OS_LINUX)
337 0, 0, 0, '\b', '\t', 0, '\r', '\r', 0, 0, 0, 0, 0x1B,
338 ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x7F, ';', '=',
339 #else
340 0, 0, 0, 0, 0, 0, '\r', '\r', 0, 0, 0, 0, 0,
341 ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ';', '=',
342 #endif
343 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
344 '*', '+', ',', '-', '.', '/'};
345 for (size_t i = 0; i <= 0x3D; ++i) {
346 if (i > 0x29 && i < 0x31)
347 continue;
348 base::string16 keys;
349 int modifiers = 0;
350 keys.push_back(0xE000U + i);
351 std::list<KeyEvent> events;
352 if (i == 1) {
353 EXPECT_NE(kOk, ConvertKeysToKeyEvents(keys,
354 true /* release_modifiers*/,
355 &modifiers, &events).code())
356 << "Index: " << i;
357 EXPECT_EQ(0u, events.size()) << "Index: " << i;
358 } else {
359 EXPECT_EQ(kOk, ConvertKeysToKeyEvents(keys,
360 true /* release_modifiers */,
361 &modifiers, &events).code())
362 << "Index: " << i;
363 if (i == 0) {
364 EXPECT_EQ(0u, events.size()) << "Index: " << i;
365 } else if (i >= arraysize(kTextForKeys) || kTextForKeys[i] == 0) {
366 EXPECT_EQ(2u, events.size()) << "Index: " << i;
367 } else {
368 ASSERT_EQ(3u, events.size()) << "Index: " << i;
369 std::list<KeyEvent>::const_iterator it = events.begin();
370 ++it; // Move to the second event.
371 ASSERT_EQ(1u, it->unmodified_text.length()) << "Index: " << i;
372 EXPECT_EQ(kTextForKeys[i], it->unmodified_text[0])
373 << "Index: " << i;
379 TEST(KeyConverter, ModifiersState) {
380 int shift_key_modifier = kShiftKeyModifierMask;
381 int control_key_modifier = shift_key_modifier | kControlKeyModifierMask;
382 int alt_key_modifier = control_key_modifier | kAltKeyModifierMask;
383 int meta_key_modifier = alt_key_modifier | kMetaKeyModifierMask;
384 KeyEvent event_array[] = {
385 CreateKeyDownEvent(ui::VKEY_SHIFT, shift_key_modifier),
386 CreateKeyDownEvent(ui::VKEY_CONTROL, control_key_modifier),
387 CreateKeyDownEvent(ui::VKEY_MENU, alt_key_modifier),
388 CreateKeyDownEvent(ui::VKEY_COMMAND, meta_key_modifier)};
389 base::string16 keys;
390 keys.push_back(static_cast<base::char16>(0xE008U));
391 keys.push_back(static_cast<base::char16>(0xE009U));
392 keys.push_back(static_cast<base::char16>(0xE00AU));
393 keys.push_back(static_cast<base::char16>(0xE03DU));
395 CheckEvents(keys, event_array, false /* release_modifiers */,
396 arraysize(event_array), meta_key_modifier);
399 TEST(KeyConverter, ReleaseModifiers) {
400 KeyEvent event_array[] = {
401 CreateKeyDownEvent(ui::VKEY_SHIFT, kShiftKeyModifierMask),
402 CreateKeyDownEvent(ui::VKEY_CONTROL,
403 kShiftKeyModifierMask | kControlKeyModifierMask),
404 CreateKeyUpEvent(ui::VKEY_SHIFT, 0),
405 CreateKeyUpEvent(ui::VKEY_CONTROL, 0)};
406 base::string16 keys;
407 keys.push_back(static_cast<base::char16>(0xE008U));
408 keys.push_back(static_cast<base::char16>(0xE009U));
410 CheckEvents(keys, event_array, true /* release_modifiers */,
411 arraysize(event_array), 0);