diff options
author | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-26 02:46:16 +0000 |
---|---|---|
committer | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-26 02:46:16 +0000 |
commit | fcb247c3df9d8f7bd304d51c7473318cb256f119 (patch) | |
tree | f902aab4a57f38011123fc3fcd407ead494dcc80 /chrome/test/webdriver | |
parent | 502e3961179b6855a717409e6947f9a389bc304d (diff) | |
download | chromium_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_TESTS | 29 | ||||
-rw-r--r-- | chrome/test/webdriver/commands/mouse_commands.cc | 29 | ||||
-rw-r--r-- | chrome/test/webdriver/commands/webelement_commands.cc | 16 | ||||
-rw-r--r-- | chrome/test/webdriver/run_webdriver_tests.py | 18 | ||||
-rw-r--r-- | chrome/test/webdriver/session.cc | 43 | ||||
-rw-r--r-- | chrome/test/webdriver/session.h | 7 | ||||
-rw-r--r-- | chrome/test/webdriver/webdriver_key_converter.cc | 119 | ||||
-rw-r--r-- | chrome/test/webdriver/webdriver_key_converter.h | 9 | ||||
-rw-r--r-- | chrome/test/webdriver/webdriver_key_converter_unittest.cc | 56 |
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; + } } } } |