Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: chrome/test/webdriver/webdriver_key_converter.cc

Issue 6694007: Small test and ChromeDriver fixes to enable additional tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/test/webdriver/webdriver_key_converter.h" 5 #include "chrome/test/webdriver/webdriver_key_converter.h"
6 6
7 #include "base/format_macros.h"
8 #include "base/stringprintf.h"
7 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
8 #include "chrome/common/automation_constants.h" 10 #include "chrome/common/automation_constants.h"
9 #include "chrome/test/automation/automation_json_requests.h" 11 #include "chrome/test/automation/automation_json_requests.h"
10 #include "chrome/test/webdriver/keycode_text_conversion.h" 12 #include "chrome/test/webdriver/keycode_text_conversion.h"
11 13
12 namespace { 14 namespace {
13 15
14 // TODO(kkania): Use this in KeyMap. 16 // TODO(kkania): Use this in KeyMap.
15 // Ordered list of all the key codes corresponding to special WebDriver keys. 17 // Ordered list of all the key codes corresponding to special WebDriver keys.
16 // These WebDriver keys are defined in the Unicode Private Use Area. 18 // These WebDriver keys are defined in the Unicode Private Use Area.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 // be set. 104 // be set.
103 bool KeyCodeFromSpecialWebDriverKey(char16 key, ui::KeyboardCode* key_code) { 105 bool KeyCodeFromSpecialWebDriverKey(char16 key, ui::KeyboardCode* key_code) {
104 int index = static_cast<int>(key) - 0xE000U; 106 int index = static_cast<int>(key) - 0xE000U;
105 bool is_special_key = index >= 0 && 107 bool is_special_key = index >= 0 &&
106 index < static_cast<int>(arraysize(kSpecialWebDriverKeys)); 108 index < static_cast<int>(arraysize(kSpecialWebDriverKeys));
107 if (is_special_key) 109 if (is_special_key)
108 *key_code = kSpecialWebDriverKeys[index]; 110 *key_code = kSpecialWebDriverKeys[index];
109 return is_special_key; 111 return is_special_key;
110 } 112 }
111 113
114 // Gets the key code associated with |key|, if it is a special shorthand key,
dennis_jeffrey 2011/03/23 16:57:02 Change the comma at the end of this line into a pe
kkania 2011/03/26 01:58:32 Done.
115 // Shorthand keys are common text equivalents for keys, such as the newline
116 // character, which is shorthand for the return key. Returns whether |key| is
117 // a shorthand key. If true, |key_code| will be set and |should_skip| will be
dennis_jeffrey 2011/03/23 16:57:02 "should_skip" --> "client_should_skip"
kkania 2011/03/26 01:58:32 Done.
118 // set to whether the key should be skipped.
119 bool KeyCodeFromShorthandKey(char16 key_utf16,
120 ui::KeyboardCode* key_code,
121 bool* client_should_skip) {
122 string16 key_str_utf16;
123 key_str_utf16.push_back(key_utf16);
124 std::string key_str_utf8 = UTF16ToUTF8(key_str_utf16);
125 if (key_str_utf8.length() != 1)
126 return false;
127 bool should_skip = false;
128 char key = key_str_utf8[0];
129 if (key == '\n') {
130 *key_code = ui::VKEY_RETURN;
131 } else if (key == '\t') {
132 *key_code = ui::VKEY_TAB;
133 } else if (key == '\b') {
134 *key_code = ui::VKEY_BACK;
135 } else if (key == ' ') {
136 *key_code = ui::VKEY_SPACE;
137 } else if (key == '\r') {
138 *key_code = ui::VKEY_UNKNOWN;
139 should_skip = true;
140 } else {
141 return false;
142 }
143 *client_should_skip = should_skip;
144 return true;
145 }
146
112 } // namespace 147 } // namespace
113 148
114 namespace webdriver { 149 namespace webdriver {
115 150
116 WebKeyEvent CreateKeyDownEvent(ui::KeyboardCode key_code, int modifiers) { 151 WebKeyEvent CreateKeyDownEvent(ui::KeyboardCode key_code, int modifiers) {
117 return WebKeyEvent(automation::kRawKeyDownType, key_code, "", "", modifiers); 152 return WebKeyEvent(automation::kRawKeyDownType, key_code, "", "", modifiers);
118 } 153 }
119 154
120 WebKeyEvent CreateKeyUpEvent(ui::KeyboardCode key_code, int modifiers) { 155 WebKeyEvent CreateKeyUpEvent(ui::KeyboardCode key_code, int modifiers) {
121 return WebKeyEvent(automation::kKeyUpType, key_code, "", "", modifiers); 156 return WebKeyEvent(automation::kKeyUpType, key_code, "", "", modifiers);
122 } 157 }
123 158
124 WebKeyEvent CreateCharEvent(const std::string& unmodified_text, 159 WebKeyEvent CreateCharEvent(const std::string& unmodified_text,
125 const std::string& modified_text, 160 const std::string& modified_text,
126 int modifiers) { 161 int modifiers) {
127 return WebKeyEvent(automation::kCharType, 162 return WebKeyEvent(automation::kCharType,
128 ui::VKEY_UNKNOWN, 163 ui::VKEY_UNKNOWN,
129 unmodified_text, 164 unmodified_text,
130 modified_text, 165 modified_text,
131 modifiers); 166 modifiers);
132 } 167 }
133 168
134 void ConvertKeysToWebKeyEvents(const string16& client_keys, 169 bool ConvertKeysToWebKeyEvents(const string16& client_keys,
135 std::vector<WebKeyEvent>* key_events) { 170 std::vector<WebKeyEvent>* client_key_events,
171 std::string* error_msg) {
172 std::vector<WebKeyEvent> key_events;
173
136 // Add an implicit NULL character to the end of the input to depress all 174 // Add an implicit NULL character to the end of the input to depress all
137 // modifiers. 175 // modifiers.
138 string16 keys = client_keys; 176 string16 keys = client_keys;
139 keys.push_back(kWebDriverNullKey); 177 keys.push_back(kWebDriverNullKey);
140 178
141 int sticky_modifiers = 0; 179 int sticky_modifiers = 0;
142 for (size_t i = 0; i < keys.size(); ++i) { 180 for (size_t i = 0; i < keys.size(); ++i) {
143 char16 key = keys[i]; 181 char16 key = keys[i];
144 182
145 if (key == kWebDriverNullKey) { 183 if (key == kWebDriverNullKey) {
146 // Release all modifier keys and clear |stick_modifiers|. 184 // Release all modifier keys and clear |stick_modifiers|.
147 if (sticky_modifiers & automation::kShiftKeyMask) 185 if (sticky_modifiers & automation::kShiftKeyMask)
148 key_events->push_back(CreateKeyUpEvent(ui::VKEY_SHIFT, 0)); 186 key_events.push_back(CreateKeyUpEvent(ui::VKEY_SHIFT, 0));
149 if (sticky_modifiers & automation::kControlKeyMask) 187 if (sticky_modifiers & automation::kControlKeyMask)
150 key_events->push_back(CreateKeyUpEvent(ui::VKEY_CONTROL, 0)); 188 key_events.push_back(CreateKeyUpEvent(ui::VKEY_CONTROL, 0));
151 if (sticky_modifiers & automation::kAltKeyMask) 189 if (sticky_modifiers & automation::kAltKeyMask)
152 key_events->push_back(CreateKeyUpEvent(ui::VKEY_MENU, 0)); 190 key_events.push_back(CreateKeyUpEvent(ui::VKEY_MENU, 0));
153 if (sticky_modifiers & automation::kMetaKeyMask) 191 if (sticky_modifiers & automation::kMetaKeyMask)
154 key_events->push_back(CreateKeyUpEvent(ui::VKEY_COMMAND, 0)); 192 key_events.push_back(CreateKeyUpEvent(ui::VKEY_COMMAND, 0));
155 sticky_modifiers = 0; 193 sticky_modifiers = 0;
156 continue; 194 continue;
157 } 195 }
158 if (IsModifierKey(key)) { 196 if (IsModifierKey(key)) {
159 // Press or release the modifier, and adjust |sticky_modifiers|. 197 // Press or release the modifier, and adjust |sticky_modifiers|.
160 bool modifier_down = false; 198 bool modifier_down = false;
161 ui::KeyboardCode key_code = ui::VKEY_UNKNOWN; 199 ui::KeyboardCode key_code = ui::VKEY_UNKNOWN;
162 if (key == kWebDriverShiftKey) { 200 if (key == kWebDriverShiftKey) {
163 sticky_modifiers ^= automation::kShiftKeyMask; 201 sticky_modifiers ^= automation::kShiftKeyMask;
164 modifier_down = sticky_modifiers & automation::kShiftKeyMask; 202 modifier_down = sticky_modifiers & automation::kShiftKeyMask;
165 key_code = ui::VKEY_SHIFT; 203 key_code = ui::VKEY_SHIFT;
166 } else if (key == kWebDriverControlKey) { 204 } else if (key == kWebDriverControlKey) {
167 sticky_modifiers ^= automation::kControlKeyMask; 205 sticky_modifiers ^= automation::kControlKeyMask;
168 modifier_down = sticky_modifiers & automation::kControlKeyMask; 206 modifier_down = sticky_modifiers & automation::kControlKeyMask;
169 key_code = ui::VKEY_CONTROL; 207 key_code = ui::VKEY_CONTROL;
170 } else if (key == kWebDriverAltKey) { 208 } else if (key == kWebDriverAltKey) {
171 sticky_modifiers ^= automation::kAltKeyMask; 209 sticky_modifiers ^= automation::kAltKeyMask;
172 modifier_down = sticky_modifiers & automation::kAltKeyMask; 210 modifier_down = sticky_modifiers & automation::kAltKeyMask;
173 key_code = ui::VKEY_MENU; 211 key_code = ui::VKEY_MENU;
174 } else if (key == kWebDriverCommandKey) { 212 } else if (key == kWebDriverCommandKey) {
175 sticky_modifiers ^= automation::kMetaKeyMask; 213 sticky_modifiers ^= automation::kMetaKeyMask;
176 modifier_down = sticky_modifiers & automation::kMetaKeyMask; 214 modifier_down = sticky_modifiers & automation::kMetaKeyMask;
177 key_code = ui::VKEY_COMMAND; 215 key_code = ui::VKEY_COMMAND;
178 } else { 216 } else {
179 NOTREACHED(); 217 NOTREACHED();
180 } 218 }
181 if (modifier_down) 219 if (modifier_down)
182 key_events->push_back(CreateKeyDownEvent(key_code, sticky_modifiers)); 220 key_events.push_back(CreateKeyDownEvent(key_code, sticky_modifiers));
183 else 221 else
184 key_events->push_back(CreateKeyUpEvent(key_code, sticky_modifiers)); 222 key_events.push_back(CreateKeyUpEvent(key_code, sticky_modifiers));
185 continue; 223 continue;
186 } 224 }
187 225
188 ui::KeyboardCode key_code = ui::VKEY_UNKNOWN; 226 ui::KeyboardCode key_code = ui::VKEY_UNKNOWN;
189 std::string unmodified_text, modified_text; 227 std::string unmodified_text, modified_text;
190 int all_modifiers = sticky_modifiers; 228 int all_modifiers = sticky_modifiers;
191 229
192 bool is_special_key = KeyCodeFromSpecialWebDriverKey(key, &key_code); 230 // Get the key code, text, and modifiers for the given key.
193 if (is_special_key && key_code == ui::VKEY_UNKNOWN) { 231 bool should_skip = false;
194 LOG(ERROR) << "Unknown WebDriver key: " << static_cast<int>(key); 232 if (KeyCodeFromSpecialWebDriverKey(key, &key_code) ||
195 continue; 233 KeyCodeFromShorthandKey(key, &key_code, &should_skip)) {
196 } 234 if (should_skip)
197 if (!is_special_key) { 235 continue;
236 if (key_code == ui::VKEY_UNKNOWN) {
237 *error_msg = StringPrintf(
238 "Unknown WebDriver key(%d) at string index (%" PRIuS ")",
dennis_jeffrey 2011/03/23 16:57:02 This might be fine, but the examples I saw in the
kkania 2011/03/26 01:58:32 Yes, i noticed that the style guide didn't have sp
239 static_cast<int>(key),
240 i);
241 return false;
242 }
243 if (key_code == ui::VKEY_RETURN) {
244 // For some reason Chrome expects a carriage return for the return key.
245 modified_text = unmodified_text = "\r";
246 } else {
247 unmodified_text = ConvertKeyCodeToText(key_code, 0);
248 modified_text = ConvertKeyCodeToText(key_code, all_modifiers);
249 }
250 } else {
198 int necessary_modifiers = 0; 251 int necessary_modifiers = 0;
199 ConvertCharToKeyCode(key, &key_code, &necessary_modifiers); 252 ConvertCharToKeyCode(key, &key_code, &necessary_modifiers);
200 all_modifiers |= necessary_modifiers; 253 all_modifiers |= necessary_modifiers;
201 } 254 if (key_code != ui::VKEY_UNKNOWN) {
202 if (key_code != ui::VKEY_UNKNOWN) { 255 unmodified_text = ConvertKeyCodeToText(key_code, 0);
203 unmodified_text = ConvertKeyCodeToText(key_code, 0); 256 modified_text = ConvertKeyCodeToText(key_code, all_modifiers);
204 modified_text = ConvertKeyCodeToText(key_code, all_modifiers); 257 }
205 } 258 if (unmodified_text.empty() || modified_text.empty()) {
206 if (!is_special_key && (unmodified_text.empty() || modified_text.empty())) { 259 // Do a best effort and use the raw key we were given.
207 // Do a best effort and use the raw key we were given. 260 LOG(WARNING) << "No translation for key code. Code point: "
208 LOG(WARNING) << "No translation for key code. Code point: " 261 << static_cast<int>(key);
209 << static_cast<int>(key); 262 if (unmodified_text.empty())
210 if (unmodified_text.empty()) 263 unmodified_text = UTF16ToUTF8(keys.substr(i, 1));
211 unmodified_text = UTF16ToUTF8(keys.substr(i, 1)); 264 if (modified_text.empty())
212 if (modified_text.empty()) 265 modified_text = UTF16ToUTF8(keys.substr(i, 1));
213 modified_text = UTF16ToUTF8(keys.substr(i, 1)); 266 }
214 } 267 }
215 268
216 // Create the key events. 269 // Create the key events.
217 bool need_shift_key = 270 bool need_shift_key =
218 all_modifiers & automation::kShiftKeyMask && 271 all_modifiers & automation::kShiftKeyMask &&
219 !(sticky_modifiers & automation::kShiftKeyMask); 272 !(sticky_modifiers & automation::kShiftKeyMask);
220 if (need_shift_key) { 273 if (need_shift_key) {
221 key_events->push_back( 274 key_events.push_back(
222 CreateKeyDownEvent(ui::VKEY_SHIFT, sticky_modifiers)); 275 CreateKeyDownEvent(ui::VKEY_SHIFT, sticky_modifiers));
223 } 276 }
224 277
225 key_events->push_back(CreateKeyDownEvent(key_code, all_modifiers)); 278 key_events.push_back(CreateKeyDownEvent(key_code, all_modifiers));
226 if (unmodified_text.length() || modified_text.length()) { 279 if (unmodified_text.length() || modified_text.length()) {
227 key_events->push_back( 280 key_events.push_back(
228 CreateCharEvent(unmodified_text, modified_text, all_modifiers)); 281 CreateCharEvent(unmodified_text, modified_text, all_modifiers));
229 } 282 }
230 key_events->push_back(CreateKeyUpEvent(key_code, all_modifiers)); 283 key_events.push_back(CreateKeyUpEvent(key_code, all_modifiers));
231 284
232 if (need_shift_key) { 285 if (need_shift_key) {
233 key_events->push_back( 286 key_events.push_back(
234 CreateKeyUpEvent(ui::VKEY_SHIFT, sticky_modifiers)); 287 CreateKeyUpEvent(ui::VKEY_SHIFT, sticky_modifiers));
235 } 288 }
236 } 289 }
290 client_key_events->swap(key_events);
291 return true;
237 } 292 }
238 293
239 } // namespace webdriver 294 } // namespace webdriver
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698