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
16namespace chromeos {
17
18namespace {
19struct InputTypeExpectation {
20  std::string node_id;
21  ui::TextInputType type;
22};
23}  // namespace
24
25typedef TextInputTestBase TextInput_TextInputStateChangedTest;
26
27IN_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
58IN_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
71IN_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
85IN_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
110IN_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
142IN_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
171IN_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
200IN_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
232IN_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// Flaky on chromeos.  http://crbug.com/391582
272IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest,
273                       DISABLED_OpenNewTabOnloadTest) {
274  TextInputTestHelper helper;
275  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());
276
277  GURL base_url = ui_test_utils::GetTestUrl(
278      base::FilePath(FILE_PATH_LITERAL("textinput")),
279      base::FilePath(FILE_PATH_LITERAL("all_input_node.html")));
280  ui_test_utils::NavigateToURL(browser(), base_url);
281  content::WebContents* base_tab =
282      browser()->tab_strip_model()->GetActiveWebContents();
283
284  // Focus to password field.
285  helper.ClickElement("password_id", base_tab);
286  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD);
287  EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType());
288
289  // Then opening new foreground tab and wait new TextInputType.
290  GURL new_url = ui_test_utils::GetTestUrl(
291      base::FilePath(FILE_PATH_LITERAL("textinput")),
292      base::FilePath(FILE_PATH_LITERAL("focus_input_on_load.html")));
293  ui_test_utils::NavigateToURLWithDisposition(browser(),
294                                              new_url,
295                                              NEW_FOREGROUND_TAB,
296                                              0);
297  content::WebContents* new_tab =
298      browser()->tab_strip_model()->GetActiveWebContents();
299  EXPECT_NE(base_tab, new_tab);
300
301  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT);
302  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType());
303}
304
305} // namespace chromeos
306