Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1185)

Side by Side Diff: chrome/browser/ui/webui/options/autofill_options_interactive_uitest.cc

Issue 819193003: Fix list focus after tab key in chrome://settings/autofillEditAddress page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address reviewer comments on patch set 5. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 "base/strings/stringprintf.h"
6 #include "chrome/browser/chrome_notification_types.h"
7 #include "chrome/browser/ui/browser_window.h"
8 #include "chrome/browser/ui/chrome_pages.h"
9 #include "chrome/browser/ui/tabs/tab_strip_model.h"
10 #include "chrome/common/url_constants.h"
11 #include "chrome/test/base/in_process_browser_test.h"
12 #include "chrome/test/base/interactive_test_utils.h"
13 #include "content/public/test/browser_test_utils.h"
14
15 namespace autofill_options_ui_test {
16
17 namespace {
18
19 // This class tests the autofill options settings.
Dan Beam 2015/01/23 22:46:14 nit: capitalize Autofill when it's not used as a v
bondd 2015/01/29 19:01:02 Done.
20 // This test is part of the interactive_ui_tests instead of browser_tests
21 // because it is necessary to emulate pushing the tab key.
Dan Beam 2015/01/23 22:46:14 i think it's actually because focus is hard to sha
bondd 2015/01/29 19:01:02 Acknowledged.
22 class AutofillOptionsWebUITest : public InProcessBrowserTest {
23 public:
24 AutofillOptionsWebUITest() {}
25
26 // Navigate to the autofillEditAddress page.
27 void SetUpOnMainThread() override {
28 const GURL url = chrome::GetSettingsUrl("autofillEditAddress");
29 ui_test_utils::NavigateToURL(browser(), url);
30 }
31
32 protected:
33 const std::string kEditAddressOverlaySelector =
34 "#autofill-edit-address-overlay";
35
36 content::RenderFrameHost* GetActiveFrame() {
37 return GetActiveWebContents()->GetFocusedFrame();
38 }
39
40 content::RenderViewHost* GetRenderViewHost() {
41 return GetActiveWebContents()->GetRenderViewHost();
42 }
43
44 content::WebContents* GetActiveWebContents() {
45 return browser()->tab_strip_model()->GetActiveWebContents();
46 }
47
48 // Returns true if element contains document.activeElement.
49 bool ContainsActiveElement(const std::string& element_selector) {
50 std::string script = base::StringPrintf(
51 "domAutomationController.send("
52 "document.querySelector('%s').contains(document.activeElement));",
53 element_selector.c_str());
54 bool result;
55 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
56 GetActiveFrame(),
57 script,
58 &result));
59 return result;
60 }
61
62 // Returns the number of items in the list.
63 int GetListSize(const std::string& list_selector) {
64 std::string script = base::StringPrintf(
65 "domAutomationController.send("
66 "document.querySelector('%s').items.length);",
67 list_selector.c_str());
68 int length = -1;
69 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
70 GetActiveFrame(),
71 script,
72 &length));
73 return length;
74 }
75
76 // Focus the first input field of the first list item.
77 void FocusFirstListItemInput(const std::string& list_selector) {
78 std::string script = base::StringPrintf(
79 "document.querySelector('%s input').focus();",
80 list_selector.c_str());
81 EXPECT_TRUE(content::ExecuteScript(GetActiveFrame(), script));
82 }
83
84 // Returns the text of the first item in the list.
85 std::string GetFirstListItemText(const std::string& list_selector) {
86 // EXPECT_TRUE will fail if there is no first item or first item does not
87 // have 'input'.
88 std::string script = base::StringPrintf(
89 "domAutomationController.send("
90 "document.querySelector('%s input').value);",
91 list_selector.c_str());
92 std::string result;
93 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
94 GetActiveFrame(),
95 script,
96 &result));
97 return result;
98 }
99
100 // Returns true if the first item in the list has 'selected' attribute.
101 bool GetFirstListItemSelected(const std::string& list_selector) {
102 // EXPECT_TRUE will fail if there is no first item.
103 std::string script = base::StringPrintf(
104 "domAutomationController.send("
105 "document.querySelector('%s').items[0].hasAttribute('selected'));",
106 list_selector.c_str());
107 bool result = false;
108 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
109 GetActiveFrame(),
110 script,
111 &result));
112 return result;
113 }
114
115 // Returns true if a row delete button ('X' button) is focused.
116 bool GetDeleteButtonFocused() {
117 std::string script =
118 "domAutomationController.send("
119 "document.activeElement.classList.contains('row-delete-button'));";
120 bool result = false;
121 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
122 GetActiveFrame(),
123 script,
124 &result));
125 return result;
126 }
127
128 // Insert text into currently focused element.
129 void InsertText(const std::string& text) {
Dan Beam 2015/01/23 22:46:14 nit: ASSERT_EQ(std::string::npos, text.find("'"));
bondd 2015/01/29 19:01:02 Done.
130 std::string script = base::StringPrintf(
131 "document.execCommand('insertText', false, '%s');",
132 text.c_str());
133 EXPECT_TRUE(content::ExecuteScript(GetActiveFrame(), script));
134 }
135
136 // Press and release tab key in the browser. This will wait for the element on
137 // the page to change.
138 bool PressTab(bool shift) {
139 return ui_test_utils::SendKeyPressAndWait(
140 browser(),
141 ui::VKEY_TAB,
142 false,
143 shift,
144 false,
145 false,
146 content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
147 content::Source<content::RenderViewHost>(GetRenderViewHost()));
148 }
149
150 // Verifies that everything is the way it should be after list item is
151 // added or edited.
152 void VerifyEditAddressListPostConditions(const std::string& list_selector,
153 std::string input_text) {
Dan Beam 2015/01/23 22:46:14 make input_text const-ref
bondd 2015/01/29 19:01:02 Done.
154 // Verify that neither the list nor any of its children still have focus.
155 EXPECT_FALSE(ContainsActiveElement(list_selector));
156
157 // Verify that focus moved to a different element of the overlay.
158 EXPECT_TRUE(ContainsActiveElement(kEditAddressOverlaySelector));
159
160 // Verify that list has exactly two items. They will be the item that was
161 // just added/modified + the placeholder.
162 EXPECT_EQ(2, GetListSize(list_selector));
163
164 // Verify that the first list item has the string that was inserted.
165 EXPECT_EQ(input_text, GetFirstListItemText(list_selector));
166
167 // Verify that the first list item is the selected item in the list.
168 EXPECT_TRUE(GetFirstListItemSelected(list_selector));
169 }
170
171 // Make sure that when text is entered in the placeholder of an empty list and
172 // the tab key is pressed:
173 // + Focus leaves the list and goes to a different element on the page.
174 // + The text stays added and a new placeholder is created.
175 // + The list item with the newly added text is the selected list item (not
176 // the placeholder).
177 //
178 // Added to prevent http://crbug.com/440760 from regressing again.
179 void TestEditAddressListTabKeyAddItem(const std::string& list_selector,
180 const std::string& input_text) {
181 // Focus the input field and insert test string.
182 FocusFirstListItemInput(list_selector);
183 InsertText(input_text);
184
185 // Press tab key to move to next element after the list.
186 PressTab(false);
187
188 // Make sure everything ended up the way it should be.
189 VerifyEditAddressListPostConditions(list_selector, input_text);
190 }
191
192 // Depends on state set up by TestEditAddressListTabKeyAddItem. Should be
193 // called immediately after that method.
194 //
195 // Make sure that when a list item's text is edited and the tab key is
196 // pressed twice:
197 // + After the first tab press the item's delete button is focused.
198 // + After the second tab press focus leaves the list and goes to a
199 // different element on the page.
200 // + The edited text persists.
201 // + The edited list item is the selected list item.
202 //
203 // Added to prevent http://crbug.com/443491 from regressing again.
204 void TestEditAddressListTabKeyEditItem(const std::string& list_selector,
205 const std::string& input_text) {
206 // Press shift+tab to move back to the first item in the list.
207 PressTab(true);
208 // Verify that the first item in the list is focused.
209 EXPECT_TRUE(ContainsActiveElement(list_selector + " input"));
210
211 // Insert modified text in the first list item.
212 std::string second_input = "second" + input_text;
213 InsertText(second_input);
214
215 // Press tab key to focus the list item's delete button.
216 PressTab(false);
217 EXPECT_TRUE(GetDeleteButtonFocused());
218
219 // Press tab key again to move to next element after the list.
220 PressTab(false);
221
222 // Make sure everything ended up the way it should be.
223 VerifyEditAddressListPostConditions(list_selector, second_input);
224 }
225
226 void TestEditAddressListTabKey(const std::string& field_name,
227 const std::string& input_text) {
228 std::string list_selector = kEditAddressOverlaySelector + " [field=" +
229 field_name + "]";
230
231 TestEditAddressListTabKeyAddItem(list_selector, input_text);
232 TestEditAddressListTabKeyEditItem(list_selector, input_text);
233 }
234
235 private:
236 DISALLOW_COPY_AND_ASSIGN(AutofillOptionsWebUITest);
237 };
238
239 } // namespace
240
241 // Test the 'fullName' InlineEditableItemList in autofillEditAddress overlay.
242 IN_PROC_BROWSER_TEST_F(AutofillOptionsWebUITest,
243 TestEditAddressNameListTabKey) {
244 TestEditAddressListTabKey("fullName", "Test Name");
245 }
246
247 // TODO(bondd): After tab is pressed, phone list waits for a validation
248 // callback before repopulating the list. It's not clear to me how to wait for
249 // that here on the C++ testing side. Disabling phone list test for now.
Dan Beam 2015/01/23 22:46:14 when the validation result comes back does the foc
bondd 2015/01/29 19:01:02 Done.
250 // Test the 'phone' InlineEditableItemList in autofillEditAddress overlay.
251 IN_PROC_BROWSER_TEST_F(AutofillOptionsWebUITest,
252 DISABLED_TestEditAddressPhoneListTabKey) {
253 TestEditAddressListTabKey("phone", "123-456-7890");
254 }
255
256 // Test the 'email' InlineEditableItemList in autofillEditAddress overlay.
257 IN_PROC_BROWSER_TEST_F(AutofillOptionsWebUITest,
258 TestEditAddressEmailListTabKey) {
259 TestEditAddressListTabKey("email", "test@example.com");
260 }
261
262 } // namespace autofill_options_ui_test
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698