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 <string>
6
7#include "base/strings/string16.h"
8#include "base/strings/utf_string_conversions.h"
9#include "chrome/test/chromedriver/chrome/ui_events.h"
10#include "chrome/test/chromedriver/keycode_text_conversion.h"
11#include "chrome/test/chromedriver/test_util.h"
12#include "testing/gtest/include/gtest/gtest.h"
13#include "ui/events/keycodes/keyboard_codes.h"
14
15namespace {
16
17void CheckCharToKeyCode16(base::char16 character, ui::KeyboardCode key_code,
18                          int modifiers) {
19  ui::KeyboardCode actual_key_code = ui::VKEY_UNKNOWN;
20  int actual_modifiers = 0;
21  std::string error_msg;
22  EXPECT_TRUE(ConvertCharToKeyCode(
23      character, &actual_key_code, &actual_modifiers, &error_msg));
24  EXPECT_EQ(key_code, actual_key_code) << "Char: " << character;
25  EXPECT_EQ(modifiers, actual_modifiers) << "Char: " << character;
26}
27
28void CheckCharToKeyCode(char character, ui::KeyboardCode key_code,
29                        int modifiers) {
30  CheckCharToKeyCode16(base::UTF8ToUTF16(std::string(1, character))[0],
31                       key_code, modifiers);
32}
33
34#if defined(OS_WIN)
35void CheckCharToKeyCode(wchar_t character, ui::KeyboardCode key_code,
36                        int modifiers) {
37  CheckCharToKeyCode16(base::WideToUTF16(std::wstring(1, character))[0],
38                       key_code, modifiers);
39}
40#endif
41
42void CheckCantConvertChar(wchar_t character) {
43  std::wstring character_string;
44  character_string.push_back(character);
45  base::char16 character_utf16 = base::WideToUTF16(character_string)[0];
46  ui::KeyboardCode actual_key_code = ui::VKEY_UNKNOWN;
47  int actual_modifiers = 0;
48  std::string error_msg;
49  EXPECT_FALSE(ConvertCharToKeyCode(
50      character_utf16, &actual_key_code, &actual_modifiers, &error_msg));
51}
52
53std::string ConvertKeyCodeToTextNoError(ui::KeyboardCode key_code,
54                                        int modifiers) {
55  std::string error_msg;
56  std::string text;
57  EXPECT_TRUE(ConvertKeyCodeToText(key_code, modifiers, &text, &error_msg));
58  return text;
59}
60
61}  // namespace
62
63#if defined(OS_LINUX)
64// Fails on bots: crbug.com/174962
65#define MAYBE_KeyCodeToText DISABLED_KeyCodeToText
66#else
67#define MAYBE_KeyCodeToText KeyCodeToText
68#endif
69
70TEST(KeycodeTextConversionTest, MAYBE_KeyCodeToText) {
71  EXPECT_EQ("a", ConvertKeyCodeToTextNoError(ui::VKEY_A, 0));
72  EXPECT_EQ("A",
73      ConvertKeyCodeToTextNoError(ui::VKEY_A, kShiftKeyModifierMask));
74
75  EXPECT_EQ("1", ConvertKeyCodeToTextNoError(ui::VKEY_1, 0));
76  EXPECT_EQ("!",
77      ConvertKeyCodeToTextNoError(ui::VKEY_1, kShiftKeyModifierMask));
78
79  EXPECT_EQ(",", ConvertKeyCodeToTextNoError(ui::VKEY_OEM_COMMA, 0));
80  EXPECT_EQ("<", ConvertKeyCodeToTextNoError(
81      ui::VKEY_OEM_COMMA, kShiftKeyModifierMask));
82
83  EXPECT_EQ("", ConvertKeyCodeToTextNoError(ui::VKEY_F1, 0));
84  EXPECT_EQ("",
85      ConvertKeyCodeToTextNoError(ui::VKEY_F1, kShiftKeyModifierMask));
86
87  EXPECT_EQ("/", ConvertKeyCodeToTextNoError(ui::VKEY_DIVIDE, 0));
88  EXPECT_EQ("/",
89      ConvertKeyCodeToTextNoError(ui::VKEY_DIVIDE, kShiftKeyModifierMask));
90
91  EXPECT_EQ("", ConvertKeyCodeToTextNoError(ui::VKEY_SHIFT, 0));
92  EXPECT_EQ("",
93      ConvertKeyCodeToTextNoError(ui::VKEY_SHIFT, kShiftKeyModifierMask));
94}
95
96#if defined(OS_LINUX)
97// Fails on bots: crbug.com/174962
98#define MAYBE_CharToKeyCode DISABLED_CharToKeyCode
99#else
100#define MAYBE_CharToKeyCode CharToKeyCode
101#endif
102
103TEST(KeycodeTextConversionTest, MAYBE_CharToKeyCode) {
104  CheckCharToKeyCode('a', ui::VKEY_A, 0);
105  CheckCharToKeyCode('A', ui::VKEY_A, kShiftKeyModifierMask);
106
107  CheckCharToKeyCode('1', ui::VKEY_1, 0);
108  CheckCharToKeyCode('!', ui::VKEY_1, kShiftKeyModifierMask);
109
110  CheckCharToKeyCode(',', ui::VKEY_OEM_COMMA, 0);
111  CheckCharToKeyCode('<', ui::VKEY_OEM_COMMA, kShiftKeyModifierMask);
112
113  CheckCharToKeyCode('/', ui::VKEY_OEM_2, 0);
114  CheckCharToKeyCode('?', ui::VKEY_OEM_2, kShiftKeyModifierMask);
115
116  CheckCantConvertChar(L'\u00E9');
117  CheckCantConvertChar(L'\u2159');
118}
119
120#if defined(OS_LINUX) || defined(OS_MACOSX)
121// Not implemented on Linux.
122// Fails if German layout is not installed on Mac.
123#define MAYBE_NonShiftModifiers DISABLED_NonShiftModifiers
124#else
125#define MAYBE_NonShiftModifiers NonShiftModifiers
126#endif
127
128TEST(KeycodeTextConversionTest, MAYBE_NonShiftModifiers) {
129  RestoreKeyboardLayoutOnDestruct restore;
130#if defined(OS_WIN)
131  ASSERT_TRUE(SwitchKeyboardLayout("00000407"));  // german
132  int ctrl_and_alt = kControlKeyModifierMask | kAltKeyModifierMask;
133  CheckCharToKeyCode('@', ui::VKEY_Q, ctrl_and_alt);
134  EXPECT_EQ("@", ConvertKeyCodeToTextNoError(ui::VKEY_Q, ctrl_and_alt));
135#elif defined(OS_MACOSX)
136  ASSERT_TRUE(SwitchKeyboardLayout("com.apple.keylayout.German"));
137  EXPECT_EQ("@", ConvertKeyCodeToTextNoError(
138      ui::VKEY_L, kAltKeyModifierMask));
139#endif
140}
141
142#if defined(OS_LINUX) || defined(OS_MACOSX)
143// Not implemented on Linux.
144// Fails if German layout is not installed on Mac.
145#define MAYBE_NonEnglish DISABLED_NonEnglish
146#else
147#define MAYBE_NonEnglish NonEnglish
148#endif
149
150TEST(KeycodeTextConversionTest, MAYBE_NonEnglish) {
151  RestoreKeyboardLayoutOnDestruct restore;
152#if defined(OS_WIN)
153  ASSERT_TRUE(SwitchKeyboardLayout("00000408"));  // greek
154  CheckCharToKeyCode(';', ui::VKEY_Q, 0);
155  EXPECT_EQ(";", ConvertKeyCodeToTextNoError(ui::VKEY_Q, 0));
156  // Regression test for chromedriver bug #405.
157  ASSERT_TRUE(SwitchKeyboardLayout("00000419"));  // russian
158  CheckCharToKeyCode(L'\u0438', ui::VKEY_B, 0);
159  EXPECT_EQ(base::UTF16ToUTF8(L"\u0438"),
160            ConvertKeyCodeToTextNoError(ui::VKEY_B, 0));
161#elif defined(OS_MACOSX)
162  ASSERT_TRUE(SwitchKeyboardLayout("com.apple.keylayout.German"));
163  CheckCharToKeyCode('z', ui::VKEY_Y, 0);
164  EXPECT_EQ("z", ConvertKeyCodeToTextNoError(ui::VKEY_Y, 0));
165#endif
166}
167