textinput_test_helper.cc revision 58537e28ecd584eab876aee8be7156509866d23a
1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ash/shell.h" 6#include "base/strings/string_number_conversions.h" 7#include "base/strings/string_util.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/browser/chromeos/input_method/textinput_test_helper.h" 10#include "chrome/browser/ui/browser.h" 11#include "chrome/test/base/interactive_test_utils.h" 12#include "content/public/browser/render_view_host.h" 13#include "content/public/browser/web_contents.h" 14#include "content/public/test/browser_test_utils.h" 15#include "ui/aura/client/aura_constants.h" 16#include "ui/aura/root_window.h" 17#include "ui/base/ime/input_method_factory.h" 18 19namespace chromeos { 20namespace { 21ui::MockInputMethod* GetInputMethod() { 22 ui::MockInputMethod* input_method = static_cast<ui::MockInputMethod*>( 23 ash::Shell::GetPrimaryRootWindow()->GetProperty( 24 aura::client::kRootWindowInputMethodKey)); 25 CHECK(input_method); 26 return input_method; 27} 28} // namespace 29 30void TextInputTestBase::SetUpInProcessBrowserTestFixture() { 31 ui::SetUpInputMethodFactoryForTesting(); 32} 33 34TextInputTestHelper::TextInputTestHelper() 35 : waiting_type_(NO_WAIT), 36 selection_range_(gfx::Range::InvalidRange()), 37 focus_state_(false), 38 latest_text_input_type_(ui::TEXT_INPUT_TYPE_NONE) { 39 GetInputMethod()->AddObserver(this); 40} 41 42TextInputTestHelper::~TextInputTestHelper() { 43 GetInputMethod()->RemoveObserver(this); 44} 45 46string16 TextInputTestHelper::GetSurroundingText() const { 47 return surrounding_text_; 48} 49 50gfx::Rect TextInputTestHelper::GetCaretRect() const { 51 return caret_rect_; 52} 53 54gfx::Rect TextInputTestHelper::GetCompositionHead() const { 55 return composition_head_; 56} 57 58gfx::Range TextInputTestHelper::GetSelectionRange() const { 59 return selection_range_; 60} 61 62bool TextInputTestHelper::GetFocusState() const { 63 return focus_state_; 64} 65 66ui::TextInputType TextInputTestHelper::GetTextInputType() const { 67 return latest_text_input_type_; 68} 69 70ui::TextInputClient* TextInputTestHelper::GetTextInputClient() const { 71 return GetInputMethod()->GetTextInputClient(); 72} 73 74void TextInputTestHelper::OnTextInputTypeChanged( 75 const ui::TextInputClient* client) { 76 latest_text_input_type_ = client->GetTextInputType(); 77 if (waiting_type_ == WAIT_ON_TEXT_INPUT_TYPE_CHANGED) 78 base::MessageLoop::current()->Quit(); 79} 80 81void TextInputTestHelper::OnInputMethodDestroyed( 82 const ui::InputMethod* input_method) { 83} 84 85void TextInputTestHelper::OnFocus() { 86 focus_state_ = true; 87 if (waiting_type_ == WAIT_ON_FOCUS) 88 base::MessageLoop::current()->Quit(); 89} 90 91void TextInputTestHelper::OnBlur() { 92 focus_state_ = false; 93 if (waiting_type_ == WAIT_ON_BLUR) 94 base::MessageLoop::current()->Quit(); 95} 96 97void TextInputTestHelper::OnUntranslatedIMEMessage( 98 const base::NativeEvent& event) { 99} 100 101void TextInputTestHelper::OnCaretBoundsChanged( 102 const ui::TextInputClient* client) { 103 gfx::Range text_range; 104 if (!GetTextInputClient()->GetTextRange(&text_range) || 105 !GetTextInputClient()->GetTextFromRange(text_range, &surrounding_text_) || 106 !GetTextInputClient()->GetSelectionRange(&selection_range_)) 107 return; 108 if (waiting_type_ == WAIT_ON_CARET_BOUNDS_CHANGED) 109 base::MessageLoop::current()->Quit(); 110} 111 112void TextInputTestHelper::OnInputLocaleChanged() { 113} 114 115void TextInputTestHelper::OnTextInputStateChanged( 116 const ui::TextInputClient* client) { 117} 118 119void TextInputTestHelper::WaitForTextInputStateChanged( 120 ui::TextInputType expected_type) { 121 CHECK_EQ(NO_WAIT, waiting_type_); 122 waiting_type_ = WAIT_ON_TEXT_INPUT_TYPE_CHANGED; 123 while (latest_text_input_type_ != expected_type) 124 content::RunMessageLoop(); 125 waiting_type_ = NO_WAIT; 126} 127 128void TextInputTestHelper::WaitForFocus() { 129 CHECK_EQ(NO_WAIT, waiting_type_); 130 waiting_type_ = WAIT_ON_FOCUS; 131 while (focus_state_) 132 content::RunMessageLoop(); 133 waiting_type_ = NO_WAIT; 134} 135 136void TextInputTestHelper::WaitForBlur() { 137 CHECK_EQ(NO_WAIT, waiting_type_); 138 waiting_type_ = WAIT_ON_BLUR; 139 while (!focus_state_) 140 content::RunMessageLoop(); 141 waiting_type_ = NO_WAIT; 142} 143 144void TextInputTestHelper::WaitForCaretBoundsChanged( 145 const gfx::Rect& expected_caret_rect, 146 const gfx::Rect& expected_composition_head) { 147 waiting_type_ = WAIT_ON_CARET_BOUNDS_CHANGED; 148 while (expected_caret_rect != caret_rect_ || 149 expected_composition_head != composition_head_) 150 content::RunMessageLoop(); 151 waiting_type_ = NO_WAIT; 152} 153 154void TextInputTestHelper::WaitForSurroundingTextChanged( 155 const string16& expected_text, 156 const gfx::Range& expected_selection) { 157 waiting_type_ = WAIT_ON_CARET_BOUNDS_CHANGED; 158 while (expected_text != surrounding_text_ || 159 expected_selection != selection_range_) 160 content::RunMessageLoop(); 161 waiting_type_ = NO_WAIT; 162} 163 164// static 165bool TextInputTestHelper::ConvertRectFromString(const std::string& str, 166 gfx::Rect* rect) { 167 DCHECK(rect); 168 std::vector<std::string> rect_piece; 169 if (Tokenize(str, ",", &rect_piece) != 4UL) 170 return false; 171 int x, y, width, height; 172 if (!base::StringToInt(rect_piece[0], &x)) 173 return false; 174 if (!base::StringToInt(rect_piece[1], &y)) 175 return false; 176 if (!base::StringToInt(rect_piece[2], &width)) 177 return false; 178 if (!base::StringToInt(rect_piece[3], &height)) 179 return false; 180 *rect = gfx::Rect(x, y, width, height); 181 return true; 182} 183 184// static 185bool TextInputTestHelper::ClickElement(const std::string& id, 186 content::WebContents* tab) { 187 std::string coordinate; 188 if (!content::ExecuteScriptAndExtractString( 189 tab, 190 "textinput_helper.retrieveElementCoordinate('" + id + "')", 191 &coordinate)) 192 return false; 193 gfx::Rect rect; 194 if (!ConvertRectFromString(coordinate, &rect)) 195 return false; 196 197 WebKit::WebMouseEvent mouse_event; 198 mouse_event.type = WebKit::WebInputEvent::MouseDown; 199 mouse_event.button = WebKit::WebMouseEvent::ButtonLeft; 200 mouse_event.x = rect.CenterPoint().x(); 201 mouse_event.y = rect.CenterPoint().y(); 202 mouse_event.clickCount = 1; 203 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 204 205 mouse_event.type = WebKit::WebInputEvent::MouseUp; 206 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 207 return true; 208} 209 210} // namespace chromeos 211