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.
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"
18 void CheckEvents(const base::string16
& keys
,
19 KeyEvent expected_events
[],
20 bool release_modifiers
,
22 int expected_modifiers
) {
24 std::list
<KeyEvent
> events
;
25 EXPECT_EQ(kOk
, ConvertKeysToKeyEvents(keys
, release_modifiers
,
26 &modifiers
, &events
).code());
27 EXPECT_EQ(expected_size
, events
.size());
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
);
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
) {
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
) {
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
;
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)};
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)};
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
));
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
));
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)};
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)};
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
));
241 // https://code.google.com/p/chromedriver/issues/detail?id=546
242 #define MAYBE_AllShorthandKeys DISABLED_AllShorthandKeys
244 #define MAYBE_AllShorthandKeys AllShorthandKeys
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),
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),
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
276 #define MAYBE_AllEnglishKeyboardSymbols AllEnglishKeyboardSymbols
279 TEST(KeyConverter
, MAYBE_AllEnglishKeyboardSymbols
) {
281 const ui::KeyboardCode kSymbolKeyCodes
[] = {
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
) {
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
) {
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
330 #define MAYBE_AllSpecialWebDriverKeysOnEnglishKeyboard \
331 AllSpecialWebDriverKeysOnEnglishKeyboard
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, ';', '=',
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, ';', '=',
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)
350 keys
.push_back(0xE000U
+ i
);
351 std::list
<KeyEvent
> events
;
353 EXPECT_NE(kOk
, ConvertKeysToKeyEvents(keys
,
354 true /* release_modifiers*/,
355 &modifiers
, &events
).code())
357 EXPECT_EQ(0u, events
.size()) << "Index: " << i
;
359 EXPECT_EQ(kOk
, ConvertKeysToKeyEvents(keys
,
360 true /* release_modifiers */,
361 &modifiers
, &events
).code())
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
;
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])
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
)};
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)};
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);