| Index: content/public/test/render_view_test.cc
|
| diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
|
| index ca67587df8b334707b223f0019aed624b7ebd983..6ec66a1111a262780ecf70a15599c425caecb8a4 100644
|
| --- a/content/public/test/render_view_test.cc
|
| +++ b/content/public/test/render_view_test.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "content/public/test/render_view_test.h"
|
|
|
| +#include <cctype>
|
| +
|
| #include "base/run_loop.h"
|
| #include "content/common/dom_storage/dom_storage_types.h"
|
| #include "content/common/frame_messages.h"
|
| @@ -23,10 +25,12 @@
|
| #include "content/renderer/renderer_main_platform_delegate.h"
|
| #include "content/renderer/scheduler/renderer_scheduler.h"
|
| #include "content/test/fake_compositor_dependencies.h"
|
| +#include "content/test/mock_keyboard.h"
|
| #include "content/test/mock_render_process.h"
|
| #include "content/test/test_content_client.h"
|
| #include "third_party/WebKit/public/platform/WebScreenInfo.h"
|
| #include "third_party/WebKit/public/platform/WebURLRequest.h"
|
| +#include "third_party/WebKit/public/web/WebDocument.h"
|
| #include "third_party/WebKit/public/web/WebHistoryItem.h"
|
| #include "third_party/WebKit/public/web/WebInputEvent.h"
|
| #include "third_party/WebKit/public/web/WebKit.h"
|
| @@ -34,12 +38,26 @@
|
| #include "third_party/WebKit/public/web/WebScriptSource.h"
|
| #include "third_party/WebKit/public/web/WebView.h"
|
| #include "ui/base/resource/resource_bundle.h"
|
| +#include "ui/events/event.h"
|
| +#include "ui/events/keycodes/keyboard_codes.h"
|
| #include "v8/include/v8.h"
|
|
|
| #if defined(OS_MACOSX)
|
| #include "base/mac/scoped_nsautorelease_pool.h"
|
| #endif
|
|
|
| +#if defined(USE_AURA) && defined(USE_X11)
|
| +#include <X11/Xlib.h>
|
| +#include "ui/events/event_constants.h"
|
| +#include "ui/events/keycodes/keyboard_code_conversion.h"
|
| +#include "ui/events/test/events_test_utils.h"
|
| +#include "ui/events/test/events_test_utils_x11.h"
|
| +#endif
|
| +
|
| +#if defined(USE_OZONE)
|
| +#include "ui/events/keycodes/keyboard_code_conversion.h"
|
| +#endif
|
| +
|
| using blink::WebGestureEvent;
|
| using blink::WebInputEvent;
|
| using blink::WebLocalFrame;
|
| @@ -49,6 +67,7 @@ using blink::WebString;
|
| using blink::WebURLRequest;
|
|
|
| namespace {
|
| +
|
| const int32 kOpenerId = -2;
|
| const int32 kRouteId = 5;
|
| const int32 kMainFrameRouteId = 6;
|
| @@ -56,6 +75,30 @@ const int32 kNewWindowRouteId = 7;
|
| const int32 kNewFrameRouteId = 10;
|
| const int32 kSurfaceId = 42;
|
|
|
| +#if (defined(USE_AURA) && defined(USE_X11)) || defined(USE_OZONE)
|
| +// Converts MockKeyboard::Modifiers to ui::EventFlags.
|
| +int ConvertMockKeyboardModifier(content::MockKeyboard::Modifiers modifiers) {
|
| + static struct ModifierMap {
|
| + content::MockKeyboard::Modifiers src;
|
| + int dst;
|
| + } kModifierMap[] = {
|
| + { content::MockKeyboard::LEFT_SHIFT, ui::EF_SHIFT_DOWN },
|
| + { content::MockKeyboard::RIGHT_SHIFT, ui::EF_SHIFT_DOWN },
|
| + { content::MockKeyboard::LEFT_CONTROL, ui::EF_CONTROL_DOWN },
|
| + { content::MockKeyboard::RIGHT_CONTROL, ui::EF_CONTROL_DOWN },
|
| + { content::MockKeyboard::LEFT_ALT, ui::EF_ALT_DOWN },
|
| + { content::MockKeyboard::RIGHT_ALT, ui::EF_ALT_DOWN },
|
| + };
|
| + int flags = 0;
|
| + for (size_t i = 0; i < arraysize(kModifierMap); ++i) {
|
| + if (kModifierMap[i].src & modifiers) {
|
| + flags |= kModifierMap[i].dst;
|
| + }
|
| + }
|
| + return flags;
|
| +}
|
| +#endif
|
| +
|
| } // namespace
|
|
|
| namespace content {
|
| @@ -394,6 +437,159 @@ void RenderViewTest::Resize(gfx::Size new_size,
|
| OnMessageReceived(*resize_message);
|
| }
|
|
|
| +int RenderViewTest::SendKeyEvent(const MockKeyboard& keyboard,
|
| + int key_code,
|
| + base::string16* output) {
|
| +#if defined(OS_WIN)
|
| + // Retrieve the Unicode character for the given tuple (keyboard-layout,
|
| + // key-code, and modifiers).
|
| + // Exit when a keyboard-layout driver cannot assign a Unicode character to
|
| + // the tuple to prevent sending an invalid key code to the RenderView
|
| + // object.
|
| + CHECK(output);
|
| + int length = keyboard.GetCharacters(key_code, output);
|
| + if (length != 1)
|
| + return -1;
|
| +
|
| + // Create IPC messages from Windows messages and send them to our
|
| + // back-end.
|
| + // A keyboard event of Windows consists of three Windows messages:
|
| + // WM_KEYDOWN, WM_CHAR, and WM_KEYUP.
|
| + // WM_KEYDOWN and WM_KEYUP sends virtual-key codes. On the other hand,
|
| + // WM_CHAR sends a composed Unicode character.
|
| + MSG msg1 = {NULL, WM_KEYDOWN, key_code, 0};
|
| + ui::KeyEvent evt1(msg1);
|
| + NativeWebKeyboardEvent keydown_event(evt1);
|
| + SendNativeKeyEvent(keydown_event);
|
| +
|
| + MSG msg2 = {NULL, WM_CHAR, (*output)[0], 0};
|
| + ui::KeyEvent evt2(msg2);
|
| + NativeWebKeyboardEvent char_event(evt2);
|
| + SendNativeKeyEvent(char_event);
|
| +
|
| + MSG msg3 = {NULL, WM_KEYUP, key_code, 0};
|
| + ui::KeyEvent evt3(msg3);
|
| + NativeWebKeyboardEvent keyup_event(evt3);
|
| + SendNativeKeyEvent(keyup_event);
|
| +
|
| + return length;
|
| +#elif defined(USE_AURA) && defined(USE_X11)
|
| + // We ignore |layout|, which means we are only testing the layout of the
|
| + // current locale. TODO(mazda): fix this to respect |layout|.
|
| + CHECK(output);
|
| + const int flags = ConvertMockKeyboardModifier(keyboard.modifiers());
|
| +
|
| + ui::ScopedXI2Event xevent;
|
| + xevent.InitKeyEvent(ui::ET_KEY_PRESSED,
|
| + static_cast<ui::KeyboardCode>(key_code), flags);
|
| + ui::KeyEvent event1(xevent);
|
| + NativeWebKeyboardEvent keydown_event(event1);
|
| + SendNativeKeyEvent(keydown_event);
|
| +
|
| + // X11 doesn't actually have native character events, but give the test
|
| + // what it wants.
|
| + xevent.InitKeyEvent(ui::ET_KEY_PRESSED,
|
| + static_cast<ui::KeyboardCode>(key_code), flags);
|
| + ui::KeyEvent event2(xevent);
|
| + event2.set_character(
|
| + GetCharacterFromKeyCode(event2.key_code(), event2.flags()));
|
| + ui::KeyEventTestApi test_event2(&event2);
|
| + test_event2.set_is_char(true);
|
| + NativeWebKeyboardEvent char_event(event2);
|
| + SendNativeKeyEvent(char_event);
|
| +
|
| + xevent.InitKeyEvent(ui::ET_KEY_RELEASED,
|
| + static_cast<ui::KeyboardCode>(key_code), flags);
|
| + ui::KeyEvent event3(xevent);
|
| + NativeWebKeyboardEvent keyup_event(event3);
|
| + SendNativeKeyEvent(keyup_event);
|
| +
|
| + long c =
|
| + GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(key_code), flags);
|
| + output->assign(1, static_cast<base::char16>(c));
|
| + return 1;
|
| +#elif defined(USE_OZONE)
|
| + const int flags = ConvertMockKeyboardModifier(keyboard.modifiers());
|
| +
|
| + ui::KeyEvent keydown_event(ui::ET_KEY_PRESSED,
|
| + static_cast<ui::KeyboardCode>(key_code), flags);
|
| + NativeWebKeyboardEvent keydown_web_event(keydown_event);
|
| + SendNativeKeyEvent(keydown_web_event);
|
| +
|
| + ui::KeyEvent char_event(keydown_event.GetCharacter(),
|
| + static_cast<ui::KeyboardCode>(key_code), flags);
|
| + NativeWebKeyboardEvent char_web_event(char_event);
|
| + SendNativeKeyEvent(char_web_event);
|
| +
|
| + ui::KeyEvent keyup_event(ui::ET_KEY_RELEASED,
|
| + static_cast<ui::KeyboardCode>(key_code), flags);
|
| + NativeWebKeyboardEvent keyup_web_event(keyup_event);
|
| + SendNativeKeyEvent(keyup_web_event);
|
| +
|
| + long c =
|
| + GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(key_code), flags);
|
| + output->assign(1, static_cast<base::char16>(c));
|
| + return 1;
|
| +#else
|
| + NOTIMPLEMENTED();
|
| + return L'\0';
|
| +#endif
|
| +}
|
| +
|
| +void RenderViewTest::SimulateUserTypingASCIICharacter(char ascii_character) {
|
| + int key_code = ascii_character;
|
| + bool is_shift_pressed = false;
|
| +
|
| + if (isalnum(ascii_character)) {
|
| + key_code = base::ToUpperASCII(ascii_character);
|
| + is_shift_pressed = isupper(ascii_character);
|
| + } else if (ascii_character == '@') {
|
| + key_code = '2';
|
| + is_shift_pressed = true;
|
| + } else if (ascii_character == '.') {
|
| + key_code = ui::VKEY_OEM_PERIOD;
|
| + } else if (ascii_character == '_') {
|
| + key_code = ui::VKEY_OEM_MINUS;
|
| + is_shift_pressed = true;
|
| + } else {
|
| + NOTREACHED();
|
| + }
|
| +
|
| + SimulateUserTypingKeyCodeWithShift(key_code, is_shift_pressed);
|
| +}
|
| +
|
| +void RenderViewTest::SimulateUserTypingKeyCodeWithShift(int key_code,
|
| + bool is_shift_pressed) {
|
| + base::string16 unused_char_code;
|
| + content::MockKeyboard keyboard;
|
| + EXPECT_TRUE(keyboard.Update(
|
| + content::MockKeyboard::LAYOUT_UNITED_STATES,
|
| + is_shift_pressed ? content::MockKeyboard::LEFT_SHIFT
|
| + : content::MockKeyboard::NONE));
|
| + SendKeyEvent(keyboard, key_code, &unused_char_code);
|
| +}
|
| +
|
| +void RenderViewTest::SimulateUserInputChangeForElement(
|
| + blink::WebInputElement* input,
|
| + blink::WebFrame* input_frame,
|
| + const std::string& new_value) {
|
| + while (!input->focused())
|
| + input_frame->document().frame()->view()->advanceFocus(false);
|
| +
|
| + size_t previous_length = input->value().length();
|
| + for (size_t i = 0; i < previous_length; ++i)
|
| + SimulateUserTypingKeyCodeWithShift(ui::VKEY_BACK, false);
|
| +
|
| + EXPECT_TRUE(input->value().utf8().empty());
|
| + ASSERT_TRUE(base::IsStringASCII(new_value));
|
| + for (size_t i = 0; i < new_value.size(); ++i)
|
| + SimulateUserTypingASCIICharacter(new_value[i]);
|
| +
|
| + // Compare only beginning, because autocomplete may have filled out the
|
| + // form.
|
| + EXPECT_EQ(new_value, input->value().utf8().substr(0, new_value.length()));
|
| +}
|
| +
|
| bool RenderViewTest::OnMessageReceived(const IPC::Message& msg) {
|
| RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
|
| return impl->OnMessageReceived(msg);
|
| @@ -421,7 +617,6 @@ blink::WebWidget* RenderViewTest::GetWebWidget() {
|
| return impl->webwidget();
|
| }
|
|
|
| -
|
| ContentClient* RenderViewTest::CreateContentClient() {
|
| return new TestContentClient;
|
| }
|
|
|