OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include <string> | |
6 #include <vector> | |
7 | |
8 #include "base/strings/string16.h" | |
9 #include "base/strings/utf_string_conversions.h" | |
10 #include "chrome/test/automation/automation_json_requests.h" | |
11 #include "chrome/test/webdriver/webdriver_key_converter.h" | |
12 #include "chrome/test/webdriver/webdriver_test_util.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 namespace webdriver { | |
16 | |
17 void CheckEvents(const string16& keys, | |
18 WebKeyEvent expected_events[], | |
19 bool release_modifiers, | |
20 size_t expected_size, | |
21 int expected_modifiers) { | |
22 int modifiers = 0; | |
23 std::vector<WebKeyEvent> events; | |
24 std::string error_msg; | |
25 EXPECT_TRUE(ConvertKeysToWebKeyEvents(keys, Logger(), | |
26 release_modifiers, | |
27 &modifiers, &events, &error_msg)); | |
28 EXPECT_EQ(expected_size, events.size()); | |
29 for (size_t i = 0; i < events.size() && i < expected_size; ++i) { | |
30 EXPECT_EQ(expected_events[i].type, events[i].type); | |
31 EXPECT_EQ(expected_events[i].key_code, events[i].key_code); | |
32 EXPECT_EQ(expected_events[i].unmodified_text, events[i].unmodified_text); | |
33 EXPECT_EQ(expected_events[i].modified_text, events[i].modified_text); | |
34 EXPECT_EQ(expected_events[i].modifiers, events[i].modifiers); | |
35 } | |
36 EXPECT_EQ(expected_modifiers, modifiers); | |
37 } | |
38 | |
39 void CheckEventsReleaseModifiers(const string16& keys, | |
40 WebKeyEvent expected_events[], | |
41 size_t expected_size) { | |
42 CheckEvents(keys, expected_events, true /* release_modifier */, | |
43 expected_size, 0 /* expected_modifiers */); | |
44 } | |
45 | |
46 void CheckEventsReleaseModifiers(const std::string& keys, | |
47 WebKeyEvent expected_events[], | |
48 size_t expected_size) { | |
49 CheckEventsReleaseModifiers(UTF8ToUTF16(keys), | |
50 expected_events, expected_size); | |
51 } | |
52 | |
53 void CheckNonShiftChar(ui::KeyboardCode key_code, char character) { | |
54 int modifiers = 0; | |
55 std::string char_string; | |
56 char_string.push_back(character); | |
57 std::vector<WebKeyEvent> events; | |
58 std::string error_msg; | |
59 EXPECT_TRUE(ConvertKeysToWebKeyEvents(ASCIIToUTF16(char_string), Logger(), | |
60 true /* release_modifiers*/, | |
61 &modifiers, &events, &error_msg)); | |
62 ASSERT_EQ(3u, events.size()) << "Char: " << character; | |
63 EXPECT_EQ(key_code, events[0].key_code) << "Char: " << character; | |
64 ASSERT_EQ(1u, events[1].modified_text.length()) << "Char: " << character; | |
65 ASSERT_EQ(1u, events[1].unmodified_text.length()) << "Char: " << character; | |
66 EXPECT_EQ(character, events[1].modified_text[0]) << "Char: " << character; | |
67 EXPECT_EQ(character, events[1].unmodified_text[0]) << "Char: " << character; | |
68 EXPECT_EQ(key_code, events[2].key_code) << "Char: " << character; | |
69 } | |
70 | |
71 void CheckShiftChar(ui::KeyboardCode key_code, char character, char lower) { | |
72 int modifiers = 0; | |
73 std::string char_string; | |
74 char_string.push_back(character); | |
75 std::vector<WebKeyEvent> events; | |
76 std::string error_msg; | |
77 EXPECT_TRUE(ConvertKeysToWebKeyEvents(ASCIIToUTF16(char_string), Logger(), | |
78 true /* release_modifiers*/, | |
79 &modifiers, &events, &error_msg)); | |
80 ASSERT_EQ(5u, events.size()) << "Char: " << character; | |
81 EXPECT_EQ(ui::VKEY_SHIFT, events[0].key_code) << "Char: " << character; | |
82 EXPECT_EQ(key_code, events[1].key_code) << "Char: " << character; | |
83 ASSERT_EQ(1u, events[2].modified_text.length()) << "Char: " << character; | |
84 ASSERT_EQ(1u, events[2].unmodified_text.length()) << "Char: " << character; | |
85 EXPECT_EQ(character, events[2].modified_text[0]) << "Char: " << character; | |
86 EXPECT_EQ(lower, events[2].unmodified_text[0]) << "Char: " << character; | |
87 EXPECT_EQ(key_code, events[3].key_code) << "Char: " << character; | |
88 EXPECT_EQ(ui::VKEY_SHIFT, events[4].key_code) << "Char: " << character; | |
89 } | |
90 | |
91 TEST(WebDriverKeyConverter, SingleChar) { | |
92 WebKeyEvent event_array[] = { | |
93 CreateKeyDownEvent(ui::VKEY_H, 0), | |
94 CreateCharEvent("h", "h", 0), | |
95 CreateKeyUpEvent(ui::VKEY_H, 0)}; | |
96 CheckEventsReleaseModifiers("h", event_array, arraysize(event_array)); | |
97 } | |
98 | |
99 TEST(WebDriverKeyConverter, SingleNumber) { | |
100 WebKeyEvent event_array[] = { | |
101 CreateKeyDownEvent(ui::VKEY_1, 0), | |
102 CreateCharEvent("1", "1", 0), | |
103 CreateKeyUpEvent(ui::VKEY_1, 0)}; | |
104 CheckEventsReleaseModifiers("1", event_array, arraysize(event_array)); | |
105 } | |
106 | |
107 TEST(WebDriverKeyConverter, MultipleChars) { | |
108 WebKeyEvent event_array[] = { | |
109 CreateKeyDownEvent(ui::VKEY_H, 0), | |
110 CreateCharEvent("h", "h", 0), | |
111 CreateKeyUpEvent(ui::VKEY_H, 0), | |
112 CreateKeyDownEvent(ui::VKEY_E, 0), | |
113 CreateCharEvent("e", "e", 0), | |
114 CreateKeyUpEvent(ui::VKEY_E, 0), | |
115 CreateKeyDownEvent(ui::VKEY_Y, 0), | |
116 CreateCharEvent("y", "y", 0), | |
117 CreateKeyUpEvent(ui::VKEY_Y, 0)}; | |
118 CheckEventsReleaseModifiers("hey", event_array, arraysize(event_array)); | |
119 } | |
120 | |
121 TEST(WebDriverKeyConverter, WebDriverSpecialChar) { | |
122 WebKeyEvent event_array[] = { | |
123 CreateKeyDownEvent(ui::VKEY_SPACE, 0), | |
124 CreateCharEvent(" ", " ", 0), | |
125 CreateKeyUpEvent(ui::VKEY_SPACE, 0)}; | |
126 string16 keys; | |
127 keys.push_back(static_cast<char16>(0xE00DU)); | |
128 CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array)); | |
129 } | |
130 | |
131 TEST(WebDriverKeyConverter, WebDriverSpecialNonCharKey) { | |
132 WebKeyEvent event_array[] = { | |
133 CreateKeyDownEvent(ui::VKEY_F1, 0), | |
134 CreateKeyUpEvent(ui::VKEY_F1, 0)}; | |
135 string16 keys; | |
136 keys.push_back(static_cast<char16>(0xE031U)); | |
137 CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array)); | |
138 } | |
139 | |
140 TEST(WebDriverKeyConverter, FrenchKeyOnEnglishLayout) { | |
141 WebKeyEvent event_array[] = { | |
142 CreateKeyDownEvent(ui::VKEY_UNKNOWN, 0), | |
143 CreateCharEvent(WideToUTF8(L"\u00E9"), WideToUTF8(L"\u00E9"), 0), | |
144 CreateKeyUpEvent(ui::VKEY_UNKNOWN, 0)}; | |
145 CheckEventsReleaseModifiers(WideToUTF16(L"\u00E9"), | |
146 event_array, arraysize(event_array)); | |
147 } | |
148 | |
149 #if defined(OS_WIN) | |
150 TEST(WebDriverKeyConverter, NeedsCtrlAndAlt) { | |
151 RestoreKeyboardLayoutOnDestruct restore; | |
152 int ctrl_and_alt = automation::kControlKeyMask | automation::kAltKeyMask; | |
153 WebKeyEvent event_array[] = { | |
154 CreateKeyDownEvent(ui::VKEY_CONTROL, 0), | |
155 CreateKeyDownEvent(ui::VKEY_MENU, 0), | |
156 CreateKeyDownEvent(ui::VKEY_Q, ctrl_and_alt), | |
157 CreateCharEvent("q", "@", ctrl_and_alt), | |
158 CreateKeyUpEvent(ui::VKEY_Q, ctrl_and_alt), | |
159 CreateKeyUpEvent(ui::VKEY_MENU, 0), | |
160 CreateKeyUpEvent(ui::VKEY_CONTROL, 0)}; | |
161 ASSERT_TRUE(SwitchKeyboardLayout("00000407")); | |
162 CheckEventsReleaseModifiers("@", event_array, arraysize(event_array)); | |
163 } | |
164 #endif | |
165 | |
166 TEST(WebDriverKeyConverter, UppercaseCharDoesShift) { | |
167 WebKeyEvent event_array[] = { | |
168 CreateKeyDownEvent(ui::VKEY_SHIFT, 0), | |
169 CreateKeyDownEvent(ui::VKEY_A, automation::kShiftKeyMask), | |
170 CreateCharEvent("a", "A", automation::kShiftKeyMask), | |
171 CreateKeyUpEvent(ui::VKEY_A, automation::kShiftKeyMask), | |
172 CreateKeyUpEvent(ui::VKEY_SHIFT, 0)}; | |
173 CheckEventsReleaseModifiers("A", event_array, arraysize(event_array)); | |
174 } | |
175 | |
176 TEST(WebDriverKeyConverter, UppercaseSymbolCharDoesShift) { | |
177 WebKeyEvent event_array[] = { | |
178 CreateKeyDownEvent(ui::VKEY_SHIFT, 0), | |
179 CreateKeyDownEvent(ui::VKEY_1, automation::kShiftKeyMask), | |
180 CreateCharEvent("1", "!", automation::kShiftKeyMask), | |
181 CreateKeyUpEvent(ui::VKEY_1, automation::kShiftKeyMask), | |
182 CreateKeyUpEvent(ui::VKEY_SHIFT, 0)}; | |
183 CheckEventsReleaseModifiers("!", event_array, arraysize(event_array)); | |
184 } | |
185 | |
186 TEST(WebDriverKeyConverter, UppercaseCharUsesShiftOnlyIfNecessary) { | |
187 WebKeyEvent event_array[] = { | |
188 CreateKeyDownEvent(ui::VKEY_SHIFT, automation::kShiftKeyMask), | |
189 CreateKeyDownEvent(ui::VKEY_A, automation::kShiftKeyMask), | |
190 CreateCharEvent("a", "A", automation::kShiftKeyMask), | |
191 CreateKeyUpEvent(ui::VKEY_A, automation::kShiftKeyMask), | |
192 CreateKeyDownEvent(ui::VKEY_B, automation::kShiftKeyMask), | |
193 CreateCharEvent("b", "B", automation::kShiftKeyMask), | |
194 CreateKeyUpEvent(ui::VKEY_B, automation::kShiftKeyMask), | |
195 CreateKeyDownEvent(ui::VKEY_C, automation::kShiftKeyMask), | |
196 CreateCharEvent("c", "C", automation::kShiftKeyMask), | |
197 CreateKeyUpEvent(ui::VKEY_C, automation::kShiftKeyMask), | |
198 CreateKeyUpEvent(ui::VKEY_SHIFT, 0)}; | |
199 string16 keys; | |
200 keys.push_back(static_cast<char16>(0xE008U)); | |
201 keys.append(UTF8ToUTF16("aBc")); | |
202 CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array)); | |
203 } | |
204 | |
205 TEST(WebDriverKeyConverter, ToggleModifiers) { | |
206 WebKeyEvent event_array[] = { | |
207 CreateKeyDownEvent(ui::VKEY_SHIFT, automation::kShiftKeyMask), | |
208 CreateKeyUpEvent(ui::VKEY_SHIFT, 0), | |
209 CreateKeyDownEvent(ui::VKEY_CONTROL, automation::kControlKeyMask), | |
210 CreateKeyUpEvent(ui::VKEY_CONTROL, 0), | |
211 CreateKeyDownEvent(ui::VKEY_MENU, automation::kAltKeyMask), | |
212 CreateKeyUpEvent(ui::VKEY_MENU, 0), | |
213 CreateKeyDownEvent(ui::VKEY_COMMAND, automation::kMetaKeyMask), | |
214 CreateKeyUpEvent(ui::VKEY_COMMAND, 0)}; | |
215 string16 keys; | |
216 keys.push_back(static_cast<char16>(0xE008U)); | |
217 keys.push_back(static_cast<char16>(0xE008U)); | |
218 keys.push_back(static_cast<char16>(0xE009U)); | |
219 keys.push_back(static_cast<char16>(0xE009U)); | |
220 keys.push_back(static_cast<char16>(0xE00AU)); | |
221 keys.push_back(static_cast<char16>(0xE00AU)); | |
222 keys.push_back(static_cast<char16>(0xE03DU)); | |
223 keys.push_back(static_cast<char16>(0xE03DU)); | |
224 CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array)); | |
225 } | |
226 | |
227 TEST(WebDriverKeyConverter, AllShorthandKeys) { | |
228 WebKeyEvent event_array[] = { | |
229 CreateKeyDownEvent(ui::VKEY_RETURN, 0), | |
230 CreateCharEvent("\r", "\r", 0), | |
231 CreateKeyUpEvent(ui::VKEY_RETURN, 0), | |
232 CreateKeyDownEvent(ui::VKEY_RETURN, 0), | |
233 CreateCharEvent("\r", "\r", 0), | |
234 CreateKeyUpEvent(ui::VKEY_RETURN, 0), | |
235 CreateKeyDownEvent(ui::VKEY_TAB, 0), | |
236 #if defined(USE_AURA) | |
237 CreateCharEvent("\t", "\t", 0), | |
238 #endif | |
239 CreateKeyUpEvent(ui::VKEY_TAB, 0), | |
240 CreateKeyDownEvent(ui::VKEY_BACK, 0), | |
241 #if defined(USE_AURA) | |
242 CreateCharEvent("\b", "\b", 0), | |
243 #endif | |
244 CreateKeyUpEvent(ui::VKEY_BACK, 0), | |
245 CreateKeyDownEvent(ui::VKEY_SPACE, 0), | |
246 CreateCharEvent(" ", " ", 0), | |
247 CreateKeyUpEvent(ui::VKEY_SPACE, 0)}; | |
248 CheckEventsReleaseModifiers("\n\r\n\t\b ", | |
249 event_array,arraysize(event_array)); | |
250 } | |
251 | |
252 TEST(WebDriverKeyConverter, AllEnglishKeyboardSymbols) { | |
253 string16 keys; | |
254 const ui::KeyboardCode kSymbolKeyCodes[] = { | |
255 ui::VKEY_OEM_3, | |
256 ui::VKEY_OEM_MINUS, | |
257 ui::VKEY_OEM_PLUS, | |
258 ui::VKEY_OEM_4, | |
259 ui::VKEY_OEM_6, | |
260 ui::VKEY_OEM_5, | |
261 ui::VKEY_OEM_1, | |
262 ui::VKEY_OEM_7, | |
263 ui::VKEY_OEM_COMMA, | |
264 ui::VKEY_OEM_PERIOD, | |
265 ui::VKEY_OEM_2}; | |
266 std::string kLowerSymbols = "`-=[]\\;',./"; | |
267 std::string kUpperSymbols = "~_+{}|:\"<>?"; | |
268 for (size_t i = 0; i < kLowerSymbols.length(); ++i) | |
269 CheckNonShiftChar(kSymbolKeyCodes[i], kLowerSymbols[i]); | |
270 for (size_t i = 0; i < kUpperSymbols.length(); ++i) | |
271 CheckShiftChar(kSymbolKeyCodes[i], kUpperSymbols[i], kLowerSymbols[i]); | |
272 } | |
273 | |
274 TEST(WebDriverKeyConverter, AllEnglishKeyboardTextChars) { | |
275 std::string kLowerChars = "0123456789abcdefghijklmnopqrstuvwxyz"; | |
276 std::string kUpperChars = ")!@#$%^&*(ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
277 for (size_t i = 0; i < kLowerChars.length(); ++i) { | |
278 int offset = 0; | |
279 if (i < 10) | |
280 offset = ui::VKEY_0; | |
281 else | |
282 offset = ui::VKEY_0 + 7; | |
283 ui::KeyboardCode expected_code = static_cast<ui::KeyboardCode>(offset + i); | |
284 CheckNonShiftChar(expected_code, kLowerChars[i]); | |
285 } | |
286 for (size_t i = 0; i < kUpperChars.length(); ++i) { | |
287 int offset = 0; | |
288 if (i < 10) | |
289 offset = ui::VKEY_0; | |
290 else | |
291 offset = ui::VKEY_0 + 7; | |
292 ui::KeyboardCode expected_code = static_cast<ui::KeyboardCode>(offset + i); | |
293 CheckShiftChar(expected_code, kUpperChars[i], kLowerChars[i]); | |
294 } | |
295 } | |
296 | |
297 TEST(WebDriverKeyConverter, AllSpecialWebDriverKeysOnEnglishKeyboard) { | |
298 const char kTextForKeys[] = { | |
299 #if defined(USE_AURA) | |
300 0, 0, 0, '\b', '\t', 0, '\r', '\r', 0, 0, 0, 0, 0x1B, | |
301 ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x7F, ';', '=', | |
302 #else | |
303 0, 0, 0, 0, 0, 0, '\r', '\r', 0, 0, 0, 0, 0, | |
304 ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ';', '=', | |
305 #endif | |
306 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', | |
307 '*', '+', ',', '-', '.', '/'}; | |
308 for (size_t i = 0; i <= 0x3D; ++i) { | |
309 if (i > 0x29 && i < 0x31) | |
310 continue; | |
311 string16 keys; | |
312 int modifiers = 0; | |
313 keys.push_back(0xE000U + i); | |
314 std::vector<WebKeyEvent> events; | |
315 std::string error_msg; | |
316 if (i == 1) { | |
317 EXPECT_FALSE(ConvertKeysToWebKeyEvents(keys, Logger(), | |
318 true /* release_modifiers*/, | |
319 &modifiers, &events, &error_msg)) | |
320 << "Index: " << i; | |
321 EXPECT_EQ(0u, events.size()) << "Index: " << i; | |
322 } else { | |
323 EXPECT_TRUE(ConvertKeysToWebKeyEvents(keys, Logger(), | |
324 true /* release_modifiers */, | |
325 &modifiers, &events, &error_msg)) | |
326 << "Index: " << i; | |
327 if (i == 0) { | |
328 EXPECT_EQ(0u, events.size()) << "Index: " << i; | |
329 } else if (i >= arraysize(kTextForKeys) || kTextForKeys[i] == 0) { | |
330 EXPECT_EQ(2u, events.size()) << "Index: " << i; | |
331 } else { | |
332 ASSERT_EQ(3u, events.size()) << "Index: " << i; | |
333 ASSERT_EQ(1u, events[1].unmodified_text.length()) << "Index: " << i; | |
334 EXPECT_EQ(kTextForKeys[i], events[1].unmodified_text[0]) | |
335 << "Index: " << i; | |
336 } | |
337 } | |
338 } | |
339 } | |
340 | |
341 TEST(WebDriverKeyConverter, ModifiersState) { | |
342 int shift_key_modifier = automation::kShiftKeyMask; | |
343 int control_key_modifier = shift_key_modifier | automation::kControlKeyMask; | |
344 int alt_key_modifier = control_key_modifier | automation::kAltKeyMask; | |
345 int meta_key_modifier = alt_key_modifier | automation::kMetaKeyMask; | |
346 WebKeyEvent event_array[] = { | |
347 CreateKeyDownEvent(ui::VKEY_SHIFT, shift_key_modifier), | |
348 CreateKeyDownEvent(ui::VKEY_CONTROL, control_key_modifier), | |
349 CreateKeyDownEvent(ui::VKEY_MENU, alt_key_modifier), | |
350 CreateKeyDownEvent(ui::VKEY_COMMAND, meta_key_modifier)}; | |
351 string16 keys; | |
352 keys.push_back(static_cast<char16>(0xE008U)); | |
353 keys.push_back(static_cast<char16>(0xE009U)); | |
354 keys.push_back(static_cast<char16>(0xE00AU)); | |
355 keys.push_back(static_cast<char16>(0xE03DU)); | |
356 | |
357 CheckEvents(keys, event_array, false /* release_modifiers */, | |
358 arraysize(event_array), meta_key_modifier); | |
359 } | |
360 | |
361 TEST(WebDriverKeyConverter, ReleaseModifiers) { | |
362 WebKeyEvent event_array[] = { | |
363 CreateKeyDownEvent(ui::VKEY_SHIFT, automation::kShiftKeyMask), | |
364 CreateKeyDownEvent(ui::VKEY_CONTROL, | |
365 automation::kShiftKeyMask | automation::kControlKeyMask), | |
366 CreateKeyUpEvent(ui::VKEY_SHIFT, 0), | |
367 CreateKeyUpEvent(ui::VKEY_CONTROL, 0)}; | |
368 string16 keys; | |
369 keys.push_back(static_cast<char16>(0xE008U)); | |
370 keys.push_back(static_cast<char16>(0xE009U)); | |
371 | |
372 CheckEvents(keys, event_array, true /* release_modifiers */, | |
373 arraysize(event_array), 0); | |
374 } | |
375 | |
376 } // namespace webdriver | |
OLD | NEW |