Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / test / chromedriver / key_converter_unittest.cc
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.
4
5 #include <list>
6 #include <string>
7
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"
15
16 namespace {
17
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);
36
37     ++i;
38     ++it;
39   }
40   EXPECT_EQ(expected_modifiers, modifiers);
41 }
42
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 */);
48 }
49
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);
55 }
56
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;
75 }
76
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;
99 }
100
101 }  // namespace
102
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));
109 }
110
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));
117 }
118
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));
131 }
132
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));
141 }
142
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));
150 }
151
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));
160 }
161
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));
176 }
177 #endif
178
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));
187 }
188
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));
197 }
198
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));
216 }
217
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));
238 }
239
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
246
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));
270 }
271
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
278
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]);
299 }
300
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]);
312   }
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]);
321   }
322 }
323
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
333
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;
374       }
375     }
376   }
377 }
378
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));
394
395   CheckEvents(keys, event_array, false /* release_modifiers */,
396       arraysize(event_array), meta_key_modifier);
397 }
398
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));
409
410   CheckEvents(keys, event_array, true /* release_modifiers */,
411       arraysize(event_array), 0);
412 }