1 // Copyright 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 "chrome/browser/chromeos/input_method/textinput_test_helper.h" 6 #include "chrome/browser/ui/browser.h" 7 #include "chrome/browser/ui/browser_window.h" 8 #include "chrome/browser/ui/tabs/tab_strip_model.h" 9 #include "chrome/test/base/in_process_browser_test.h" 10 #include "chrome/test/base/interactive_test_utils.h" 11 #include "content/public/browser/render_view_host.h" 12 #include "content/public/browser/web_contents.h" 13 #include "content/public/test/browser_test_utils.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 16 namespace chromeos { 17 18 namespace { 19 struct InputTypeExpectation { 20 std::string node_id; 21 ui::TextInputType type; 22 }; 23 } // namespace 24 25 typedef TextInputTestBase TextInput_TextInputStateChangedTest; 26 27 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, 28 SwitchToPasswordFieldTest) { 29 TextInputTestHelper helper; 30 GURL url = ui_test_utils::GetTestUrl( 31 base::FilePath(FILE_PATH_LITERAL("textinput")), 32 base::FilePath(FILE_PATH_LITERAL("ime_enable_disable_test.html"))); 33 ui_test_utils::NavigateToURL(browser(), url); 34 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 35 36 content::WebContents* tab = 37 browser()->tab_strip_model()->GetActiveWebContents(); 38 39 bool worker_finished = false; 40 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 41 tab, 42 "window.domAutomationController.send(text01_focus());", 43 &worker_finished)); 44 EXPECT_TRUE(worker_finished); 45 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT); 46 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType()); 47 48 worker_finished = false; 49 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 50 tab, 51 "window.domAutomationController.send(password01_focus());", 52 &worker_finished)); 53 EXPECT_TRUE(worker_finished); 54 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD); 55 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType()); 56 } 57 58 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, FocusOnLoadTest) { 59 TextInputTestHelper helper; 60 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 61 62 GURL url = ui_test_utils::GetTestUrl( 63 base::FilePath(FILE_PATH_LITERAL("textinput")), 64 base::FilePath(FILE_PATH_LITERAL("focus_input_on_load.html"))); 65 ui_test_utils::NavigateToURL(browser(), url); 66 67 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT); 68 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType()); 69 } 70 71 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, 72 FocusOnContentJSTest) { 73 TextInputTestHelper helper; 74 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 75 76 GURL url = ui_test_utils::GetTestUrl( 77 base::FilePath(FILE_PATH_LITERAL("textinput")), 78 base::FilePath(FILE_PATH_LITERAL("focus_input_on_content_js.html"))); 79 ui_test_utils::NavigateToURL(browser(), url); 80 81 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT); 82 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType()); 83 } 84 85 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, 86 MouseClickChange) { 87 TextInputTestHelper helper; 88 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 89 90 GURL url = ui_test_utils::GetTestUrl( 91 base::FilePath(FILE_PATH_LITERAL("textinput")), 92 base::FilePath(FILE_PATH_LITERAL("focus_input_with_mouse_click.html"))); 93 ui_test_utils::NavigateToURL(browser(), url); 94 95 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 96 97 content::WebContents* tab = 98 browser()->tab_strip_model()->GetActiveWebContents(); 99 content::WaitForLoadStop(tab); 100 101 ASSERT_TRUE(helper.ClickElement("text_id", tab)); 102 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT); 103 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType()); 104 105 ASSERT_TRUE(helper.ClickElement("password_id", tab)); 106 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD); 107 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType()); 108 } 109 110 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, 111 FocusChangeOnFocus) { 112 TextInputTestHelper helper; 113 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 114 115 GURL url = ui_test_utils::GetTestUrl( 116 base::FilePath(FILE_PATH_LITERAL("textinput")), 117 base::FilePath(FILE_PATH_LITERAL("focus_input_on_anothor_focus.html"))); 118 ui_test_utils::NavigateToURL(browser(), url); 119 120 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 121 122 content::WebContents* tab = 123 browser()->tab_strip_model()->GetActiveWebContents(); 124 125 std::string coordinate; 126 ASSERT_TRUE(content::ExecuteScript( 127 tab, 128 "document.getElementById('text_id').focus();")); 129 130 // Expects PASSWORD text input type because javascript will chagne the focus 131 // to password field in #text_id's onfocus handler. 132 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD); 133 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType()); 134 135 ASSERT_TRUE(helper.ClickElement("text_id", tab)); 136 // Expects PASSWORD text input type because javascript will chagne the focus 137 // to password field in #text_id's onfocus handler. 138 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD); 139 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType()); 140 } 141 142 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, 143 NodeEliminationCase) { 144 TextInputTestHelper helper; 145 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 146 147 GURL url = ui_test_utils::GetTestUrl( 148 base::FilePath(FILE_PATH_LITERAL("textinput")), 149 base::FilePath(FILE_PATH_LITERAL("simple_textinput.html"))); 150 ui_test_utils::NavigateToURL(browser(), url); 151 152 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 153 154 content::WebContents* tab = 155 browser()->tab_strip_model()->GetActiveWebContents(); 156 157 ASSERT_TRUE(content::ExecuteScript( 158 tab, 159 "document.getElementById('text_id').focus();")); 160 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT); 161 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType()); 162 163 // Changing text input type to password. 164 ASSERT_TRUE(content::ExecuteScript( 165 tab, 166 "document.body.removeChild(document.getElementById('text_id'));")); 167 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_NONE); 168 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 169 } 170 171 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, 172 TextInputTypeChangedByJavaScript) { 173 TextInputTestHelper helper; 174 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 175 176 GURL url = ui_test_utils::GetTestUrl( 177 base::FilePath(FILE_PATH_LITERAL("textinput")), 178 base::FilePath(FILE_PATH_LITERAL("simple_textinput.html"))); 179 ui_test_utils::NavigateToURL(browser(), url); 180 181 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 182 183 content::WebContents* tab = 184 browser()->tab_strip_model()->GetActiveWebContents(); 185 186 ASSERT_TRUE(content::ExecuteScript( 187 tab, 188 "document.getElementById('text_id').focus();")); 189 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT); 190 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType()); 191 192 // Changing text input type to password. 193 ASSERT_TRUE(content::ExecuteScript( 194 tab, 195 "document.getElementById('text_id').type = 'password';")); 196 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD); 197 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType()); 198 } 199 200 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, 201 ChangingToContentEditableCase) { 202 TextInputTestHelper helper; 203 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 204 205 GURL url = ui_test_utils::GetTestUrl( 206 base::FilePath(FILE_PATH_LITERAL("textinput")), 207 base::FilePath(FILE_PATH_LITERAL("content_editable.html"))); 208 ui_test_utils::NavigateToURL(browser(), url); 209 content::WebContents* tab = 210 browser()->tab_strip_model()->GetActiveWebContents(); 211 212 helper.ClickElement("anchor_id", tab); 213 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE); 214 EXPECT_EQ(ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE, helper.GetTextInputType()); 215 216 217 // Disabling content editable, then expecting TEXT_INPUT_TYPE_NONE. 218 ASSERT_TRUE(content::ExecuteScript( 219 tab, 220 "document.getElementById('anchor_id').contentEditable = false;")); 221 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_NONE); 222 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 223 224 // Then re-enabling content editable, then expecting CONTENT_EDITABLE. 225 ASSERT_TRUE(content::ExecuteScript( 226 tab, 227 "document.getElementById('anchor_id').contentEditable = true;")); 228 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE); 229 EXPECT_EQ(ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE, helper.GetTextInputType()); 230 } 231 232 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, 233 SwitchingAllTextInputTest) { 234 TextInputTestHelper helper; 235 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 236 237 GURL url = ui_test_utils::GetTestUrl( 238 base::FilePath(FILE_PATH_LITERAL("textinput")), 239 base::FilePath(FILE_PATH_LITERAL("all_input_node.html"))); 240 ui_test_utils::NavigateToURL(browser(), url); 241 content::WebContents* tab = 242 browser()->tab_strip_model()->GetActiveWebContents(); 243 244 InputTypeExpectation expectations[] = { 245 { "text_id", ui::TEXT_INPUT_TYPE_TEXT }, 246 { "password_id", ui::TEXT_INPUT_TYPE_PASSWORD }, 247 { "search_id", ui::TEXT_INPUT_TYPE_SEARCH }, 248 { "email_id", ui::TEXT_INPUT_TYPE_EMAIL }, 249 { "number_id", ui::TEXT_INPUT_TYPE_NUMBER }, 250 { "tel_id", ui::TEXT_INPUT_TYPE_TELEPHONE }, 251 { "url_id", ui::TEXT_INPUT_TYPE_URL }, 252 { "textarea_id", ui::TEXT_INPUT_TYPE_TEXT_AREA }, 253 { "contenteditable_id", ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE }, 254 }; // The order should be same as tab order in all_input_node.html. 255 256 for (size_t i = 0; i < arraysize(expectations); ++i) { 257 content::SimulateKeyPress(tab, ui::VKEY_TAB, false, false, false, false); 258 259 helper.WaitForTextInputStateChanged(expectations[i].type); 260 EXPECT_EQ(expectations[i].type, helper.GetTextInputType()); 261 } 262 263 for (size_t i = 0; i < arraysize(expectations); ++i) { 264 helper.ClickElement(expectations[i].node_id, tab); 265 266 helper.WaitForTextInputStateChanged(expectations[i].type); 267 EXPECT_EQ(expectations[i].type, helper.GetTextInputType()); 268 } 269 } 270 271 IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, 272 OpenNewTabOnloadTest) { 273 TextInputTestHelper helper; 274 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType()); 275 276 GURL base_url = ui_test_utils::GetTestUrl( 277 base::FilePath(FILE_PATH_LITERAL("textinput")), 278 base::FilePath(FILE_PATH_LITERAL("all_input_node.html"))); 279 ui_test_utils::NavigateToURL(browser(), base_url); 280 content::WebContents* base_tab = 281 browser()->tab_strip_model()->GetActiveWebContents(); 282 283 // Focus to password field. 284 helper.ClickElement("password_id", base_tab); 285 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD); 286 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType()); 287 288 // Then opening new foreground tab and wait new TextInputType. 289 GURL new_url = ui_test_utils::GetTestUrl( 290 base::FilePath(FILE_PATH_LITERAL("textinput")), 291 base::FilePath(FILE_PATH_LITERAL("focus_input_on_load.html"))); 292 ui_test_utils::NavigateToURLWithDisposition(browser(), 293 new_url, 294 NEW_FOREGROUND_TAB, 295 0); 296 content::WebContents* new_tab = 297 browser()->tab_strip_model()->GetActiveWebContents(); 298 EXPECT_NE(base_tab, new_tab); 299 300 helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT); 301 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType()); 302 } 303 304 } // namespace chromeos 305