summaryrefslogtreecommitdiffstats
path: root/chrome/test/webdriver
diff options
context:
space:
mode:
authorkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-26 02:46:16 +0000
committerkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-26 02:46:16 +0000
commitfcb247c3df9d8f7bd304d51c7473318cb256f119 (patch)
treef902aab4a57f38011123fc3fcd407ead494dcc80 /chrome/test/webdriver
parent502e3961179b6855a717409e6947f9a389bc304d (diff)
downloadchromium_src-fcb247c3df9d8f7bd304d51c7473318cb256f119.zip
chromium_src-fcb247c3df9d8f7bd304d51c7473318cb256f119.tar.gz
chromium_src-fcb247c3df9d8f7bd304d51c7473318cb256f119.tar.bz2
Small test and ChromeDriver fixes to enable additional webdriver python tests.
BUG=none TEST=none Review URL: http://codereview.chromium.org/6694007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79484 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/webdriver')
-rw-r--r--chrome/test/webdriver/WEBDRIVER_TESTS29
-rw-r--r--chrome/test/webdriver/commands/mouse_commands.cc29
-rw-r--r--chrome/test/webdriver/commands/webelement_commands.cc16
-rw-r--r--chrome/test/webdriver/run_webdriver_tests.py18
-rw-r--r--chrome/test/webdriver/session.cc43
-rw-r--r--chrome/test/webdriver/session.h7
-rw-r--r--chrome/test/webdriver/webdriver_key_converter.cc119
-rw-r--r--chrome/test/webdriver/webdriver_key_converter.h9
-rw-r--r--chrome/test/webdriver/webdriver_key_converter_unittest.cc56
9 files changed, 242 insertions, 84 deletions
diff --git a/chrome/test/webdriver/WEBDRIVER_TESTS b/chrome/test/webdriver/WEBDRIVER_TESTS
index 5be6d6c..6b574bb 100644
--- a/chrome/test/webdriver/WEBDRIVER_TESTS
+++ b/chrome/test/webdriver/WEBDRIVER_TESTS
@@ -28,10 +28,11 @@
# Automation proxy only returns cookie name=value pairs.
'-cookie_tests.CookieTest.testAddCookie',
'-cookie_tests.CookieTest.testGetGoogleCookie',
-# 'correct_event_firing_tests',
+ 'correct_event_firing_tests',
'driver_element_finding_test',
'element_attribute_tests',
-# 'executing_async_javascript_test',
+ # Async execution has not been implemented.
+ # 'executing_async_javascript_test',
'executing_javascript_test',
'form_handling_tests',
# This test is flaky, probably because of form submission race.
@@ -39,30 +40,26 @@
'frame_switching_tests',
'implicit_waits_tests',
'page_loading_tests',
- # testShouldReturnWhenGettingAUrlThatDoesNotResolve causes the test after
- # to fail when run in xvfb: crbug.com/72027.
+ # This test causes the test after to fail occassionally. See
+ # crbug.com/72027. This is because we are not waiting for navigation
+ # error pages.
'-page_loading_tests.PageLoadingTests.testShouldReturnWhenGettingAUrlThatDoesNotResolve',
- '-page_loading_tests.PageLoadingTests.testShouldBeAbleToNavigateBackInTheBrowserHistory',
- '-page_loading_tests.PageLoadingTests.testShouldBeAbleToNavigateBackInTheBrowserHistoryInPresenceOfIframes',
- '-page_loading_tests.PageLoadingTests.testShouldBeAbleToNavigateForwardsInTheBrowserHistory',
- # This test is flaky.
- '-page_loading_tests.PageLoadingTests.testShouldWaitForDocumentToBeLoaded',
'rendered_webelement_tests',
- # Test is flaky. Sometimes can't find an element.
- '-rendered_webelement_tests.RenderedWebElementTests.testShouldCorrectlyIdentifyThatAnElementHasWidth',
# Test expects a color keyword, but a rgba tuple is returned.
'-rendered_webelement_tests.RenderedWebElementTests.testShouldAllowInheritedStylesToBeUsed',
# Test expects hex color, but a rgb tuple is returned.
'-rendered_webelement_tests.RenderedWebElementTests.testShouldPickUpStyleOfAnElement',
'select_element_handling_tests',
'stale_reference_tests',
-# 'text_handling_tests',
+ 'text_handling_tests',
+ # Getting the page source is broken.
+ '-text_handling_tests.TextHandlingTests.testReadALargeAmountOfData',
+ # Chrome bug/oddity. See crbug.com/76111.
+ '-text_handling_tests.TextHandlingTests.testShouldBeAbleToSetMoreThanOneLineOfTextInATextArea',
+ # See issue 1225 on the webdriver OSS tracker.
+ '-text_handling_tests.TextHandlingTests.testShouldReturnEmptyStringWhenTagIsSelfClosing',
'typing_tests',
'visibility_tests',
- # Bug in clicking: element is not verified before clicking.
- '-visibility_tests.VisibilityTests.testShouldNotBeAbleToClickOnAnElementThatIsNotDisplayed',
- # Bug in typing: element is not verified before typing.
- '-visibility_tests.VisibilityTests.testShouldNotBeAbleToTypeAnElementThatIsNotDisplayed',
],
'win': [
diff --git a/chrome/test/webdriver/commands/mouse_commands.cc b/chrome/test/webdriver/commands/mouse_commands.cc
index 93341ff..a802a98 100644
--- a/chrome/test/webdriver/commands/mouse_commands.cc
+++ b/chrome/test/webdriver/commands/mouse_commands.cc
@@ -22,9 +22,22 @@ bool MouseCommand::DoesPost() {
}
void MouseCommand::ExecutePost(Response* response) {
- // TODO(jmikhail): verify that the element is visible
+ bool is_displayed;
+ ErrorCode code = session_->IsElementDisplayed(
+ session_->current_target(), element, &is_displayed);
+ if (code != kSuccess) {
+ SET_WEBDRIVER_ERROR(response, "Failed to determine element visibility",
+ code);
+ return;
+ }
+ if (!is_displayed) {
+ SET_WEBDRIVER_ERROR(response, "Element must be displayed",
+ kElementNotVisible);
+ return;
+ }
+
gfx::Point location;
- ErrorCode code = session_->GetElementLocationInView(element, &location);
+ code = session_->GetElementLocationInView(element, &location);
if (code != kSuccess) {
SET_WEBDRIVER_ERROR(response, "Failed to compute element location.",
code);
@@ -39,17 +52,18 @@ void MouseCommand::ExecutePost(Response* response) {
}
location.Offset(size.width() / 2, size.height() / 2);
+ bool success = false;
switch (cmd_) {
case kClick:
VLOG(1) << "Mouse click at: (" << location.x() << ", "
<< location.y() << ")" << std::endl;
- session_->MouseClick(location, automation::kLeftButton);
+ success = session_->MouseClick(location, automation::kLeftButton);
break;
case kHover:
VLOG(1) << "Mouse hover at: (" << location.x() << ", "
<< location.y() << ")" << std::endl;
- session_->MouseMove(location);
+ success = session_->MouseMove(location);
break;
case kDrag: {
@@ -65,7 +79,7 @@ void MouseCommand::ExecutePost(Response* response) {
<< "(" << location.x() << ", " << location.y() << ") "
<< "to: (" << drag_to.x() << ", " << drag_to.y() << ")"
<< std::endl;
- session_->MouseDrag(location, drag_to);
+ success = session_->MouseDrag(location, drag_to);
break;
}
@@ -74,6 +88,11 @@ void MouseCommand::ExecutePost(Response* response) {
return;
}
+ if (!success) {
+ SET_WEBDRIVER_ERROR(response, "Performing mouse operation failed",
+ kUnknownError);
+ return;
+ }
response->SetStatus(kSuccess);
}
diff --git a/chrome/test/webdriver/commands/webelement_commands.cc b/chrome/test/webdriver/commands/webelement_commands.cc
index 9471e4b..1f4e4dd 100644
--- a/chrome/test/webdriver/commands/webelement_commands.cc
+++ b/chrome/test/webdriver/commands/webelement_commands.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -155,16 +155,12 @@ bool ElementDisplayedCommand::DoesGet() {
}
void ElementDisplayedCommand::ExecuteGet(Response* const response) {
- scoped_ptr<ListValue> args(new ListValue);
- args->Append(element.ToValue());
-
- std::string script = base::StringPrintf(
- "return (%s).apply(null, arguments);", atoms::IS_DISPLAYED);
-
- Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args.get(), &result);
+ bool is_displayed;
+ ErrorCode status = session_->IsElementDisplayed(
+ session_->current_target(), element, &is_displayed);
+ if (status == kSuccess)
+ response->SetValue(Value::CreateBooleanValue(is_displayed));
response->SetStatus(status);
- response->SetValue(result);
}
///////////////////// ElementEnabledCommand ////////////////////
diff --git a/chrome/test/webdriver/run_webdriver_tests.py b/chrome/test/webdriver/run_webdriver_tests.py
index 527846a..591168c 100644
--- a/chrome/test/webdriver/run_webdriver_tests.py
+++ b/chrome/test/webdriver/run_webdriver_tests.py
@@ -243,8 +243,26 @@ class Main(object):
logging.debug('Excluded %d test(s): %s' % (len(excluded), excluded))
return args
+ def _FakePytestHack(self):
+ """Adds a fake 'pytest' module to the system modules.
+
+ A single test in text_handling_tests.py depends on the pytest module for
+ its test skipping capabilities. Without pytest, we can not run any tests
+ in the text_handling_tests.py module.
+
+ We are not sure we want to add pytest to chrome's third party dependencies,
+ so for now create a fake pytest module so that we can at least import and
+ run all the tests that do not depend on it. Those depending on it are
+ disabled.
+ """
+ import imp
+ sys.modules['pytest'] = imp.new_module('pytest')
+
def _Run(self):
"""Run the tests."""
+ # TODO(kkania): Remove this hack.
+ self._FakePytestHack()
+
test_names = self._GetTestNames(self._args)
# The tests expect to run with preset 'driver' and 'webserver' class
diff --git a/chrome/test/webdriver/session.cc b/chrome/test/webdriver/session.cc
index ebb7fae..39bcd86 100644
--- a/chrome/test/webdriver/session.cc
+++ b/chrome/test/webdriver/session.cc
@@ -173,12 +173,19 @@ ErrorCode Session::ExecuteScript(const std::string& script,
}
ErrorCode Session::SendKeys(const WebElementId& element, const string16& keys) {
+ bool is_displayed = false;
+ ErrorCode code = IsElementDisplayed(current_target_, element, &is_displayed);
+ if (code != kSuccess)
+ return code;
+ if (!is_displayed)
+ return kElementNotVisible;
+
ListValue args;
args.Append(element.ToValue());
// TODO(jleyba): Update this to use the correct atom.
std::string script = "document.activeElement.blur();arguments[0].focus();";
Value* unscoped_result = NULL;
- ErrorCode code = ExecuteScript(script, &args, &unscoped_result);
+ code = ExecuteScript(script, &args, &unscoped_result);
scoped_ptr<Value> result(unscoped_result);
if (code != kSuccess) {
LOG(ERROR) << "Failed to focus element before sending keys";
@@ -278,7 +285,7 @@ bool Session::GetTabTitle(std::string* tab_title) {
return success;
}
-void Session::MouseClick(const gfx::Point& click,
+bool Session::MouseClick(const gfx::Point& click,
automation::MouseButton button) {
bool success = false;
RunSessionTask(NewRunnableMethod(
@@ -288,6 +295,7 @@ void Session::MouseClick(const gfx::Point& click,
click,
button,
&success));
+ return success;
}
bool Session::MouseMove(const gfx::Point& location) {
@@ -649,6 +657,26 @@ ErrorCode Session::GetElementBorder(const FrameId& frame_id,
return kSuccess;
}
+ErrorCode Session::IsElementDisplayed(const FrameId& frame_id,
+ const WebElementId& element,
+ bool* is_displayed) {
+ std::string script = base::StringPrintf(
+ "return (%s).apply(null, arguments);", atoms::IS_DISPLAYED);
+ ListValue args;
+ args.Append(element.ToValue());
+
+ Value* unscoped_result = NULL;
+ ErrorCode code = ExecuteScript(frame_id, script, &args, &unscoped_result);
+ scoped_ptr<Value> result(unscoped_result);
+ if (code != kSuccess)
+ return code;
+ if (!result->GetAsBoolean(is_displayed)) {
+ LOG(ERROR) << "IsDisplayed atom returned non boolean";
+ return kUnknownError;
+ }
+ return kSuccess;
+}
+
bool Session::WaitForAllTabsToStopLoading() {
if (!automation_.get())
return true;
@@ -707,11 +735,16 @@ void Session::TerminateOnSessionThread() {
automation_.reset();
}
-void Session::SendKeysOnSessionThread(const string16& keys,
- bool* success) {
+void Session::SendKeysOnSessionThread(const string16& keys, bool* success) {
*success = true;
std::vector<WebKeyEvent> key_events;
- ConvertKeysToWebKeyEvents(keys, &key_events);
+ std::string error_msg;
+ if (!ConvertKeysToWebKeyEvents(keys, &key_events, &error_msg)) {
+ // TODO(kkania): Return this message to the user.
+ LOG(ERROR) << error_msg;
+ *success = false;
+ return;
+ }
for (size_t i = 0; i < key_events.size(); ++i) {
bool key_success = false;
automation_->SendWebKeyEvent(
diff --git a/chrome/test/webdriver/session.h b/chrome/test/webdriver/session.h
index 79b0b54..58994f8 100644
--- a/chrome/test/webdriver/session.h
+++ b/chrome/test/webdriver/session.h
@@ -87,7 +87,7 @@ class Session {
ErrorCode SendKeys(const WebElementId& element, const string16& keys);
// Clicks the mouse at the given location using the given button.
- void MouseClick(const gfx::Point& click, automation::MouseButton button);
+ bool MouseClick(const gfx::Point& click, automation::MouseButton button);
bool MouseMove(const gfx::Point& location);
bool MouseDrag(const gfx::Point& start, const gfx::Point& end);
@@ -170,6 +170,11 @@ class Session {
int* border_left,
int* border_top);
+ // Gets whether the element is currently displayed.
+ ErrorCode IsElementDisplayed(const FrameId& frame_id,
+ const WebElementId& element,
+ bool* is_visible);
+
// Waits for all tabs to stop loading. Returns true on success.
bool WaitForAllTabsToStopLoading();
diff --git a/chrome/test/webdriver/webdriver_key_converter.cc b/chrome/test/webdriver/webdriver_key_converter.cc
index f8f3db6..8d72191 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
diff --git a/chrome/test/webdriver/webdriver_key_converter.h b/chrome/test/webdriver/webdriver_key_converter.h
index e0fad87..1567cdd 100644
--- a/chrome/test/webdriver/webdriver_key_converter.h
+++ b/chrome/test/webdriver/webdriver_key_converter.h
@@ -22,9 +22,12 @@ WebKeyEvent CreateCharEvent(const std::string& unmodified_text,
const std::string& modified_text,
int modifiers);
-// Converts keys into appropriate |WebKeyEvent|s.
-void ConvertKeysToWebKeyEvents(const string16& keys,
- std::vector<WebKeyEvent>* key_events);
+// Converts keys into appropriate |WebKeyEvent|s. This will do a best effort
+// conversion. However, if the input is invalid it will return false and set
+// an error message.
+bool ConvertKeysToWebKeyEvents(const string16& keys,
+ std::vector<WebKeyEvent>* key_events,
+ std::string* error_msg);
} // namespace webdriver
diff --git a/chrome/test/webdriver/webdriver_key_converter_unittest.cc b/chrome/test/webdriver/webdriver_key_converter_unittest.cc
index cc9c473..e7974f2 100644
--- a/chrome/test/webdriver/webdriver_key_converter_unittest.cc
+++ b/chrome/test/webdriver/webdriver_key_converter_unittest.cc
@@ -17,7 +17,8 @@ void CheckEvents(const string16& keys,
WebKeyEvent expected_events[],
size_t expected_size) {
std::vector<WebKeyEvent> events;
- ConvertKeysToWebKeyEvents(keys, &events);
+ std::string error_msg;
+ EXPECT_TRUE(ConvertKeysToWebKeyEvents(keys, &events, &error_msg));
EXPECT_EQ(expected_size, events.size());
for (size_t i = 0; i < events.size() && i < expected_size; ++i) {
EXPECT_EQ(expected_events[i].type, events[i].type);
@@ -38,7 +39,9 @@ void CheckNonShiftChar(ui::KeyboardCode key_code, char character) {
std::string char_string;
char_string.push_back(character);
std::vector<WebKeyEvent> events;
- ConvertKeysToWebKeyEvents(ASCIIToUTF16(char_string), &events);
+ std::string error_msg;
+ EXPECT_TRUE(ConvertKeysToWebKeyEvents(ASCIIToUTF16(char_string), &events,
+ &error_msg));
ASSERT_EQ(3u, events.size()) << "Char: " << character;
EXPECT_EQ(key_code, events[0].key_code) << "Char: " << character;
ASSERT_EQ(1u, events[1].modified_text.length()) << "Char: " << character;
@@ -52,7 +55,9 @@ void CheckShiftChar(ui::KeyboardCode key_code, char character, char lower) {
std::string char_string;
char_string.push_back(character);
std::vector<WebKeyEvent> events;
- ConvertKeysToWebKeyEvents(ASCIIToUTF16(char_string), &events);
+ std::string error_msg;
+ EXPECT_TRUE(ConvertKeysToWebKeyEvents(ASCIIToUTF16(char_string), &events,
+ &error_msg));
ASSERT_EQ(5u, events.size()) << "Char: " << character;
EXPECT_EQ(ui::VKEY_SHIFT, events[0].key_code) << "Char: " << character;
EXPECT_EQ(key_code, events[1].key_code) << "Char: " << character;
@@ -196,6 +201,24 @@ TEST(WebDriverKeyConverter, ToggleModifiers) {
CheckEvents(keys, event_array, arraysize(event_array));
}
+TEST(WebDriverKeyConverter, AllShorthandKeys) {
+ WebKeyEvent event_array[] = {
+ CreateKeyDownEvent(ui::VKEY_RETURN, 0),
+ CreateCharEvent("\r", "\r", 0),
+ CreateKeyUpEvent(ui::VKEY_RETURN, 0),
+ CreateKeyDownEvent(ui::VKEY_RETURN, 0),
+ CreateCharEvent("\r", "\r", 0),
+ CreateKeyUpEvent(ui::VKEY_RETURN, 0),
+ CreateKeyDownEvent(ui::VKEY_TAB, 0),
+ CreateKeyUpEvent(ui::VKEY_TAB, 0),
+ CreateKeyDownEvent(ui::VKEY_BACK, 0),
+ CreateKeyUpEvent(ui::VKEY_BACK, 0),
+ CreateKeyDownEvent(ui::VKEY_SPACE, 0),
+ CreateCharEvent(" ", " ", 0),
+ CreateKeyUpEvent(ui::VKEY_SPACE, 0)};
+ CheckEvents("\n\r\n\t\b ", event_array, arraysize(event_array));
+}
+
TEST(WebDriverKeyConverter, AllEnglishKeyboardSymbols) {
string16 keys;
const ui::KeyboardCode kSymbolKeyCodes[] = {
@@ -243,24 +266,33 @@ TEST(WebDriverKeyConverter, AllEnglishKeyboardTextChars) {
TEST(WebDriverKeyConverter, AllSpecialWebDriverKeysOnEnglishKeyboard) {
const char kTextKeys[] = {
- ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ';', '=', '0', '1', '2', '3', '4', '5',
- '6', '7', '8', '9', '*', '+', ',', '-', '.', '/'};
+ 0, 0, 0, 0, 0, 0, '\r', '\r', 0, 0, 0, 0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, ';', '=', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '*', '+', ',', '-', '.', '/'};
for (size_t i = 0; i <= 0x3D; ++i) {
if (i > 0x29 && i < 0x31)
continue;
string16 keys;
keys.push_back(0xE000U + i);
std::vector<WebKeyEvent> events;
- ConvertKeysToWebKeyEvents(keys, &events);
- if (i == 0xD || (i >= 0x18 && i <= 0x29)) {
- ASSERT_EQ(3u, events.size()) << "Index: " << i;
- ASSERT_EQ(1u, events[1].unmodified_text.length()) << "Index: " << i;
- EXPECT_EQ(kTextKeys[i - 0xD], events[1].unmodified_text[0])
+ std::string error_msg;
+ if (i == 1) {
+ EXPECT_FALSE(ConvertKeysToWebKeyEvents(keys, &events, &error_msg))
<< "Index: " << i;
- } else if (i < 2) {
EXPECT_EQ(0u, events.size()) << "Index: " << i;
} else {
- EXPECT_EQ(2u, events.size()) << "Index: " << i;
+ EXPECT_TRUE(ConvertKeysToWebKeyEvents(keys, &events, &error_msg))
+ << "Index: " << i;
+ if (i == 0) {
+ EXPECT_EQ(0u, events.size()) << "Index: " << i;
+ } else if (i == 6 || i == 7 || i == 0xD || (i >= 0x18 && i <= 0x29)) {
+ ASSERT_EQ(3u, events.size()) << "Index: " << i;
+ ASSERT_EQ(1u, events[1].unmodified_text.length()) << "Index: " << i;
+ EXPECT_EQ(kTextKeys[i], events[1].unmodified_text[0])
+ << "Index: " << i;
+ } else {
+ EXPECT_EQ(2u, events.size()) << "Index: " << i;
+ }
}
}
}