blob: e14e7849ddd53ca45433ac939b189bc484c923ad [file] [log] [blame]
// Copyright (c) 2013 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 "ash/shell.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/input_method/textinput_test_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/root_window.h"
#include "ui/base/ime/input_method_factory.h"
namespace chromeos {
namespace {
ui::MockInputMethod* GetInputMethod() {
ui::MockInputMethod* input_method = static_cast<ui::MockInputMethod*>(
ash::Shell::GetPrimaryRootWindow()->GetProperty(
aura::client::kRootWindowInputMethodKey));
CHECK(input_method);
return input_method;
}
} // namespace
void TextInputTestBase::SetUpInProcessBrowserTestFixture() {
ui::SetUpInputMethodFactoryForTesting();
}
TextInputTestHelper::TextInputTestHelper()
: waiting_type_(NO_WAIT),
selection_range_(gfx::Range::InvalidRange()),
focus_state_(false),
latest_text_input_type_(ui::TEXT_INPUT_TYPE_NONE) {
GetInputMethod()->AddObserver(this);
}
TextInputTestHelper::~TextInputTestHelper() {
GetInputMethod()->RemoveObserver(this);
}
string16 TextInputTestHelper::GetSurroundingText() const {
return surrounding_text_;
}
gfx::Rect TextInputTestHelper::GetCaretRect() const {
return caret_rect_;
}
gfx::Rect TextInputTestHelper::GetCompositionHead() const {
return composition_head_;
}
gfx::Range TextInputTestHelper::GetSelectionRange() const {
return selection_range_;
}
bool TextInputTestHelper::GetFocusState() const {
return focus_state_;
}
ui::TextInputType TextInputTestHelper::GetTextInputType() const {
return latest_text_input_type_;
}
ui::TextInputClient* TextInputTestHelper::GetTextInputClient() const {
return GetInputMethod()->GetTextInputClient();
}
void TextInputTestHelper::OnTextInputTypeChanged(
const ui::TextInputClient* client) {
latest_text_input_type_ = client->GetTextInputType();
if (waiting_type_ == WAIT_ON_TEXT_INPUT_TYPE_CHANGED)
base::MessageLoop::current()->Quit();
}
void TextInputTestHelper::OnInputMethodDestroyed(
const ui::InputMethod* input_method) {
}
void TextInputTestHelper::OnFocus() {
focus_state_ = true;
if (waiting_type_ == WAIT_ON_FOCUS)
base::MessageLoop::current()->Quit();
}
void TextInputTestHelper::OnBlur() {
focus_state_ = false;
if (waiting_type_ == WAIT_ON_BLUR)
base::MessageLoop::current()->Quit();
}
void TextInputTestHelper::OnUntranslatedIMEMessage(
const base::NativeEvent& event) {
}
void TextInputTestHelper::OnCaretBoundsChanged(
const ui::TextInputClient* client) {
gfx::Range text_range;
if (!GetTextInputClient()->GetTextRange(&text_range) ||
!GetTextInputClient()->GetTextFromRange(text_range, &surrounding_text_) ||
!GetTextInputClient()->GetSelectionRange(&selection_range_))
return;
if (waiting_type_ == WAIT_ON_CARET_BOUNDS_CHANGED)
base::MessageLoop::current()->Quit();
}
void TextInputTestHelper::OnInputLocaleChanged() {
}
void TextInputTestHelper::OnTextInputStateChanged(
const ui::TextInputClient* client) {
}
void TextInputTestHelper::WaitForTextInputStateChanged(
ui::TextInputType expected_type) {
CHECK_EQ(NO_WAIT, waiting_type_);
waiting_type_ = WAIT_ON_TEXT_INPUT_TYPE_CHANGED;
while (latest_text_input_type_ != expected_type)
content::RunMessageLoop();
waiting_type_ = NO_WAIT;
}
void TextInputTestHelper::WaitForFocus() {
CHECK_EQ(NO_WAIT, waiting_type_);
waiting_type_ = WAIT_ON_FOCUS;
while (focus_state_)
content::RunMessageLoop();
waiting_type_ = NO_WAIT;
}
void TextInputTestHelper::WaitForBlur() {
CHECK_EQ(NO_WAIT, waiting_type_);
waiting_type_ = WAIT_ON_BLUR;
while (!focus_state_)
content::RunMessageLoop();
waiting_type_ = NO_WAIT;
}
void TextInputTestHelper::WaitForCaretBoundsChanged(
const gfx::Rect& expected_caret_rect,
const gfx::Rect& expected_composition_head) {
waiting_type_ = WAIT_ON_CARET_BOUNDS_CHANGED;
while (expected_caret_rect != caret_rect_ ||
expected_composition_head != composition_head_)
content::RunMessageLoop();
waiting_type_ = NO_WAIT;
}
void TextInputTestHelper::WaitForSurroundingTextChanged(
const string16& expected_text,
const gfx::Range& expected_selection) {
waiting_type_ = WAIT_ON_CARET_BOUNDS_CHANGED;
while (expected_text != surrounding_text_ ||
expected_selection != selection_range_)
content::RunMessageLoop();
waiting_type_ = NO_WAIT;
}
// static
bool TextInputTestHelper::ConvertRectFromString(const std::string& str,
gfx::Rect* rect) {
DCHECK(rect);
std::vector<std::string> rect_piece;
if (Tokenize(str, ",", &rect_piece) != 4UL)
return false;
int x, y, width, height;
if (!base::StringToInt(rect_piece[0], &x))
return false;
if (!base::StringToInt(rect_piece[1], &y))
return false;
if (!base::StringToInt(rect_piece[2], &width))
return false;
if (!base::StringToInt(rect_piece[3], &height))
return false;
*rect = gfx::Rect(x, y, width, height);
return true;
}
// static
bool TextInputTestHelper::ClickElement(const std::string& id,
content::WebContents* tab) {
std::string coordinate;
if (!content::ExecuteScriptAndExtractString(
tab,
"textinput_helper.retrieveElementCoordinate('" + id + "')",
&coordinate))
return false;
gfx::Rect rect;
if (!ConvertRectFromString(coordinate, &rect))
return false;
WebKit::WebMouseEvent mouse_event;
mouse_event.type = WebKit::WebInputEvent::MouseDown;
mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
mouse_event.x = rect.CenterPoint().x();
mouse_event.y = rect.CenterPoint().y();
mouse_event.clickCount = 1;
tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
mouse_event.type = WebKit::WebInputEvent::MouseUp;
tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
return true;
}
} // namespace chromeos