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

Side by Side Diff: chrome/browser/ui/browser_command_controller_interactive_browsertest.cc

Issue 2922773002: Add BrowserCommandController Interactive Test (Closed)
Patch Set: Build break on platforms other than MacOSX Created 3 years, 5 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
« no previous file with comments | « no previous file | chrome/test/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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 <memory>
6 #include <string>
7
8 #include "base/macros.h"
9 #include "base/memory/ptr_util.h"
10 #include "base/strings/string_util.h"
11 #include "build/build_config.h"
12 #include "chrome/app/chrome_command_ids.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_commands.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
18 #include "chrome/test/base/in_process_browser_test.h"
19 #include "chrome/test/base/interactive_test_utils.h"
20 #include "content/public/browser/notification_service.h"
21 #include "content/public/test/browser_test_utils.h"
22 #include "content/public/test/test_utils.h"
23 #include "ui/events/keycodes/keyboard_codes.h"
24 #include "ui/events/keycodes/keyboard_code_conversion.h"
25 #include "ui/events/keycodes/dom/keycode_converter.h"
26 #include "url/gurl.h"
27
28 namespace {
29 // The html file to receive key events, prevent defaults and export all the
30 // events with "getKeyEventReport()" function. It has two magic keys: pressing
31 // "S" to enter fullscreen mode; pressing "X" to indicate the end of all the
32 // keys.
33 constexpr char kFullscreenKeyboardLockHTML[] = "/fullscreen_keyboardlock.html";
34
35 // On MacOSX command key is used for most of the shortcuts, so replace it with
36 // control to reduce the complexity of comparison of the results.
37 #if defined(OS_MACOSX)
msw 2017/07/05 19:11:45 nit: move the #if block inside the function, all p
Hzj_jie 2017/07/07 23:18:10 Done.
38 void NormalizeMetaKeyForMacOS(std::string* output) {
39 base::ReplaceSubstringsAfterOffset(output, 0, "MetaLeft", "ControlLeft");
40 }
41 #else
42 // Avoid unused variable warning.
43 void NormalizeMetaKeyForMacOS(std::string*) {}
44 #endif
45
46 } // namespace
47
48 class BrowserCommandControllerInteractiveTest : public InProcessBrowserTest {
49 public:
50 BrowserCommandControllerInteractiveTest() = default;
51 ~BrowserCommandControllerInteractiveTest() override = default;
52
53 protected:
54 // Starts the test page and waits for it to be loaded.
55 void StartTestPage();
56
57 // Wait for the browser to have the expected tab count or timeout.
58 void WaitForTabCount(int tab_count) const;
59
60 // Sends a control or command + |key| shortcut to the focused window. Shift
61 // modifier will be added if |shift| is true.
62 void SendShortcut(ui::KeyboardCode key, bool shift = false);
63
64 // Sends a control or command + shift + |key| shortcut to the focused window.
65 void SendShiftShortcut(ui::KeyboardCode key);
66
67 // Sends a fullscreen shortcut to the focused window and wait for the
68 // operation to take effect.
69 void SendFullscreenShortcutAndWait();
70
71 // Sends a KeyS to the focused window to trigger JavaScript fullscreen and
72 // wait for the operation to take effect.
73 void SendJsFullscreenShortcutAndWait();
74
75 // Sends an ESC to the focused window.
76 void SendEscape();
77
78 // Sends an ESC to the focused window to exit JavaScript fullscreen and wait
79 // for the operation to take effect.
80 void SendEscapeAndWaitForExitingFullscreen();
81
82 // Sends a magic KeyX to the focused window to stop the test case, receives
83 // the result and verifies if it equals to |expected_result_|.
msw 2017/07/05 19:11:45 nit: "if it equals |expected_result_|." of "if it
Hzj_jie 2017/07/07 23:18:10 Done.
84 void FinishTestAndVerifyResult();
85
86 private:
87 void SetUpOnMainThread() override;
88
89 std::string expected_result_;
90
91 DISALLOW_COPY_AND_ASSIGN(BrowserCommandControllerInteractiveTest);
92 };
93
94 void BrowserCommandControllerInteractiveTest::StartTestPage() {
95 ASSERT_TRUE(embedded_test_server()->Start());
96 ui_test_utils::NavigateToURLWithDisposition(
97 browser(),
98 embedded_test_server()->GetURL(kFullscreenKeyboardLockHTML),
99 WindowOpenDisposition::CURRENT_TAB,
100 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
101 }
102
103 void BrowserCommandControllerInteractiveTest::WaitForTabCount(
104 int tab_count) const {
105 while (browser()->tab_strip_model()->count() != tab_count)
106 content::RunAllPendingInMessageLoop();
107 }
108
109 void BrowserCommandControllerInteractiveTest::SendShortcut(
110 ui::KeyboardCode key,
111 bool shift /* = false */) {
112 #if defined(OS_MACOSX)
113 const bool control_modifier = false;
114 const bool command_modifier = true;
115 #else
116 const bool control_modifier = true;
117 const bool command_modifier = false;
118 #endif
119 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(),
120 key, control_modifier, shift, false, command_modifier));
121
122 // 1. ui_controls_mac.mm puts shift key before meta (command) key.
msw 2017/07/05 19:11:45 Trent's point about test fragility is very much wo
Hzj_jie 2017/07/07 23:18:10 A good suggestion to avoid addressing the order of
msw 2017/07/10 18:48:17 Feel free to add a separate keyup behavior test in
Hzj_jie 2017/07/11 02:46:07 Acknowledged.
123 // https://cs.chromium.org/chromium/src/ui/base/test/ui_controls_mac.mm?type=c s&q=SynthesizeKeyEventsSequence&sq=package:chromium&l=67
124 // 2. To match safari, key up event won't fire if meta (command) key is down.
125 // See http://crbug.com/126282.
126 std::string code_string = ui::KeycodeConverter::DomCodeToCodeString(
127 ui::UsLayoutKeyboardCodeToDomCode(key));
128 #if defined(OS_MACOSX)
129 if (shift) {
130 expected_result_ += "keydown ShiftLeft\n";
131 }
132 expected_result_ += "keydown ControlLeft\n";
133 expected_result_ += "keydown ";
134 expected_result_ += code_string;
135 expected_result_ += "\n";
136 expected_result_ += "keyup ControlLeft\n";
137 if (shift) {
138 expected_result_ += "keyup ShiftLeft\n";
139 }
140 #else
141 expected_result_ += "keydown ControlLeft\n";
142 if (shift) {
143 expected_result_ += "keydown ShiftLeft\n";
144 }
145 expected_result_ += "keydown ";
146 expected_result_ += code_string;
147 expected_result_ += "\n";
148 expected_result_ += "keyup ";
149 expected_result_ += code_string;
150 expected_result_ += "\n";
151 if (shift) {
152 expected_result_ += "keyup ShiftLeft\n";
153 }
154 expected_result_ += "keyup ControlLeft\n";
155 #endif
156 }
157
158 void BrowserCommandControllerInteractiveTest::SendShiftShortcut(
159 ui::KeyboardCode key) {
160 SendShortcut(key, true);
161 }
162
163 void BrowserCommandControllerInteractiveTest::SendFullscreenShortcutAndWait() {
164 content::WindowedNotificationObserver observer(
165 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
166 content::NotificationService::AllSources());
167 // Enter fullscreen.
168 #if defined(OS_MACOSX)
169 // On MACOSX, Command + Control + F is used.
170 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
171 browser(), ui::VKEY_F, true, false, false, true));
172 // Both Command and Control key presses are still catchable by web page.
173 expected_result_ += "keydown ControlLeft\n"
174 "keydown MetaLeft\n"
175 "keyup MetaLeft\n"
176 "keyup ControlLeft\n";
177 #elif defined(OS_CHROMEOS)
178 // A dedicated fullscreen key is used on Chrome OS, so send a fullscreen
179 // command directly instead, to avoid constructing the key press.
180 ASSERT_TRUE(chrome::ExecuteCommand(browser(), IDC_FULLSCREEN));
181 #else
182 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
183 browser(), ui::VKEY_F11, false, false, false, false));
184 #endif
185
186 observer.Wait();
187 }
188
189 void
190 BrowserCommandControllerInteractiveTest::SendJsFullscreenShortcutAndWait() {
191 content::WindowedNotificationObserver observer(
192 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
193 content::NotificationService::AllSources());
194 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
195 browser(), ui::VKEY_S, false, false, false, false));
196 expected_result_ += "keydown KeyS\n";
197 expected_result_ += "keyup KeyS\n";
198 observer.Wait();
199 }
200
201 void BrowserCommandControllerInteractiveTest::SendEscape() {
202 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
203 browser(), ui::VKEY_ESCAPE, false, false, false, false));
204 expected_result_ += "keydown Escape\n";
205 expected_result_ += "keyup Escape\n";
206 }
207
208 void BrowserCommandControllerInteractiveTest
209 ::SendEscapeAndWaitForExitingFullscreen() {
210 content::WindowedNotificationObserver observer(
211 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
212 content::NotificationService::AllSources());
213 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
214 browser(), ui::VKEY_ESCAPE, false, false, false, false));
215 observer.Wait();
216 }
217
218 void BrowserCommandControllerInteractiveTest::FinishTestAndVerifyResult() {
219 // Magic KeyX to stop the test.
220 EXPECT_TRUE(ui_test_utils::SendKeyPressSync(browser(),
221 ui::VKEY_X, false, false, false, false));
222 expected_result_ += "keydown KeyX\n";
223 expected_result_ += "keyup KeyX";
224 std::string result;
225 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
226 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
227 "getKeyEventReport();",
228 &result));
229 NormalizeMetaKeyForMacOS(&result);
230 NormalizeMetaKeyForMacOS(&expected_result_);
231 base::TrimWhitespaceASCII(result, base::TRIM_ALL, &result);
232 ASSERT_EQ(result, expected_result_);
msw 2017/07/05 19:11:45 nit: ASSERT_EQ and EXPECTED_EQ macros should have
Hzj_jie 2017/07/07 23:18:10 Done.
233 }
234
235 void BrowserCommandControllerInteractiveTest::SetUpOnMainThread() {
236 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
237 }
238
239 IN_PROC_BROWSER_TEST_F(BrowserCommandControllerInteractiveTest,
240 ShortcutsShouldTakeEffectInWindowMode) {
241 ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
242 SendShortcut(ui::VKEY_T);
243 WaitForTabCount(2);
244 ASSERT_EQ(browser()->tab_strip_model()->count(), 2);
245 SendShortcut(ui::VKEY_T);
246 WaitForTabCount(3);
247 ASSERT_EQ(browser()->tab_strip_model()->count(), 3);
248 SendShortcut(ui::VKEY_W);
249 WaitForTabCount(2);
250 ASSERT_EQ(browser()->tab_strip_model()->count(), 2);
251 SendShortcut(ui::VKEY_W);
252 WaitForTabCount(1);
253 ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
254 SendFullscreenShortcutAndWait();
255 ASSERT_TRUE(browser()->
256 exclusive_access_manager()->
257 fullscreen_controller()->
258 IsFullscreenForBrowser());
259 }
260
261 IN_PROC_BROWSER_TEST_F(BrowserCommandControllerInteractiveTest,
262 UnpreservedShortcutsShouldBePreventable) {
263 ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
264 StartTestPage();
265
266 // The browser print function should be blocked by the web page.
267 SendShortcut(ui::VKEY_P);
268 // The system print function should be blocked by the web page.
269 SendShiftShortcut(ui::VKEY_P);
270 FinishTestAndVerifyResult();
271 }
272
273 #if defined(OS_MACOSX)
274 // TODO(zijiehe): Figure out why this test crashes on Mac OSX. The suspicious
275 // command is "SendFullscreenShortcutAndWait()". See, http://crbug.com/738949.
276 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen \
277 DISABLED_KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen
278 #else
279 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen \
280 KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen
281 #endif
282 IN_PROC_BROWSER_TEST_F(
283 BrowserCommandControllerInteractiveTest,
284 MAYBE_KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen) {
285 ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
286 StartTestPage();
287
288 SendFullscreenShortcutAndWait();
289 // The tab should not be closed.
msw 2017/07/05 19:11:45 Can you make a helper function that sends these co
Hzj_jie 2017/07/07 23:18:10 AddTabAtIndex() always creates a focused tab and c
290 SendShortcut(ui::VKEY_W);
291 // The window should not be closed.
292 SendShiftShortcut(ui::VKEY_W);
293 // TODO(zijiehe): ChromeOS incorrectly handles these;
294 // see http://crbug.com/737307.
295 #if !defined(OS_CHROMEOS)
296 // A new tab should not be created.
297 SendShortcut(ui::VKEY_T);
298 // A new window should not be created.
299 SendShortcut(ui::VKEY_N);
300 // A new incognito window should not be created.
301 SendShiftShortcut(ui::VKEY_N);
302 // Last closed tab should not be restored.
303 SendShiftShortcut(ui::VKEY_T);
304 #endif
305 // Browser should not switch to the next tab.
306 SendShortcut(ui::VKEY_TAB);
307 // Browser should not switch to the previous tab.
308 SendShiftShortcut(ui::VKEY_TAB);
309 // Current page should not exit browser fullscreen mode.
310 SendEscape();
311
312 FinishTestAndVerifyResult();
313 }
314
315 IN_PROC_BROWSER_TEST_F(
316 BrowserCommandControllerInteractiveTest,
317 KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForEsc) {
318 ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
319 StartTestPage();
320
321 SendJsFullscreenShortcutAndWait();
322 // The tab should not be closed.
323 SendShortcut(ui::VKEY_W);
324 // The window should not be closed.
325 SendShiftShortcut(ui::VKEY_W);
326 // TODO(zijiehe): ChromeOS incorrectly handles these;
327 // see http://crbug.com/737307.
328 #if !defined(OS_CHROMEOS)
329 // A new tab should not be created.
330 SendShortcut(ui::VKEY_T);
331 // A new window should not be created.
332 SendShortcut(ui::VKEY_N);
333 // A new incognito window should not be created.
334 SendShiftShortcut(ui::VKEY_N);
335 // Last closed tab should not be restored.
336 SendShiftShortcut(ui::VKEY_T);
337 #endif
338 // Browser should not switch to the next tab.
339 SendShortcut(ui::VKEY_TAB);
340 // Browser should not switch to the previous tab.
341 SendShiftShortcut(ui::VKEY_TAB);
342 // Current page should exit HTML fullscreen mode.
343 SendEscapeAndWaitForExitingFullscreen();
344
345 FinishTestAndVerifyResult();
346 }
347
348 IN_PROC_BROWSER_TEST_F(
349 BrowserCommandControllerInteractiveTest,
350 KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11) {
351 ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
352 StartTestPage();
353
354 SendJsFullscreenShortcutAndWait();
355 // The tab should not be closed.
356 SendShortcut(ui::VKEY_W);
357 // The window should not be closed.
358 SendShiftShortcut(ui::VKEY_W);
359 // TODO(zijiehe): ChromeOS incorrectly handles these;
360 // see http://crbug.com/737307.
361 #if !defined(OS_CHROMEOS)
362 // A new tab should not be created.
363 SendShortcut(ui::VKEY_T);
364 // A new window should not be created.
365 SendShortcut(ui::VKEY_N);
366 // A new incognito window should not be created.
367 SendShiftShortcut(ui::VKEY_N);
368 // Last closed tab should not be restored.
369 SendShiftShortcut(ui::VKEY_T);
370 #endif
371 // Browser should not switch to the next tab.
372 SendShortcut(ui::VKEY_TAB);
373 // Browser should not switch to the previous tab.
374 SendShiftShortcut(ui::VKEY_TAB);
375 // Current page should exit browser fullscreen mode.
376 SendFullscreenShortcutAndWait();
377
378 FinishTestAndVerifyResult();
379 }
OLDNEW
« no previous file with comments | « no previous file | chrome/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698