From 182bd9a5fd7a9f031c9c88aba15fbe17475236fb Mon Sep 17 00:00:00 2001 From: "phajdan.jr@chromium.org" Date: Tue, 24 Aug 2010 21:25:25 +0000 Subject: GTTF: move tests that use WebKit from unit_tests to browser_tests to avoid crashes. TBR=dhollowa, sky, erikkay TEST=unit_tests, browser_tests BUG=52731, 52643 Review URL: http://codereview.chromium.org/3150034 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57236 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/renderer/render_view_browsertest.cc | 1091 ++++++++++++++++++++++++++++ 1 file changed, 1091 insertions(+) create mode 100644 chrome/renderer/render_view_browsertest.cc (limited to 'chrome/renderer/render_view_browsertest.cc') diff --git a/chrome/renderer/render_view_browsertest.cc b/chrome/renderer/render_view_browsertest.cc new file mode 100644 index 0000000..f2d507a --- /dev/null +++ b/chrome/renderer/render_view_browsertest.cc @@ -0,0 +1,1091 @@ +// Copyright (c) 2010 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 "base/basictypes.h" + +#include "base/file_util.h" +#include "base/keyboard_codes.h" +#include "base/shared_memory.h" +#include "base/utf_string_conversions.h" +#include "chrome/common/content_settings.h" +#include "chrome/common/native_web_keyboard_event.h" +#include "chrome/common/render_messages.h" +#include "chrome/common/render_messages_params.h" +#include "chrome/renderer/print_web_view_helper.h" +#include "chrome/test/render_view_test.h" +#include "gfx/codec/jpeg_codec.h" +#include "net/base/net_errors.h" +#include "printing/image.h" +#include "printing/native_metafile.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" +#include "third_party/WebKit/WebKit/chromium/public/WebInputElement.h" +#include "third_party/WebKit/WebKit/chromium/public/WebString.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLError.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" +#include "webkit/glue/form_data.h" +#include "webkit/glue/form_field.h" + +using WebKit::WebDocument; +using WebKit::WebFrame; +using WebKit::WebInputElement; +using WebKit::WebString; +using WebKit::WebTextDirection; +using WebKit::WebURLError; +using webkit_glue::FormData; +using webkit_glue::FormField; + +// Test that we get form state change notifications when input fields change. +TEST_F(RenderViewTest, OnNavStateChanged) { + // Don't want any delay for form state sync changes. This will still post a + // message so updates will get coalesced, but as soon as we spin the message + // loop, it will generate an update. + view_->set_send_content_state_immediately(true); + + LoadHTML(""); + + // We should NOT have gotten a form state change notification yet. + EXPECT_FALSE(render_thread_.sink().GetFirstMessageMatching( + ViewHostMsg_UpdateState::ID)); + render_thread_.sink().ClearMessages(); + + // Change the value of the input. We should have gotten an update state + // notification. We need to spin the message loop to catch this update. + ExecuteJavaScript("document.getElementById('elt_text').value = 'foo';"); + ProcessPendingMessages(); + EXPECT_TRUE(render_thread_.sink().GetUniqueMessageMatching( + ViewHostMsg_UpdateState::ID)); +} + +// Test that our IME backend sends a notification message when the input focus +// changes. +TEST_F(RenderViewTest, OnImeStateChanged) { + // Enable our IME backend code. + view_->OnSetInputMethodActive(true); + + // Load an HTML page consisting of two input fields. + view_->set_send_content_state_immediately(true); + LoadHTML("" + "" + "" + "" + "" + "" + "" + ""); + render_thread_.sink().ClearMessages(); + + const int kRepeatCount = 10; + for (int i = 0; i < kRepeatCount; i++) { + // Move the input focus to the first element, where we should + // activate IMEs. + ExecuteJavaScript("document.getElementById('test1').focus();"); + ProcessPendingMessages(); + render_thread_.sink().ClearMessages(); + + // Update the IME status and verify if our IME backend sends an IPC message + // to activate IMEs. + view_->UpdateInputMethod(); + const IPC::Message* msg = render_thread_.sink().GetMessageAt(0); + EXPECT_TRUE(msg != NULL); + EXPECT_EQ(ViewHostMsg_ImeUpdateTextInputState::ID, msg->type()); + ViewHostMsg_ImeUpdateTextInputState::Param params; + ViewHostMsg_ImeUpdateTextInputState::Read(msg, ¶ms); + EXPECT_EQ(params.a, WebKit::WebTextInputTypeText); + EXPECT_TRUE(params.b.x() > 0 && params.b.y() > 0); + + // Move the input focus to the second element, where we should + // de-activate IMEs. + ExecuteJavaScript("document.getElementById('test2').focus();"); + ProcessPendingMessages(); + render_thread_.sink().ClearMessages(); + + // Update the IME status and verify if our IME backend sends an IPC message + // to de-activate IMEs. + view_->UpdateInputMethod(); + msg = render_thread_.sink().GetMessageAt(0); + EXPECT_TRUE(msg != NULL); + EXPECT_EQ(ViewHostMsg_ImeUpdateTextInputState::ID, msg->type()); + ViewHostMsg_ImeUpdateTextInputState::Read(msg, ¶ms); + EXPECT_EQ(params.a, WebKit::WebTextInputTypePassword); + } +} + +// Test that our IME backend can compose CJK words. +// Our IME front-end sends many platform-independent messages to the IME backend +// while it composes CJK words. This test sends the minimal messages captured +// on my local environment directly to the IME backend to verify if the backend +// can compose CJK words without any problems. +// This test uses an array of command sets because an IME composotion does not +// only depends on IME events, but also depends on window events, e.g. moving +// the window focus while composing a CJK text. To handle such complicated +// cases, this test should not only call IME-related functions in the +// RenderWidget class, but also call some RenderWidget members, e.g. +// ExecuteJavaScript(), RenderWidget::OnSetFocus(), etc. +TEST_F(RenderViewTest, ImeComposition) { + enum ImeCommand { + IME_INITIALIZE, + IME_SETINPUTMODE, + IME_SETFOCUS, + IME_SETCOMPOSITION, + IME_CONFIRMCOMPOSITION, + IME_CANCELCOMPOSITION + }; + struct ImeMessage { + ImeCommand command; + bool enable; + int selection_start; + int selection_end; + const wchar_t* ime_string; + const wchar_t* result; + }; + static const ImeMessage kImeMessages[] = { + // Scenario 1: input a Chinese word with Microsoft IME (on Vista). + {IME_INITIALIZE, true, 0, 0, NULL, NULL}, + {IME_SETINPUTMODE, true, 0, 0, NULL, NULL}, + {IME_SETFOCUS, true, 0, 0, NULL, NULL}, + {IME_SETCOMPOSITION, false, 1, 1, L"n", L"n"}, + {IME_SETCOMPOSITION, false, 2, 2, L"ni", L"ni"}, + {IME_SETCOMPOSITION, false, 3, 3, L"nih", L"nih"}, + {IME_SETCOMPOSITION, false, 4, 4, L"niha", L"niha"}, + {IME_SETCOMPOSITION, false, 5, 5, L"nihao", L"nihao"}, + {IME_SETCOMPOSITION, false, 2, 2, L"\x4F60\x597D", L"\x4F60\x597D"}, + {IME_CONFIRMCOMPOSITION, false, -1, -1, NULL, L"\x4F60\x597D"}, + {IME_CANCELCOMPOSITION, false, -1, -1, L"", L"\x4F60\x597D"}, + // Scenario 2: input a Japanese word with Microsoft IME (on Vista). + {IME_INITIALIZE, true, 0, 0, NULL, NULL}, + {IME_SETINPUTMODE, true, 0, 0, NULL, NULL}, + {IME_SETFOCUS, true, 0, 0, NULL, NULL}, + {IME_SETCOMPOSITION, false, 0, 1, L"\xFF4B", L"\xFF4B"}, + {IME_SETCOMPOSITION, false, 0, 1, L"\x304B", L"\x304B"}, + {IME_SETCOMPOSITION, false, 0, 2, L"\x304B\xFF4E", L"\x304B\xFF4E"}, + {IME_SETCOMPOSITION, false, 0, 3, L"\x304B\x3093\xFF4A", + L"\x304B\x3093\xFF4A"}, + {IME_SETCOMPOSITION, false, 0, 3, L"\x304B\x3093\x3058", + L"\x304B\x3093\x3058"}, + {IME_SETCOMPOSITION, false, 0, 2, L"\x611F\x3058", L"\x611F\x3058"}, + {IME_SETCOMPOSITION, false, 0, 2, L"\x6F22\x5B57", L"\x6F22\x5B57"}, + {IME_CONFIRMCOMPOSITION, false, -1, -1, NULL, L"\x6F22\x5B57"}, + {IME_CANCELCOMPOSITION, false, -1, -1, L"", L"\x6F22\x5B57"}, + // Scenario 3: input a Korean word with Microsot IME (on Vista). + {IME_INITIALIZE, true, 0, 0, NULL, NULL}, + {IME_SETINPUTMODE, true, 0, 0, NULL, NULL}, + {IME_SETFOCUS, true, 0, 0, NULL, NULL}, + {IME_SETCOMPOSITION, false, 0, 1, L"\x3147", L"\x3147"}, + {IME_SETCOMPOSITION, false, 0, 1, L"\xC544", L"\xC544"}, + {IME_SETCOMPOSITION, false, 0, 1, L"\xC548", L"\xC548"}, + {IME_CONFIRMCOMPOSITION, false, -1, -1, NULL, L"\xC548"}, + {IME_SETCOMPOSITION, false, 0, 1, L"\x3134", L"\xC548\x3134"}, + {IME_SETCOMPOSITION, false, 0, 1, L"\xB140", L"\xC548\xB140"}, + {IME_SETCOMPOSITION, false, 0, 1, L"\xB155", L"\xC548\xB155"}, + {IME_CANCELCOMPOSITION, false, -1, -1, L"", L"\xC548"}, + {IME_SETCOMPOSITION, false, 0, 1, L"\xB155", L"\xC548\xB155"}, + {IME_CONFIRMCOMPOSITION, false, -1, -1, NULL, L"\xC548\xB155"}, + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kImeMessages); i++) { + const ImeMessage* ime_message = &kImeMessages[i]; + switch (ime_message->command) { + case IME_INITIALIZE: + // Load an HTML page consisting of a content-editable
element, + // and move the input focus to the
element, where we can use + // IMEs. + view_->OnSetInputMethodActive(ime_message->enable); + view_->set_send_content_state_immediately(true); + LoadHTML("" + "" + "" + "" + "
" + "" + ""); + ExecuteJavaScript("document.getElementById('test1').focus();"); + break; + + case IME_SETINPUTMODE: + // Activate (or deactivate) our IME back-end. + view_->OnSetInputMethodActive(ime_message->enable); + break; + + case IME_SETFOCUS: + // Update the window focus. + view_->OnSetFocus(ime_message->enable); + break; + + case IME_SETCOMPOSITION: + view_->OnImeSetComposition( + WideToUTF16Hack(ime_message->ime_string), + std::vector(), + ime_message->selection_start, + ime_message->selection_end); + break; + + case IME_CONFIRMCOMPOSITION: + view_->OnImeConfirmComposition(); + break; + + case IME_CANCELCOMPOSITION: + view_->OnImeSetComposition(string16(), + std::vector(), + 0, 0); + break; + } + + // Update the status of our IME back-end. + // TODO(hbono): we should verify messages to be sent from the back-end. + view_->UpdateInputMethod(); + ProcessPendingMessages(); + render_thread_.sink().ClearMessages(); + + if (ime_message->result) { + // Retrieve the content of this page and compare it with the expected + // result. + const int kMaxOutputCharacters = 128; + std::wstring output = UTF16ToWideHack( + GetMainFrame()->contentAsText(kMaxOutputCharacters)); + EXPECT_EQ(output, ime_message->result); + } + } +} + +// Test that the RenderView::OnSetTextDirection() function can change the text +// direction of the selected input element. +TEST_F(RenderViewTest, OnSetTextDirection) { + // Load an HTML page consisting of a " + "
" + "" + ""); + render_thread_.sink().ClearMessages(); + + static const struct { + WebTextDirection direction; + const wchar_t* expected_result; + } kTextDirection[] = { + { WebKit::WebTextDirectionRightToLeft, L"\x000A" L"rtl,rtl" }, + { WebKit::WebTextDirectionLeftToRight, L"\x000A" L"ltr,ltr" }, + }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTextDirection); ++i) { + // Set the text direction of the