summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-26 15:32:18 +0000
committerkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-26 15:32:18 +0000
commit376d1e164bdfde1ca048d1dac77028b7b8af531e (patch)
tree24fbbd8558084c83a95e1f004df62383aaff29c6 /chrome
parent61eeb33fdbc9925e18b7132947e99a895861b666 (diff)
downloadchromium_src-376d1e164bdfde1ca048d1dac77028b7b8af531e.zip
chromium_src-376d1e164bdfde1ca048d1dac77028b7b8af531e.tar.gz
chromium_src-376d1e164bdfde1ca048d1dac77028b7b8af531e.tar.bz2
Fix chromedriver to generate control and/or alt key strokes when given a character that requires it.
Also, print out the version info and accept integers or floats when getting the first client rect. BUG=85239,88565 TEST=none Review URL: http://codereview.chromium.org/7412003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94097 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/chrome_tests.gypi2
-rw-r--r--chrome/test/webdriver/keycode_text_conversion_mac.mm13
-rw-r--r--chrome/test/webdriver/keycode_text_conversion_unittest.cc43
-rw-r--r--chrome/test/webdriver/keycode_text_conversion_win.cc6
-rw-r--r--chrome/test/webdriver/server.cc8
-rw-r--r--chrome/test/webdriver/session.cc14
-rw-r--r--chrome/test/webdriver/webdriver_key_converter.cc34
-rw-r--r--chrome/test/webdriver/webdriver_key_converter_unittest.cc22
-rw-r--r--chrome/test/webdriver/webdriver_test_util.cc62
-rw-r--r--chrome/test/webdriver/webdriver_test_util.h56
10 files changed, 226 insertions, 34 deletions
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index fd795af..414e187 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1002,6 +1002,8 @@
'test/webdriver/keycode_text_conversion_unittest.cc',
'test/webdriver/utility_functions_unittest.cc',
'test/webdriver/webdriver_key_converter_unittest.cc',
+ 'test/webdriver/webdriver_test_util.cc',
+ 'test/webdriver/webdriver_test_util.h',
],
'conditions': [
['OS=="win"', {
diff --git a/chrome/test/webdriver/keycode_text_conversion_mac.mm b/chrome/test/webdriver/keycode_text_conversion_mac.mm
index fc142be..5dbe6bf 100644
--- a/chrome/test/webdriver/keycode_text_conversion_mac.mm
+++ b/chrome/test/webdriver/keycode_text_conversion_mac.mm
@@ -30,7 +30,16 @@ std::string ConvertKeyCodeToText(ui::KeyboardCode key_code, int modifiers) {
int mac_modifiers = 0;
if (modifiers & automation::kShiftKeyMask)
- mac_modifiers = shiftKey >> 8;
+ mac_modifiers |= shiftKey;
+ if (modifiers & automation::kControlKeyMask)
+ mac_modifiers |= controlKey;
+ if (modifiers & automation::kAltKeyMask)
+ mac_modifiers |= optionKey;
+ if (modifiers & automation::kMetaKeyMask)
+ mac_modifiers |= cmdKey;
+ // Convert EventRecord modifiers to format UCKeyTranslate accepts. See docs
+ // on UCKeyTranslate for more info.
+ UInt32 modifier_key_state = (mac_modifiers >> 8) & 0xFF;
base::mac::ScopedCFTypeRef<TISInputSourceRef> input_source_copy(
TISCopyCurrentKeyboardLayoutInputSource());
@@ -44,7 +53,7 @@ std::string ConvertKeyCodeToText(ui::KeyboardCode key_code, int modifiers) {
reinterpret_cast<const UCKeyboardLayout*>(CFDataGetBytePtr(layout_data)),
static_cast<UInt16>(mac_key_code),
kUCKeyActionDown,
- mac_modifiers,
+ modifier_key_state,
LMGetKbdLast(),
kUCKeyTranslateNoDeadKeysBit,
&dead_key_state,
diff --git a/chrome/test/webdriver/keycode_text_conversion_unittest.cc b/chrome/test/webdriver/keycode_text_conversion_unittest.cc
index 02f2db3..35dd538 100644
--- a/chrome/test/webdriver/keycode_text_conversion_unittest.cc
+++ b/chrome/test/webdriver/keycode_text_conversion_unittest.cc
@@ -8,6 +8,7 @@
#include "base/utf_string_conversions.h"
#include "chrome/common/automation_constants.h"
#include "chrome/test/webdriver/keycode_text_conversion.h"
+#include "chrome/test/webdriver/webdriver_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/keycodes/keyboard_codes.h"
@@ -15,7 +16,7 @@ using automation::kShiftKeyMask;
using webdriver::ConvertKeyCodeToText;
using webdriver::ConvertCharToKeyCode;
-namespace {
+namespace webdriver {
void CheckCharToKeyCode(char character, ui::KeyboardCode key_code,
int modifiers) {
@@ -77,4 +78,42 @@ TEST(KeycodeTextConversionTest, CharToKeyCode) {
CheckCantConvertChar(L'\u2159');
}
-} // namespace
+#if defined(OS_LINUX)
+#define MAYBE_NonShiftModifiers DISABLED_NonShiftModifiers
+#else
+#define MAYBE_NonShiftModifiers NonShiftModifiers
+#endif
+
+TEST(KeycodeTextConversionTest, MAYBE_NonShiftModifiers) {
+ RestoreKeyboardLayoutOnDestruct restore;
+#if defined(OS_WIN)
+ ASSERT_TRUE(SwitchKeyboardLayout("00000407")); // german
+ int ctrl_and_alt = automation::kControlKeyMask | automation::kAltKeyMask;
+ CheckCharToKeyCode('@', ui::VKEY_Q, ctrl_and_alt);
+ EXPECT_EQ("@", ConvertKeyCodeToText(ui::VKEY_Q, ctrl_and_alt));
+#elif defined(OS_MACOSX)
+ ASSERT_TRUE(SwitchKeyboardLayout("com.apple.keylayout.German"));
+ EXPECT_EQ("@", ConvertKeyCodeToText(ui::VKEY_L, automation::kAltKeyMask));
+#endif
+}
+
+#if defined(OS_LINUX)
+#define MAYBE_NonEnglish DISABLED_NonEnglish
+#else
+#define MAYBE_NonEnglish NonEnglish
+#endif
+
+TEST(KeycodeTextConversionTest, MAYBE_NonEnglish) {
+ RestoreKeyboardLayoutOnDestruct restore;
+#if defined(OS_WIN)
+ ASSERT_TRUE(SwitchKeyboardLayout("00000408")); // greek
+ CheckCharToKeyCode(';', ui::VKEY_Q, 0);
+ EXPECT_EQ(";", ConvertKeyCodeToText(ui::VKEY_Q, 0));
+#elif defined(OS_MACOSX)
+ ASSERT_TRUE(SwitchKeyboardLayout("com.apple.keylayout.German"));
+ CheckCharToKeyCode('z', ui::VKEY_Y, 0);
+ EXPECT_EQ("z", ConvertKeyCodeToText(ui::VKEY_Y, 0));
+#endif
+}
+
+} // namespace webdriver
diff --git a/chrome/test/webdriver/keycode_text_conversion_win.cc b/chrome/test/webdriver/keycode_text_conversion_win.cc
index 2863fc1..180c923 100644
--- a/chrome/test/webdriver/keycode_text_conversion_win.cc
+++ b/chrome/test/webdriver/keycode_text_conversion_win.cc
@@ -16,9 +16,13 @@ namespace webdriver {
std::string ConvertKeyCodeToText(ui::KeyboardCode key_code, int modifiers) {
UINT scan_code = ::MapVirtualKeyW(key_code, MAPVK_VK_TO_VSC);
BYTE keyboard_state[256];
- ::GetKeyboardState(keyboard_state);
+ memset(keyboard_state, 0, 256);
if (modifiers & automation::kShiftKeyMask)
keyboard_state[VK_SHIFT] |= 0x80;
+ if (modifiers & automation::kControlKeyMask)
+ keyboard_state[VK_CONTROL] |= 0x80;
+ if (modifiers & automation::kAltKeyMask)
+ keyboard_state[VK_MENU] |= 0x80;
wchar_t chars[5];
int code = ::ToUnicode(key_code, scan_code, keyboard_state, chars, 4, 0);
// |ToUnicode| converts some non-text key codes like F1 to various ASCII
diff --git a/chrome/test/webdriver/server.cc b/chrome/test/webdriver/server.cc
index e118466..4f612d1 100644
--- a/chrome/test/webdriver/server.cc
+++ b/chrome/test/webdriver/server.cc
@@ -25,6 +25,7 @@
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/utf_string_conversions.h"
+#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/webdriver/commands/alert_commands.h"
@@ -229,11 +230,8 @@ int main(int argc, char *argv[]) {
// The tests depend on parsing the first line ChromeDriver outputs,
// so all other logging should happen after this.
std::cout << "Started ChromeDriver" << std::endl
- << "port=" << port << std::endl;
-
- if (root.length()) {
- VLOG(1) << "Serving files from the current working directory";
- }
+ << "port=" << port << std::endl
+ << "version=" << chrome::kChromeVersion << std::endl;
// Run until we receive command to shutdown.
shutdown_event.Wait();
diff --git a/chrome/test/webdriver/session.cc b/chrome/test/webdriver/session.cc
index 54e60ef..7249bfa 100644
--- a/chrome/test/webdriver/session.cc
+++ b/chrome/test/webdriver/session.cc
@@ -812,17 +812,19 @@ Error* Session::GetElementFirstClientRect(const FrameId& frame_id,
JsonStringify(result.get()));
}
DictionaryValue* dict = static_cast<DictionaryValue*>(result.get());
- int left, top, width, height;
- if (!dict->GetInteger("left", &left) ||
- !dict->GetInteger("top", &top) ||
- !dict->GetInteger("width", &width) ||
- !dict->GetInteger("height", &height)) {
+ // TODO(kkania): Convert the atom to return integers.
+ double left, top, width, height;
+ if (!dict->GetDouble("left", &left) ||
+ !dict->GetDouble("top", &top) ||
+ !dict->GetDouble("width", &width) ||
+ !dict->GetDouble("height", &height)) {
return new Error(
kUnknownError,
"GetFirstClientRect atom returned invalid dict: " +
JsonStringify(dict));
}
- *rect = gfx::Rect(left, top, width, height);
+ *rect = gfx::Rect(static_cast<int>(left), static_cast<int>(top),
+ static_cast<int>(width), static_cast<int>(height));
return NULL;
}
diff --git a/chrome/test/webdriver/webdriver_key_converter.cc b/chrome/test/webdriver/webdriver_key_converter.cc
index 8d72191..33f9f390 100644
--- a/chrome/test/webdriver/webdriver_key_converter.cc
+++ b/chrome/test/webdriver/webdriver_key_converter.cc
@@ -13,6 +13,17 @@
namespace {
+struct ModifierMaskAndKeyCode {
+ int mask;
+ ui::KeyboardCode key_code;
+};
+
+const ModifierMaskAndKeyCode kModifiers[] = {
+ { automation::kShiftKeyMask, ui::VKEY_SHIFT },
+ { automation::kControlKeyMask, ui::VKEY_CONTROL },
+ { automation::kAltKeyMask, ui::VKEY_MENU }
+};
+
// TODO(kkania): Use this in KeyMap.
// Ordered list of all the key codes corresponding to special WebDriver keys.
// These WebDriver keys are defined in the Unicode Private Use Area.
@@ -267,12 +278,15 @@ bool ConvertKeysToWebKeyEvents(const string16& client_keys,
}
// Create the key events.
- bool need_shift_key =
- all_modifiers & automation::kShiftKeyMask &&
- !(sticky_modifiers & automation::kShiftKeyMask);
- if (need_shift_key) {
- key_events.push_back(
- CreateKeyDownEvent(ui::VKEY_SHIFT, sticky_modifiers));
+ bool necessary_modifiers[3];
+ for (int i = 0; i < 3; ++i) {
+ necessary_modifiers[i] =
+ all_modifiers & kModifiers[i].mask &&
+ !(sticky_modifiers & kModifiers[i].mask);
+ if (necessary_modifiers[i]) {
+ key_events.push_back(
+ CreateKeyDownEvent(kModifiers[i].key_code, sticky_modifiers));
+ }
}
key_events.push_back(CreateKeyDownEvent(key_code, all_modifiers));
@@ -282,9 +296,11 @@ bool ConvertKeysToWebKeyEvents(const string16& client_keys,
}
key_events.push_back(CreateKeyUpEvent(key_code, all_modifiers));
- if (need_shift_key) {
- key_events.push_back(
- CreateKeyUpEvent(ui::VKEY_SHIFT, sticky_modifiers));
+ for (int i = 2; i > -1; --i) {
+ if (necessary_modifiers[i]) {
+ key_events.push_back(
+ CreateKeyUpEvent(kModifiers[i].key_code, sticky_modifiers));
+ }
}
}
client_key_events->swap(key_events);
diff --git a/chrome/test/webdriver/webdriver_key_converter_unittest.cc b/chrome/test/webdriver/webdriver_key_converter_unittest.cc
index e7974f2..1fe3e5e 100644
--- a/chrome/test/webdriver/webdriver_key_converter_unittest.cc
+++ b/chrome/test/webdriver/webdriver_key_converter_unittest.cc
@@ -9,6 +9,7 @@
#include "base/utf_string_conversions.h"
#include "chrome/test/automation/automation_json_requests.h"
#include "chrome/test/webdriver/webdriver_key_converter.h"
+#include "chrome/test/webdriver/webdriver_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace webdriver {
@@ -127,16 +128,19 @@ TEST(WebDriverKeyConverter, FrenchKeyOnEnglishLayout) {
}
#if defined(OS_WIN)
-TEST(WebDriverKeyConverter, FrenchKeyOnFrenchLayout) {
+TEST(WebDriverKeyConverter, NeedsCtrlAndAlt) {
+ RestoreKeyboardLayoutOnDestruct restore;
+ int ctrl_and_alt = automation::kControlKeyMask | automation::kAltKeyMask;
WebKeyEvent event_array[] = {
- CreateKeyDownEvent(ui::VKEY_2, 0),
- CreateCharEvent(WideToUTF8(L"\u00E9"), WideToUTF8(L"\u00E9"), 0),
- CreateKeyUpEvent(ui::VKEY_2, 0)};
- HKL french_layout = ::LoadKeyboardLayout(L"0000040C", 0);
- ASSERT_TRUE(french_layout);
- HKL prev_layout = ::ActivateKeyboardLayout(french_layout, 0);
- CheckEvents(WideToUTF16(L"\u00E9"), event_array, arraysize(event_array));
- ::ActivateKeyboardLayout(prev_layout, 0);
+ CreateKeyDownEvent(ui::VKEY_CONTROL, 0),
+ CreateKeyDownEvent(ui::VKEY_MENU, 0),
+ CreateKeyDownEvent(ui::VKEY_Q, ctrl_and_alt),
+ CreateCharEvent("q", "@", ctrl_and_alt),
+ CreateKeyUpEvent(ui::VKEY_Q, ctrl_and_alt),
+ CreateKeyUpEvent(ui::VKEY_MENU, 0),
+ CreateKeyUpEvent(ui::VKEY_CONTROL, 0)};
+ ASSERT_TRUE(SwitchKeyboardLayout("00000407"));
+ CheckEvents("@", event_array, arraysize(event_array));
}
#endif
diff --git a/chrome/test/webdriver/webdriver_test_util.cc b/chrome/test/webdriver/webdriver_test_util.cc
new file mode 100644
index 0000000..ce464b1
--- /dev/null
+++ b/chrome/test/webdriver/webdriver_test_util.cc
@@ -0,0 +1,62 @@
+// 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.
+
+#include "chrome/test/webdriver/webdriver_test_util.h"
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+
+namespace webdriver {
+
+RestoreKeyboardLayoutOnDestruct::RestoreKeyboardLayoutOnDestruct() {
+#if defined(OS_WIN)
+ layout_ = GetKeyboardLayout(NULL);
+#elif defined(OS_MACOSX)
+ layout_.reset(TISCopyCurrentKeyboardInputSource());
+#elif defined(OS_LINUX)
+ NOTIMPLEMENTED();
+#endif
+}
+
+RestoreKeyboardLayoutOnDestruct::~RestoreKeyboardLayoutOnDestruct() {
+#if defined(OS_WIN)
+ ActivateKeyboardLayout(layout_, 0);
+#elif defined(OS_MACOSX)
+ TISSelectInputSource(layout_);
+#elif defined(OS_LINUX)
+ NOTIMPLEMENTED();
+#endif
+}
+
+#if defined(OS_WIN)
+bool SwitchKeyboardLayout(const std::string& input_locale_identifier) {
+ HKL layout = LoadKeyboardLayout(
+ UTF8ToWide(input_locale_identifier).c_str(), 0);
+ if (!layout)
+ return false;
+ return !!ActivateKeyboardLayout(layout, 0);
+}
+#endif // defined(OS_WIN)
+
+#if defined(OS_MACOSX)
+bool SwitchKeyboardLayout(const std::string& input_source_id) {
+ base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> filter_dict(
+ CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 1,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ base::mac::ScopedCFTypeRef<CFStringRef> id_ref(CFStringCreateWithCString(
+ kCFAllocatorDefault, input_source_id.c_str(), kCFStringEncodingUTF8));
+ CFDictionaryAddValue(filter_dict, kTISPropertyInputSourceID, id_ref);
+ base::mac::ScopedCFTypeRef<CFArrayRef> sources(
+ TISCreateInputSourceList(filter_dict, true));
+ if (CFArrayGetCount(sources) != 1)
+ return false;
+ TISInputSourceRef source = (TISInputSourceRef)CFArrayGetValueAtIndex(
+ sources, 0);
+ return TISSelectInputSource(source) == noErr;
+}
+#endif // defined(OS_WIN)
+
+} // namespace webdriver
diff --git a/chrome/test/webdriver/webdriver_test_util.h b/chrome/test/webdriver/webdriver_test_util.h
new file mode 100644
index 0000000..0832d2d
--- /dev/null
+++ b/chrome/test/webdriver/webdriver_test_util.h
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef CHROME_TEST_WEBDRIVER_WEBDRIVER_TEST_UTIL_H_
+#define CHROME_TEST_WEBDRIVER_WEBDRIVER_TEST_UTIL_H_
+#pragma once
+
+#include <string>
+
+#include "base/basictypes.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#elif defined(OS_MACOSX)
+#include <Carbon/Carbon.h>
+#include "base/mac/scoped_cftyperef.h"
+#endif
+
+namespace webdriver {
+
+// Restores the keyboard layout that was active at this object's creation
+// when this object goes out of scope.
+class RestoreKeyboardLayoutOnDestruct {
+ public:
+ RestoreKeyboardLayoutOnDestruct();
+ ~RestoreKeyboardLayoutOnDestruct();
+
+ private:
+#if defined(OS_WIN)
+ HKL layout_;
+#elif defined(OS_MACOSX)
+ base::mac::ScopedCFTypeRef<TISInputSourceRef> layout_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(RestoreKeyboardLayoutOnDestruct);
+};
+
+#if defined(OS_WIN)
+// Loads and activates the given keyboard layout. |input_locale_identifier|
+// is composed of a device and language ID. Returns true on success.
+// See http://msdn.microsoft.com/en-us/library/dd318693(v=vs.85).aspx
+// Example: "00000409" is the default en-us keyboard layout.
+bool SwitchKeyboardLayout(const std::string& input_locale_identifier);
+#endif // defined(OS_WIN)
+
+#if defined(OS_MACOSX)
+// Selects the input source for the given input source ID. Returns true on
+// success.
+// Example: "com.apple.keyboardlayout.US" is the default en-us keyboard layout.
+bool SwitchKeyboardLayout(const std::string& input_source_id);
+#endif // defined(OS_MACOSX)
+
+} // namespace webdriver
+
+#endif // CHROME_TEST_WEBDRIVER_WEBDRIVER_TEST_UTIL_H_