| Index: chrome/test/webdriver/webdriver_key_converter.cc
|
| diff --git a/chrome/test/webdriver/webdriver_key_converter.cc b/chrome/test/webdriver/webdriver_key_converter.cc
|
| index f8f3db66b151514c54c2eb1ee4bfe934a8d291c8..8d721915cbb92e59e89567e6b63f1db97a6d2b91 100644
|
| --- a/chrome/test/webdriver/webdriver_key_converter.cc
|
| +++ b/chrome/test/webdriver/webdriver_key_converter.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "chrome/test/webdriver/webdriver_key_converter.h"
|
|
|
| +#include "base/format_macros.h"
|
| +#include "base/stringprintf.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/common/automation_constants.h"
|
| #include "chrome/test/automation/automation_json_requests.h"
|
| @@ -109,6 +111,39 @@ bool KeyCodeFromSpecialWebDriverKey(char16 key, ui::KeyboardCode* key_code) {
|
| return is_special_key;
|
| }
|
|
|
| +// Gets the key code associated with |key|, if it is a special shorthand key.
|
| +// Shorthand keys are common text equivalents for keys, such as the newline
|
| +// character, which is shorthand for the return key. Returns whether |key| is
|
| +// a shorthand key. If true, |key_code| will be set and |client_should_skip|
|
| +// will be set to whether the key should be skipped.
|
| +bool KeyCodeFromShorthandKey(char16 key_utf16,
|
| + ui::KeyboardCode* key_code,
|
| + bool* client_should_skip) {
|
| + string16 key_str_utf16;
|
| + key_str_utf16.push_back(key_utf16);
|
| + std::string key_str_utf8 = UTF16ToUTF8(key_str_utf16);
|
| + if (key_str_utf8.length() != 1)
|
| + return false;
|
| + bool should_skip = false;
|
| + char key = key_str_utf8[0];
|
| + if (key == '\n') {
|
| + *key_code = ui::VKEY_RETURN;
|
| + } else if (key == '\t') {
|
| + *key_code = ui::VKEY_TAB;
|
| + } else if (key == '\b') {
|
| + *key_code = ui::VKEY_BACK;
|
| + } else if (key == ' ') {
|
| + *key_code = ui::VKEY_SPACE;
|
| + } else if (key == '\r') {
|
| + *key_code = ui::VKEY_UNKNOWN;
|
| + should_skip = true;
|
| + } else {
|
| + return false;
|
| + }
|
| + *client_should_skip = should_skip;
|
| + return true;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace webdriver {
|
| @@ -131,8 +166,11 @@ WebKeyEvent CreateCharEvent(const std::string& unmodified_text,
|
| modifiers);
|
| }
|
|
|
| -void ConvertKeysToWebKeyEvents(const string16& client_keys,
|
| - std::vector<WebKeyEvent>* key_events) {
|
| +bool ConvertKeysToWebKeyEvents(const string16& client_keys,
|
| + std::vector<WebKeyEvent>* client_key_events,
|
| + std::string* error_msg) {
|
| + std::vector<WebKeyEvent> key_events;
|
| +
|
| // Add an implicit NULL character to the end of the input to depress all
|
| // modifiers.
|
| string16 keys = client_keys;
|
| @@ -145,13 +183,13 @@ void ConvertKeysToWebKeyEvents(const string16& client_keys,
|
| if (key == kWebDriverNullKey) {
|
| // Release all modifier keys and clear |stick_modifiers|.
|
| if (sticky_modifiers & automation::kShiftKeyMask)
|
| - key_events->push_back(CreateKeyUpEvent(ui::VKEY_SHIFT, 0));
|
| + key_events.push_back(CreateKeyUpEvent(ui::VKEY_SHIFT, 0));
|
| if (sticky_modifiers & automation::kControlKeyMask)
|
| - key_events->push_back(CreateKeyUpEvent(ui::VKEY_CONTROL, 0));
|
| + key_events.push_back(CreateKeyUpEvent(ui::VKEY_CONTROL, 0));
|
| if (sticky_modifiers & automation::kAltKeyMask)
|
| - key_events->push_back(CreateKeyUpEvent(ui::VKEY_MENU, 0));
|
| + key_events.push_back(CreateKeyUpEvent(ui::VKEY_MENU, 0));
|
| if (sticky_modifiers & automation::kMetaKeyMask)
|
| - key_events->push_back(CreateKeyUpEvent(ui::VKEY_COMMAND, 0));
|
| + key_events.push_back(CreateKeyUpEvent(ui::VKEY_COMMAND, 0));
|
| sticky_modifiers = 0;
|
| continue;
|
| }
|
| @@ -179,9 +217,9 @@ void ConvertKeysToWebKeyEvents(const string16& client_keys,
|
| NOTREACHED();
|
| }
|
| if (modifier_down)
|
| - key_events->push_back(CreateKeyDownEvent(key_code, sticky_modifiers));
|
| + key_events.push_back(CreateKeyDownEvent(key_code, sticky_modifiers));
|
| else
|
| - key_events->push_back(CreateKeyUpEvent(key_code, sticky_modifiers));
|
| + key_events.push_back(CreateKeyUpEvent(key_code, sticky_modifiers));
|
| continue;
|
| }
|
|
|
| @@ -189,28 +227,43 @@ void ConvertKeysToWebKeyEvents(const string16& client_keys,
|
| std::string unmodified_text, modified_text;
|
| int all_modifiers = sticky_modifiers;
|
|
|
| - bool is_special_key = KeyCodeFromSpecialWebDriverKey(key, &key_code);
|
| - if (is_special_key && key_code == ui::VKEY_UNKNOWN) {
|
| - LOG(ERROR) << "Unknown WebDriver key: " << static_cast<int>(key);
|
| - continue;
|
| - }
|
| - if (!is_special_key) {
|
| + // Get the key code, text, and modifiers for the given key.
|
| + bool should_skip = false;
|
| + if (KeyCodeFromSpecialWebDriverKey(key, &key_code) ||
|
| + KeyCodeFromShorthandKey(key, &key_code, &should_skip)) {
|
| + if (should_skip)
|
| + continue;
|
| + if (key_code == ui::VKEY_UNKNOWN) {
|
| + *error_msg = StringPrintf(
|
| + "Unknown WebDriver key(%d) at string index (%" PRIuS ")",
|
| + static_cast<int>(key),
|
| + i);
|
| + return false;
|
| + }
|
| + if (key_code == ui::VKEY_RETURN) {
|
| + // For some reason Chrome expects a carriage return for the return key.
|
| + modified_text = unmodified_text = "\r";
|
| + } else {
|
| + unmodified_text = ConvertKeyCodeToText(key_code, 0);
|
| + modified_text = ConvertKeyCodeToText(key_code, all_modifiers);
|
| + }
|
| + } else {
|
| int necessary_modifiers = 0;
|
| ConvertCharToKeyCode(key, &key_code, &necessary_modifiers);
|
| all_modifiers |= necessary_modifiers;
|
| - }
|
| - if (key_code != ui::VKEY_UNKNOWN) {
|
| - unmodified_text = ConvertKeyCodeToText(key_code, 0);
|
| - modified_text = ConvertKeyCodeToText(key_code, all_modifiers);
|
| - }
|
| - if (!is_special_key && (unmodified_text.empty() || modified_text.empty())) {
|
| - // Do a best effort and use the raw key we were given.
|
| - LOG(WARNING) << "No translation for key code. Code point: "
|
| - << static_cast<int>(key);
|
| - if (unmodified_text.empty())
|
| - unmodified_text = UTF16ToUTF8(keys.substr(i, 1));
|
| - if (modified_text.empty())
|
| - modified_text = UTF16ToUTF8(keys.substr(i, 1));
|
| + if (key_code != ui::VKEY_UNKNOWN) {
|
| + unmodified_text = ConvertKeyCodeToText(key_code, 0);
|
| + modified_text = ConvertKeyCodeToText(key_code, all_modifiers);
|
| + }
|
| + if (unmodified_text.empty() || modified_text.empty()) {
|
| + // Do a best effort and use the raw key we were given.
|
| + LOG(WARNING) << "No translation for key code. Code point: "
|
| + << static_cast<int>(key);
|
| + if (unmodified_text.empty())
|
| + unmodified_text = UTF16ToUTF8(keys.substr(i, 1));
|
| + if (modified_text.empty())
|
| + modified_text = UTF16ToUTF8(keys.substr(i, 1));
|
| + }
|
| }
|
|
|
| // Create the key events.
|
| @@ -218,22 +271,24 @@ void ConvertKeysToWebKeyEvents(const string16& client_keys,
|
| all_modifiers & automation::kShiftKeyMask &&
|
| !(sticky_modifiers & automation::kShiftKeyMask);
|
| if (need_shift_key) {
|
| - key_events->push_back(
|
| + key_events.push_back(
|
| CreateKeyDownEvent(ui::VKEY_SHIFT, sticky_modifiers));
|
| }
|
|
|
| - key_events->push_back(CreateKeyDownEvent(key_code, all_modifiers));
|
| + key_events.push_back(CreateKeyDownEvent(key_code, all_modifiers));
|
| if (unmodified_text.length() || modified_text.length()) {
|
| - key_events->push_back(
|
| + key_events.push_back(
|
| CreateCharEvent(unmodified_text, modified_text, all_modifiers));
|
| }
|
| - key_events->push_back(CreateKeyUpEvent(key_code, all_modifiers));
|
| + key_events.push_back(CreateKeyUpEvent(key_code, all_modifiers));
|
|
|
| if (need_shift_key) {
|
| - key_events->push_back(
|
| + key_events.push_back(
|
| CreateKeyUpEvent(ui::VKEY_SHIFT, sticky_modifiers));
|
| }
|
| }
|
| + client_key_events->swap(key_events);
|
| + return true;
|
| }
|
|
|
| } // namespace webdriver
|
|
|