Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / webui / options / language_dictionary_interactive_uitest.cc
blob04cbf0a339e7931763ab15daef6675c82cdfa131
1 // Copyright 2015 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.
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"
15 namespace {
17 // This class tests the language dictionary settings.
18 // This test is part of the interactive_ui_tests instead of browser_tests
19 // because it is necessary to emulate pushing the tab key.
20 class LanguageDictionaryWebUITest : public InProcessBrowserTest {
21 public:
22 LanguageDictionaryWebUITest() {}
24 // Navigate to the editDictionary page.
25 void SetUpOnMainThread() override {
26 const GURL url = chrome::GetSettingsUrl("editDictionary");
27 ui_test_utils::NavigateToURL(browser(), url);
30 protected:
31 const std::string kDictionaryListSelector =
32 "#language-dictionary-overlay-word-list";
34 content::RenderFrameHost* GetActiveFrame() {
35 return GetActiveWebContents()->GetFocusedFrame();
38 content::RenderViewHost* GetRenderViewHost() {
39 return GetActiveWebContents()->GetRenderViewHost();
42 content::WebContents* GetActiveWebContents() {
43 return browser()->tab_strip_model()->GetActiveWebContents();
46 // Add a few test words to the dictionary.
47 void SetTestWords(const std::string& list_selector) {
48 const std::string script = base::StringPrintf(
49 "document.querySelector('%s').setWordList(['cat', 'dog', 'bird']);",
50 list_selector.c_str());
51 EXPECT_TRUE(content::ExecuteScript(GetActiveFrame(), script));
52 // Expected list size is 4: 3 word items + 1 placeholder.
53 EXPECT_EQ(4, GetListSize(list_selector));
56 // Returns the number of items in the list.
57 int GetListSize(const std::string& list_selector) {
58 const std::string script = base::StringPrintf(
59 "domAutomationController.send("
60 "document.querySelector('%s').items.length);",
61 list_selector.c_str());
62 int length = -1;
63 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
64 GetActiveFrame(),
65 script,
66 &length));
67 return length;
70 // Returns true if element contains document.activeElement.
71 bool ContainsActiveElement(const std::string& element_selector) {
72 const std::string script = base::StringPrintf(
73 "domAutomationController.send("
74 "document.querySelector('%s').contains(document.activeElement));",
75 element_selector.c_str());
76 bool result;
77 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
78 GetActiveFrame(),
79 script,
80 &result));
81 return result;
84 // Returns true if list item[|index|] contains document.activeElement.
85 bool ListItemContainsActiveElement(const std::string& list_selector,
86 int index) {
87 EXPECT_GE(index, 0);
88 // EXPECT_TRUE will fail if index is out of bounds.
89 const std::string script = base::StringPrintf(
90 "domAutomationController.send("
91 "document.querySelector('%s').items[%d].contains("
92 "document.activeElement));",
93 list_selector.c_str(),
94 index);
95 bool result;
96 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
97 GetActiveFrame(),
98 script,
99 &result));
100 return result;
103 // Returns true if list item[|index|] has 'selected' attribute.
104 bool ListItemSelected(const std::string& list_selector, int index) {
105 EXPECT_GE(index, 0);
106 // EXPECT_TRUE will fail if index is out of bounds.
107 const std::string script = base::StringPrintf(
108 "domAutomationController.send("
109 "document.querySelector('%s').items[%d].hasAttribute('selected'));",
110 list_selector.c_str(),
111 index);
112 bool result = false;
113 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
114 GetActiveFrame(),
115 script,
116 &result));
117 return result;
120 // Returns true if list item[|index|] has 'selected' attribute and contains
121 // document.activeElement.
122 bool ListItemSelectedAndFocused(const std::string& list_selector,
123 int index) {
124 EXPECT_GE(index, 0);
125 return ListItemSelected(list_selector, index) &&
126 ListItemContainsActiveElement(list_selector, index);
129 // Press and release a key in the browser. This will wait for the element on
130 // the page to change.
131 bool PressKey(ui::KeyboardCode key_code, bool shift) {
132 return ui_test_utils::SendKeyPressAndWait(
133 browser(),
134 key_code,
135 false,
136 shift,
137 false,
138 false,
139 content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
140 content::Source<content::RenderViewHost>(GetRenderViewHost()));
143 void InitializeDomMessageQueue() {
144 dom_message_queue_.reset(new content::DOMMessageQueue);
147 // Wait for a message from the DOM automation controller.
148 void WaitForDomMessage(const std::string& message) {
149 const std::string expected = "\"" + message + "\"";
150 std::string received;
151 do {
152 ASSERT_TRUE(dom_message_queue_->WaitForMessage(&received));
153 } while (received != expected);
156 // Add a JavaScript event listener to send a DOM automation controller message
157 // whenever the |selected| property of the list item changes.
158 void ListenForItemSelectedChange(const std::string& list_selector,
159 int index) {
160 EXPECT_GE(index, 0);
161 // EXPECT_TRUE will fail if index is out of bounds.
162 const std::string script = base::StringPrintf(
163 "document.querySelector('%s').items[%d].addEventListener("
164 "'selectedChange', function() {"
165 "domAutomationController.setAutomationId(0);"
166 "domAutomationController.send('selected=' + this.selected);"
167 "});",
168 list_selector.c_str(),
169 index);
171 EXPECT_TRUE(content::ExecuteScript(
172 GetActiveFrame(),
173 script));
176 private:
177 scoped_ptr<content::DOMMessageQueue> dom_message_queue_;
179 DISALLOW_COPY_AND_ASSIGN(LanguageDictionaryWebUITest);
182 } // namespace
184 // Test InlineEditableItemList keyboard focus behavior in editDictionary
185 // overlay.
186 // editDictionary overlay doesn't exist on OSX so disable it there.
187 #if !defined(OS_MACOSX)
189 // Crashes on Win 7. http://crbug.com/500609
190 #if defined(OS_WIN)
191 #define MAYBE_TestListKeyboardFocus DISABLED_TestListKeyboardFocus
192 #else
193 #define MAYBE_TestListKeyboardFocus TestListKeyboardFocus
194 #endif
196 IN_PROC_BROWSER_TEST_F(LanguageDictionaryWebUITest,
197 MAYBE_TestListKeyboardFocus) {
198 const std::string list_selector = kDictionaryListSelector;
200 // Populate the list with some test words.
201 SetTestWords(list_selector);
202 int placeholder_index = GetListSize(list_selector) - 1;
204 // Listen for changes of the placeholder item's |selected| property so that
205 // test can wait until change has taken place after key press before
206 // continuing.
207 InitializeDomMessageQueue();
208 ListenForItemSelectedChange(list_selector, placeholder_index);
210 // Press tab to focus the placeholder.
211 PressKey(ui::VKEY_TAB, false);
213 // Wait for placeholder item to become selected.
214 WaitForDomMessage("selected=true");
216 // Verify that the placeholder is selected and has focus.
217 EXPECT_TRUE(ListItemSelectedAndFocused(list_selector, placeholder_index));
219 // Press up arrow to select item above the placeholder.
220 PressKey(ui::VKEY_UP, false);
222 // Wait for placeholder to become unselected.
223 WaitForDomMessage("selected=false");
225 // Verify that the placeholder is no longer selected.
226 EXPECT_FALSE(ListItemSelected(list_selector, placeholder_index));
228 // Verify that the item above the placeholder is selected and has focus.
229 EXPECT_TRUE(ListItemSelectedAndFocused(list_selector,
230 placeholder_index - 1));
232 // Press tab to leave the list.
233 PressKey(ui::VKEY_TAB, false);
235 // Verify that focus has left the list.
236 EXPECT_FALSE(ContainsActiveElement(list_selector));
238 // Verify that the item above the placeholder is still selected.
239 EXPECT_TRUE(ListItemSelected(list_selector, placeholder_index - 1));
241 // Press shift+tab to go back to the list.
242 PressKey(ui::VKEY_TAB, true);
244 // Verify that the item above the placeholder is selected and has focus.
245 EXPECT_TRUE(ListItemSelectedAndFocused(list_selector,
246 placeholder_index - 1));
248 #endif // !defined(OS_MACOSX)