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

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

Issue 2922773002: Add BrowserCommandController Interactive Test (Closed)
Patch Set: Do not exiting fullscreen on OS10.9 or earlier 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 #if defined(OS_MACOSX)
29 #include "base/mac/mac_util.h"
30 #endif
31
32 namespace {
33 // The html file to receive key events, prevent defaults and export all the
34 // events with "getKeyEventReport()" function. It has two magic keys: pressing
35 // "S" to enter fullscreen mode; pressing "X" to indicate the end of all the
36 // keys.
37 constexpr char kFullscreenKeyboardLockHTML[] = "/fullscreen_keyboardlock.html";
38
39 // On MacOSX command key is used for most of the shortcuts, so replace it with
40 // control to reduce the complexity of comparison of the results.
41 void NormalizeMetaKeyForMacOS(std::string* output) {
42 #if defined(OS_MACOSX)
43 base::ReplaceSubstringsAfterOffset(output, 0, "MetaLeft", "ControlLeft");
44 #else
45 // Avoid unused variable warning.
46 output = nullptr;
47 #endif
48 }
49
50 } // namespace
51
52 class BrowserCommandControllerInteractiveTest : public InProcessBrowserTest {
53 public:
54 BrowserCommandControllerInteractiveTest() = default;
55 ~BrowserCommandControllerInteractiveTest() override = default;
56
57 protected:
58 // Starts the test page and waits for it to be loaded.
59 void StartTestPage();
60
61 // Wait for the browser to have the expected tab count or timeout.
62 void WaitForTabCount(int tab_count) const;
63
64 // Sends a control or command + |key| shortcut to the focused window. Shift
65 // modifier will be added if |shift| is true.
66 void SendShortcut(ui::KeyboardCode key, bool shift = false);
67
68 // Sends a control or command + shift + |key| shortcut to the focused window.
69 void SendShiftShortcut(ui::KeyboardCode key);
70
71 // Sends a fullscreen shortcut to the focused window and wait for the
72 // operation to take effect.
73 void SendFullscreenShortcutAndWait();
74
75 // Sends a KeyS to the focused window to trigger JavaScript fullscreen and
76 // wait for the operation to take effect.
77 void SendJsFullscreenShortcutAndWait();
78
79 // Sends an ESC to the focused window.
80 void SendEscape();
81
82 // Sends an ESC to the focused window to exit JavaScript fullscreen and wait
83 // for the operation to take effect.
84 void SendEscapeAndWaitForExitingFullscreen();
85
86 // Sends a set of preventable shortcuts to the web page.
87 void SendShortcutsInFullscreen();
88
89 // Sends a magic KeyX to the focused window to stop the test case, receives
90 // the result and verifies if it is equal to |expected_result_|.
91 void FinishTestAndVerifyResult();
92
93 private:
94 void SetUpOnMainThread() override;
95
96 std::string expected_result_;
97
98 DISALLOW_COPY_AND_ASSIGN(BrowserCommandControllerInteractiveTest);
99 };
100
101 void BrowserCommandControllerInteractiveTest::StartTestPage() {
102 ASSERT_TRUE(embedded_test_server()->Start());
103 // Ensures the initial states.
104 ASSERT_EQ(1, browser()->tab_strip_model()->count());
105 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
106 ASSERT_EQ(1U, BrowserList::GetInstance()->size());
107 // Add a second tab for counting and focus purposes.
108 AddTabAtIndex(1, GURL("about:blank"), ui::PAGE_TRANSITION_LINK);
msw 2017/07/10 18:48:17 nit: check the active index after adding the tab.
Hzj_jie 2017/07/11 02:46:07 Though it should switch to the newly added tab, it
109 ASSERT_EQ(2, browser()->tab_strip_model()->count());
110 ASSERT_EQ(1U, BrowserList::GetInstance()->size());
111
112 ui_test_utils::NavigateToURLWithDisposition(
113 browser(),
114 embedded_test_server()->GetURL(kFullscreenKeyboardLockHTML),
115 WindowOpenDisposition::CURRENT_TAB,
116 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
117 }
118
119 void BrowserCommandControllerInteractiveTest::WaitForTabCount(
120 int tab_count) const {
121 while (browser()->tab_strip_model()->count() != tab_count)
122 content::RunAllPendingInMessageLoop();
123 }
124
125 void BrowserCommandControllerInteractiveTest::SendShortcut(
126 ui::KeyboardCode key,
127 bool shift /* = false */) {
128 #if defined(OS_MACOSX)
129 const bool control_modifier = false;
130 const bool command_modifier = true;
131 #else
132 const bool control_modifier = true;
133 const bool command_modifier = false;
134 #endif
135 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(),
136 key, control_modifier, shift, false, command_modifier));
137
138 expected_result_ += ui::KeycodeConverter::DomCodeToCodeString(
139 ui::UsLayoutKeyboardCodeToDomCode(key));
140 expected_result_ += " ctrl:";
141 expected_result_ += control_modifier ? "true" : "false";
142 expected_result_ += " shift:";
143 expected_result_ += shift ? "true" : "false";
144 expected_result_ += " alt:false";
145 expected_result_ += " meta:";
146 expected_result_ += command_modifier ? "true" : "false";
147 expected_result_ += '\n';
148 }
149
150 void BrowserCommandControllerInteractiveTest::SendShiftShortcut(
151 ui::KeyboardCode key) {
152 SendShortcut(key, true);
153 }
154
155 void BrowserCommandControllerInteractiveTest::SendFullscreenShortcutAndWait() {
156 content::WindowedNotificationObserver observer(
157 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
158 content::NotificationService::AllSources());
159 // Enter fullscreen.
160 #if defined(OS_MACOSX)
161 // On MACOSX, Command + Control + F is used.
162 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
msw 2017/07/10 18:48:17 Why doesn't this modify |expected_result_| anymore
Hzj_jie 2017/07/11 02:46:07 This command won't impact |expected_result_| :)
163 browser(), ui::VKEY_F, true, false, false, true));
164 #elif defined(OS_CHROMEOS)
165 // A dedicated fullscreen key is used on Chrome OS, so send a fullscreen
166 // command directly instead, to avoid constructing the key press.
167 ASSERT_TRUE(chrome::ExecuteCommand(browser(), IDC_FULLSCREEN));
168 #else
169 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
170 browser(), ui::VKEY_F11, false, false, false, false));
171 #endif
172
173 observer.Wait();
174 }
175
176 void
177 BrowserCommandControllerInteractiveTest::SendJsFullscreenShortcutAndWait() {
178 content::WindowedNotificationObserver observer(
179 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
180 content::NotificationService::AllSources());
181 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
182 browser(), ui::VKEY_S, false, false, false, false));
183 expected_result_ += "KeyS ctrl:false shift:false alt:false meta:false\n";
184 observer.Wait();
185 }
186
187 void BrowserCommandControllerInteractiveTest::SendEscape() {
188 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
189 browser(), ui::VKEY_ESCAPE, false, false, false, false));
190 expected_result_ += "Escape ctrl:false shift:false alt:false meta:false\n";
191 }
192
193 void BrowserCommandControllerInteractiveTest
194 ::SendEscapeAndWaitForExitingFullscreen() {
195 content::WindowedNotificationObserver observer(
196 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
197 content::NotificationService::AllSources());
198 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
199 browser(), ui::VKEY_ESCAPE, false, false, false, false));
200 observer.Wait();
201 }
202
203 void BrowserCommandControllerInteractiveTest::SendShortcutsInFullscreen() {
204 const auto initial_active_index = browser()->tab_strip_model()->active_index() ;
msw 2017/07/10 18:48:17 nit: 'git cl format', avoid 'auto' here and below.
Hzj_jie 2017/07/11 02:46:07 Done.
205 const auto initial_tab_count = browser()->tab_strip_model()->count();
206 const auto initial_browser_count = BrowserList::GetInstance()->size();
207 // The tab should not be closed.
208 SendShortcut(ui::VKEY_W);
209 ASSERT_EQ(initial_tab_count, browser()->tab_strip_model()->count());
210 // The window should not be closed.
211 SendShiftShortcut(ui::VKEY_W);
212 ASSERT_EQ(initial_browser_count, BrowserList::GetInstance()->size());
213 // TODO(zijiehe): ChromeOS incorrectly handles these;
214 // see http://crbug.com/737307.
215 #if !defined(OS_CHROMEOS)
216 // A new tab should not be created.
217 SendShortcut(ui::VKEY_T);
218 ASSERT_EQ(initial_tab_count, browser()->tab_strip_model()->count());
219 // A new window should not be created.
220 SendShortcut(ui::VKEY_N);
221 ASSERT_EQ(initial_browser_count, BrowserList::GetInstance()->size());
222 // A new incognito window should not be created.
223 SendShiftShortcut(ui::VKEY_N);
224 ASSERT_EQ(initial_browser_count, BrowserList::GetInstance()->size());
225 // Last closed tab should not be restored.
226 SendShiftShortcut(ui::VKEY_T);
227 ASSERT_EQ(initial_tab_count, browser()->tab_strip_model()->count());
228 #endif
229 // Browser should not switch to the next tab.
230 SendShortcut(ui::VKEY_TAB);
231 ASSERT_EQ(initial_active_index, browser()->tab_strip_model()->active_index());
232 // Browser should not switch to the previous tab.
233 SendShiftShortcut(ui::VKEY_TAB);
234 ASSERT_EQ(initial_active_index, browser()->tab_strip_model()->active_index());
235 }
236
237 void BrowserCommandControllerInteractiveTest::FinishTestAndVerifyResult() {
238 // Magic KeyX to stop the test.
239 EXPECT_TRUE(ui_test_utils::SendKeyPressSync(browser(),
240 ui::VKEY_X, false, false, false, false));
241 expected_result_ += "KeyX ctrl:false shift:false alt:false meta:false";
242 std::string result;
243 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
244 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
245 "getKeyEventReport();",
246 &result));
247 NormalizeMetaKeyForMacOS(&result);
248 NormalizeMetaKeyForMacOS(&expected_result_);
249 base::TrimWhitespaceASCII(result, base::TRIM_ALL, &result);
250 ASSERT_EQ(expected_result_, result);
251 }
252
253 void BrowserCommandControllerInteractiveTest::SetUpOnMainThread() {
254 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
255 }
256
257 IN_PROC_BROWSER_TEST_F(BrowserCommandControllerInteractiveTest,
258 ShortcutsShouldTakeEffectInWindowMode) {
259 ASSERT_EQ(1, browser()->tab_strip_model()->count());
260 SendShortcut(ui::VKEY_T);
261 WaitForTabCount(2);
262 ASSERT_EQ(2, browser()->tab_strip_model()->count());
263 SendShortcut(ui::VKEY_T);
264 WaitForTabCount(3);
265 ASSERT_EQ(3, browser()->tab_strip_model()->count());
266 SendShortcut(ui::VKEY_W);
267 WaitForTabCount(2);
268 ASSERT_EQ(2, browser()->tab_strip_model()->count());
269 SendShortcut(ui::VKEY_W);
270 WaitForTabCount(1);
271 ASSERT_EQ(1, browser()->tab_strip_model()->count());
272 SendFullscreenShortcutAndWait();
273 ASSERT_TRUE(browser()->
274 exclusive_access_manager()->
275 fullscreen_controller()->
276 IsFullscreenForBrowser());
277 }
278
279 IN_PROC_BROWSER_TEST_F(BrowserCommandControllerInteractiveTest,
280 UnpreservedShortcutsShouldBePreventable) {
281 StartTestPage();
282
283 // The browser print function should be blocked by the web page.
284 SendShortcut(ui::VKEY_P);
285 // The system print function should be blocked by the web page.
286 SendShiftShortcut(ui::VKEY_P);
287 FinishTestAndVerifyResult();
288 }
289
290 #if defined(OS_MACOSX)
291 // TODO(zijiehe): Figure out why this test crashes on Mac OSX. The suspicious
292 // command is "SendFullscreenShortcutAndWait()". See, http://crbug.com/738949.
293 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen \
294 DISABLED_KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen
295 #else
296 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen \
297 KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen
298 #endif
299 IN_PROC_BROWSER_TEST_F(
300 BrowserCommandControllerInteractiveTest,
301 MAYBE_KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen) {
302 StartTestPage();
303
304 SendFullscreenShortcutAndWait();
305 SendShortcutsInFullscreen();
306 // Current page should not exit browser fullscreen mode.
307 SendEscape();
308
309 FinishTestAndVerifyResult();
310 }
311
312 IN_PROC_BROWSER_TEST_F(
313 BrowserCommandControllerInteractiveTest,
314 KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForEsc) {
315 StartTestPage();
316
317 SendJsFullscreenShortcutAndWait();
318 SendShortcutsInFullscreen();
319 // Current page should exit HTML fullscreen mode.
320 SendEscapeAndWaitForExitingFullscreen();
321
322 FinishTestAndVerifyResult();
323 }
324
325 IN_PROC_BROWSER_TEST_F(
326 BrowserCommandControllerInteractiveTest,
327 KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11) {
328 StartTestPage();
329
330 SendJsFullscreenShortcutAndWait();
331 SendShortcutsInFullscreen();
332 #if defined(OS_MACOSX)
333 // On 10.9 or earlier, sending the exit fullscreen shortcut will crash the
334 // binary. See http://crbug.com/740250.
335 if (base::mac::IsAtLeastOS10_10()) {
336 // Current page should exit browser fullscreen mode.
337 SendFullscreenShortcutAndWait();
338 }
339 #else
340 // Current page should exit browser fullscreen mode.
341 SendFullscreenShortcutAndWait();
342 #endif
343
344 FinishTestAndVerifyResult();
345 }
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