blob: b2cfba3c1cac402f9b6ccd1238dda901fa3195e6 [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 "chrome/browser/chromeos/input_method/textinput_test_helper.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/input_method_factory.h"
namespace chromeos {
void TextInputTestBase::SetUpInProcessBrowserTestFixture() {
ui::SetUpInputMethodFactoryForTesting();
}
ui::InputMethod* TextInputTestBase::GetInputMethod() const {
return browser()->window()->GetNativeWindow()->GetHost()->GetInputMethod();
}
TextInputTestHelper::TextInputTestHelper(ui::InputMethod* input_method)
: waiting_type_(NO_WAIT),
selection_range_(gfx::Range::InvalidRange()),
focus_state_(false),
latest_text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
input_method_(input_method) {
input_method_->AddObserver(this);
}
TextInputTestHelper::~TextInputTestHelper() {
input_method_->RemoveObserver(this);
}
base::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 input_method_->GetTextInputClient();
}
void TextInputTestHelper::OnShowVirtualKeyboardIfEnabled() {}
void TextInputTestHelper::OnInputMethodDestroyed(
const ui::InputMethod* input_method) {
}
void TextInputTestHelper::OnFocus() {
focus_state_ = true;
if (waiting_type_ == WAIT_ON_FOCUS)
base::RunLoop::QuitCurrentWhenIdleDeprecated();
}
void TextInputTestHelper::OnBlur() {
focus_state_ = false;
if (waiting_type_ == WAIT_ON_BLUR)
base::RunLoop::QuitCurrentWhenIdleDeprecated();
}
void TextInputTestHelper::OnCaretBoundsChanged(
const ui::TextInputClient* client) {
gfx::Range text_range;
if (GetTextInputClient()) {
if (!GetTextInputClient()->GetTextRange(&text_range) ||
!GetTextInputClient()->GetTextFromRange(text_range,
&surrounding_text_) ||
!GetTextInputClient()->GetEditableSelectionRange(&selection_range_))
return;
}
if (waiting_type_ == WAIT_ON_CARET_BOUNDS_CHANGED)
base::RunLoop::QuitCurrentWhenIdleDeprecated();
}
void TextInputTestHelper::OnTextInputStateChanged(
const ui::TextInputClient* client) {
latest_text_input_type_ =
client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE;
if (waiting_type_ == WAIT_ON_TEXT_INPUT_TYPE_CHANGED)
base::RunLoop::QuitCurrentWhenIdleDeprecated();
}
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 base::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;
}
void TextInputTestHelper::WaitForPassageOfTimeMillis(const int milliseconds) {
CHECK_EQ(NO_WAIT, waiting_type_);
waiting_type_ = WAIT_ON_PASSAGE_OF_TIME;
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(milliseconds));
waiting_type_ = NO_WAIT;
}
// static
bool TextInputTestHelper::ConvertRectFromString(const std::string& str,
gfx::Rect* rect) {
DCHECK(rect);
std::vector<base::StringPiece> rect_piece = base::SplitStringPiece(
str, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
if (rect_piece.size() != 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;
blink::WebMouseEvent mouse_event(
blink::WebInputEvent::kMouseDown, blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::GetStaticTimeStampForTests());
mouse_event.button = blink::WebMouseEvent::Button::kLeft;
mouse_event.SetPositionInWidget(rect.CenterPoint().x(),
rect.CenterPoint().y());
mouse_event.click_count = 1;
tab->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(mouse_event);
mouse_event.SetType(blink::WebInputEvent::kMouseUp);
tab->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(mouse_event);
return true;
}
} // namespace chromeos