Revert 178383
[chromium-blink-merge.git] / chrome / browser / ui / fullscreen / fullscreen_controller_state_unittest.cc
blob82b35a284c5f55c4d7268fcfc9016478c70f4662
1 // Copyright (c) 2012 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 "build/build_config.h"
6 #include "chrome/browser/ui/browser.h"
7 #include "chrome/browser/ui/browser_tabstrip.h"
8 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
9 #include "chrome/browser/ui/fullscreen/fullscreen_controller_state_test.h"
10 #include "chrome/test/base/browser_with_test_window_test.h"
11 #include "content/public/browser/web_contents.h"
12 #include "content/public/common/url_constants.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 // The FullscreenControllerStateUnitTest unit test suite exhastively tests
16 // the FullscreenController through all permutations of events. The behavior
17 // of the BrowserWindow is mocked via FullscreenControllerTestWindow.
19 // FullscreenControllerStateInteractiveTest is an interactive test suite
20 // used to verify that the FullscreenControllerTestWindow models the behavior
21 // of actual windows accurately. The interactive tests are too flaky to run
22 // on infrastructure, and so those tests are disabled. Run them with:
23 // interactive_ui_tests
24 // --gtest_filter="FullscreenControllerStateInteractiveTest.*"
25 // --gtest_also_run_disabled_tests
27 // A BrowserWindow used for testing FullscreenController. ----------------------
28 class FullscreenControllerTestWindow : public TestBrowserWindow {
29 public:
30 // Simulate the window state with an enumeration.
31 enum WindowState {
32 NORMAL,
33 FULLSCREEN,
34 // No TO_ state for METRO_SNAP, the windows implementation is synchronous.
35 METRO_SNAP,
36 TO_NORMAL,
37 TO_FULLSCREEN,
40 FullscreenControllerTestWindow();
41 virtual ~FullscreenControllerTestWindow() {}
43 // BrowserWindow Interface:
44 virtual void EnterFullscreen(const GURL& url,
45 FullscreenExitBubbleType type) OVERRIDE;
46 virtual void EnterFullscreen();
47 virtual void ExitFullscreen() OVERRIDE;
48 virtual bool IsFullscreen() const OVERRIDE;
49 #if defined(OS_WIN)
50 virtual void SetMetroSnapMode(bool enable) OVERRIDE;
51 virtual bool IsInMetroSnapMode() const OVERRIDE;
52 #endif
53 #if defined(OS_MACOSX)
54 virtual void EnterPresentationMode(
55 const GURL& url,
56 FullscreenExitBubbleType bubble_type) OVERRIDE;
57 virtual void ExitPresentationMode() OVERRIDE;
58 virtual bool InPresentationMode() OVERRIDE;
59 #endif
61 static const char* GetWindowStateString(WindowState state);
62 WindowState state() const { return state_; }
63 void set_browser(Browser* browser) { browser_ = browser; }
64 void set_reentrant(bool value) { reentrant_ = value; }
65 bool reentrant() const { return reentrant_; }
67 // Simulates the window changing state.
68 void ChangeWindowFullscreenState();
69 // Calls ChangeWindowFullscreenState() if |reentrant_| is true.
70 void ChangeWindowFullscreenStateIfReentrant();
72 private:
73 WindowState state_;
74 bool mac_presentation_mode_;
75 Browser* browser_;
77 // Causes reentrant calls to be made by calling
78 // browser_->WindowFullscreenStateChanged() from the BrowserWindow
79 // interface methods.
80 bool reentrant_;
83 FullscreenControllerTestWindow::FullscreenControllerTestWindow()
84 : state_(NORMAL),
85 mac_presentation_mode_(false),
86 browser_(NULL),
87 reentrant_(false) {
90 void FullscreenControllerTestWindow::EnterFullscreen(
91 const GURL& url, FullscreenExitBubbleType type) {
92 EnterFullscreen();
95 void FullscreenControllerTestWindow::EnterFullscreen() {
96 if (!IsFullscreen()) {
97 state_ = TO_FULLSCREEN;
98 ChangeWindowFullscreenStateIfReentrant();
102 void FullscreenControllerTestWindow::ExitFullscreen() {
103 if (IsFullscreen()) {
104 state_ = TO_NORMAL;
105 mac_presentation_mode_ = false;
106 ChangeWindowFullscreenStateIfReentrant();
110 bool FullscreenControllerTestWindow::IsFullscreen() const {
111 #if defined(OS_MACOSX)
112 return state_ == FULLSCREEN || state_ == TO_FULLSCREEN;
113 #else
114 return state_ == FULLSCREEN || state_ == TO_NORMAL;
115 #endif
118 #if defined(OS_WIN)
119 void FullscreenControllerTestWindow::SetMetroSnapMode(bool enable) {
120 if (enable != IsInMetroSnapMode()) {
121 if (enable)
122 state_ = METRO_SNAP;
123 else
124 state_ = NORMAL;
126 ChangeWindowFullscreenStateIfReentrant();
129 bool FullscreenControllerTestWindow::IsInMetroSnapMode() const {
130 return state_ == METRO_SNAP;
132 #endif
134 #if defined(OS_MACOSX)
135 void FullscreenControllerTestWindow::EnterPresentationMode(
136 const GURL& url,
137 FullscreenExitBubbleType bubble_type) {
138 mac_presentation_mode_ = true;
139 EnterFullscreen();
142 void FullscreenControllerTestWindow::ExitPresentationMode() {
143 if (InPresentationMode()) {
144 mac_presentation_mode_ = false;
145 ExitFullscreen();
149 bool FullscreenControllerTestWindow::InPresentationMode() {
150 return mac_presentation_mode_;
152 #endif
154 // static
155 const char* FullscreenControllerTestWindow::GetWindowStateString(
156 WindowState state) {
157 switch (state) {
158 case NORMAL:
159 return "NORMAL";
160 case FULLSCREEN:
161 return "FULLSCREEN";
162 case METRO_SNAP:
163 return "METRO_SNAP";
164 case TO_FULLSCREEN:
165 return "TO_FULLSCREEN";
166 case TO_NORMAL:
167 return "TO_NORMAL";
168 default:
169 NOTREACHED() << "No string for state " << state;
170 return "WindowState-Unknown";
174 void FullscreenControllerTestWindow::ChangeWindowFullscreenState() {
175 // Several states result in "no operation" intentionally. The tests
176 // assume that all possible states and event pairs can be tested, even
177 // though window managers will not generate all of these.
178 switch (state_) {
179 case NORMAL:
180 break;
181 case FULLSCREEN:
182 break;
183 case METRO_SNAP:
184 break;
185 case TO_FULLSCREEN:
186 state_ = FULLSCREEN;
187 break;
188 case TO_NORMAL:
189 state_ = NORMAL;
190 break;
191 default:
192 NOTREACHED();
194 // Emit a change event from every state to ensure the Fullscreen Controller
195 // handles it in all circumstances.
196 browser_->WindowFullscreenStateChanged();
199 void FullscreenControllerTestWindow::ChangeWindowFullscreenStateIfReentrant() {
200 if (reentrant_)
201 ChangeWindowFullscreenState();
204 // Unit test fixture testing Fullscreen Controller through its states. ---------
205 class FullscreenControllerStateUnitTest : public BrowserWithTestWindowTest,
206 public FullscreenControllerStateTest {
207 public:
208 FullscreenControllerStateUnitTest();
210 // FullscreenControllerStateTest:
211 virtual void SetUp() OVERRIDE;
212 virtual void ChangeWindowFullscreenState() OVERRIDE;
213 virtual const char* GetWindowStateString() OVERRIDE;
214 virtual void VerifyWindowState() OVERRIDE;
216 protected:
217 // FullscreenControllerStateTest:
218 virtual bool ShouldSkipStateAndEventPair(State state, Event event) OVERRIDE;
219 virtual void TestStateAndEvent(State state,
220 Event event,
221 bool reentrant) OVERRIDE;
222 virtual Browser* GetBrowser() OVERRIDE;
223 FullscreenControllerTestWindow* window_;
226 FullscreenControllerStateUnitTest::FullscreenControllerStateUnitTest ()
227 : window_(NULL) {
230 void FullscreenControllerStateUnitTest::SetUp() {
231 window_ = new FullscreenControllerTestWindow();
232 set_window(window_); // BrowserWithTestWindowTest takes ownership.
233 BrowserWithTestWindowTest::SetUp();
234 window_->set_browser(browser());
237 void FullscreenControllerStateUnitTest::ChangeWindowFullscreenState() {
238 window_->ChangeWindowFullscreenState();
241 const char* FullscreenControllerStateUnitTest::GetWindowStateString() {
242 return FullscreenControllerTestWindow::GetWindowStateString(window_->state());
245 void FullscreenControllerStateUnitTest::VerifyWindowState() {
246 switch (state_) {
247 case STATE_NORMAL:
248 EXPECT_EQ(FullscreenControllerTestWindow::NORMAL,
249 window_->state()) << GetAndClearDebugLog();
250 break;
251 case STATE_BROWSER_FULLSCREEN_NO_CHROME:
252 EXPECT_EQ(FullscreenControllerTestWindow::FULLSCREEN,
253 window_->state()) << GetAndClearDebugLog();
254 break;
255 #if defined(OS_WIN)
256 case STATE_METRO_SNAP:
257 EXPECT_EQ(FullscreenControllerTestWindow::METRO_SNAP,
258 window_->state()) << GetAndClearDebugLog();
259 break;
260 #endif
261 case STATE_TAB_FULLSCREEN:
262 EXPECT_EQ(FullscreenControllerTestWindow::FULLSCREEN,
263 window_->state()) << GetAndClearDebugLog();
264 break;
265 case STATE_TAB_BROWSER_FULLSCREEN:
266 EXPECT_EQ(FullscreenControllerTestWindow::FULLSCREEN,
267 window_->state()) << GetAndClearDebugLog();
268 break;
269 case STATE_TO_NORMAL:
270 EXPECT_EQ(FullscreenControllerTestWindow::TO_NORMAL,
271 window_->state()) << GetAndClearDebugLog();
272 break;
273 case STATE_TO_BROWSER_FULLSCREEN_NO_CHROME:
274 EXPECT_EQ(FullscreenControllerTestWindow::TO_FULLSCREEN,
275 window_->state()) << GetAndClearDebugLog();
276 break;
277 case STATE_TO_TAB_FULLSCREEN:
278 EXPECT_EQ(FullscreenControllerTestWindow::TO_FULLSCREEN,
279 window_->state()) << GetAndClearDebugLog();
280 break;
281 default:
282 NOTREACHED() << GetAndClearDebugLog();
285 FullscreenControllerStateTest::VerifyWindowState();
288 bool FullscreenControllerStateUnitTest::ShouldSkipStateAndEventPair(
289 State state, Event event) {
290 #if defined(OS_MACOSX)
291 // TODO(scheib) Toggle, Window Event, Toggle, Toggle on Mac as exposed by
292 // test *.STATE_TO_NORMAL__TOGGLE_FULLSCREEN runs interactively and exits to
293 // Normal. This doesn't appear to be the desired result, and would add
294 // too much complexity to mimic in our simple FullscreenControllerTestWindow.
295 // http://crbug.com/156968
296 if ((state == STATE_TO_NORMAL ||
297 state == STATE_TO_BROWSER_FULLSCREEN_NO_CHROME ||
298 state == STATE_TO_TAB_FULLSCREEN) &&
299 event == TOGGLE_FULLSCREEN)
300 return true;
301 #endif
303 return FullscreenControllerStateTest::ShouldSkipStateAndEventPair(state,
304 event);
307 void FullscreenControllerStateUnitTest::TestStateAndEvent(State state,
308 Event event,
309 bool reentrant) {
310 window_->set_reentrant(reentrant);
311 FullscreenControllerStateTest::TestStateAndEvent(state, event, reentrant);
314 Browser* FullscreenControllerStateUnitTest::GetBrowser() {
315 return BrowserWithTestWindowTest::browser();
318 // Tests -----------------------------------------------------------------------
320 #define TEST_EVENT_INNER(state, event, reentrant, reentrant_id) \
321 TEST_F(FullscreenControllerStateUnitTest, \
322 state##__##event##reentrant_id) { \
323 AddTab(browser(), GURL(chrome::kAboutBlankURL)); \
324 ASSERT_NO_FATAL_FAILURE(TestStateAndEvent(state, event, reentrant)) \
325 << GetAndClearDebugLog(); \
327 // Progress of tests can be examined by inserting the following line:
328 // LOG(INFO) << GetAndClearDebugLog(); }
330 #define TEST_EVENT(state, event) \
331 TEST_EVENT_INNER(state, event, false, ); \
332 TEST_EVENT_INNER(state, event, true, _Reentrant);
334 // Individual tests for each pair of state and event:
336 TEST_EVENT(STATE_NORMAL, TOGGLE_FULLSCREEN);
337 TEST_EVENT(STATE_NORMAL, TAB_FULLSCREEN_TRUE);
338 TEST_EVENT(STATE_NORMAL, TAB_FULLSCREEN_FALSE);
339 #if defined(OS_WIN)
340 TEST_EVENT(STATE_NORMAL, METRO_SNAP_TRUE);
341 TEST_EVENT(STATE_NORMAL, METRO_SNAP_FALSE);
342 #endif
343 TEST_EVENT(STATE_NORMAL, BUBBLE_EXIT_LINK);
344 TEST_EVENT(STATE_NORMAL, BUBBLE_ALLOW);
345 TEST_EVENT(STATE_NORMAL, BUBBLE_DENY);
346 TEST_EVENT(STATE_NORMAL, WINDOW_CHANGE);
348 TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, TOGGLE_FULLSCREEN);
349 TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, TAB_FULLSCREEN_TRUE);
350 TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, TAB_FULLSCREEN_FALSE);
351 #if defined(OS_WIN)
352 TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, METRO_SNAP_TRUE);
353 TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, METRO_SNAP_FALSE);
354 #endif
355 TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, BUBBLE_EXIT_LINK);
356 TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, BUBBLE_ALLOW);
357 TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, BUBBLE_DENY);
358 TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, WINDOW_CHANGE);
360 #if defined(OS_WIN)
361 TEST_EVENT(STATE_METRO_SNAP, TOGGLE_FULLSCREEN);
362 TEST_EVENT(STATE_METRO_SNAP, TAB_FULLSCREEN_TRUE);
363 TEST_EVENT(STATE_METRO_SNAP, TAB_FULLSCREEN_FALSE);
364 TEST_EVENT(STATE_METRO_SNAP, METRO_SNAP_TRUE);
365 TEST_EVENT(STATE_METRO_SNAP, METRO_SNAP_FALSE);
366 TEST_EVENT(STATE_METRO_SNAP, BUBBLE_EXIT_LINK);
367 TEST_EVENT(STATE_METRO_SNAP, BUBBLE_ALLOW);
368 TEST_EVENT(STATE_METRO_SNAP, BUBBLE_DENY);
369 TEST_EVENT(STATE_METRO_SNAP, WINDOW_CHANGE);
370 #endif
372 TEST_EVENT(STATE_TAB_FULLSCREEN, TOGGLE_FULLSCREEN);
373 TEST_EVENT(STATE_TAB_FULLSCREEN, TAB_FULLSCREEN_TRUE);
374 TEST_EVENT(STATE_TAB_FULLSCREEN, TAB_FULLSCREEN_FALSE);
375 #if defined(OS_WIN)
376 TEST_EVENT(STATE_TAB_FULLSCREEN, METRO_SNAP_TRUE);
377 TEST_EVENT(STATE_TAB_FULLSCREEN, METRO_SNAP_FALSE);
378 #endif
379 TEST_EVENT(STATE_TAB_FULLSCREEN, BUBBLE_EXIT_LINK);
380 TEST_EVENT(STATE_TAB_FULLSCREEN, BUBBLE_ALLOW);
381 TEST_EVENT(STATE_TAB_FULLSCREEN, BUBBLE_DENY);
382 TEST_EVENT(STATE_TAB_FULLSCREEN, WINDOW_CHANGE);
384 TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, TOGGLE_FULLSCREEN);
385 TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, TAB_FULLSCREEN_TRUE);
386 TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, TAB_FULLSCREEN_FALSE);
387 #if defined(OS_WIN)
388 TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, METRO_SNAP_TRUE);
389 TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, METRO_SNAP_FALSE);
390 #endif
391 TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, BUBBLE_EXIT_LINK);
392 TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, BUBBLE_ALLOW);
393 TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, BUBBLE_DENY);
394 TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, WINDOW_CHANGE);
396 TEST_EVENT(STATE_TO_NORMAL, TOGGLE_FULLSCREEN);
397 TEST_EVENT(STATE_TO_NORMAL, TAB_FULLSCREEN_TRUE);
398 TEST_EVENT(STATE_TO_NORMAL, TAB_FULLSCREEN_FALSE);
399 #if defined(OS_WIN)
400 TEST_EVENT(STATE_TO_NORMAL, METRO_SNAP_TRUE);
401 TEST_EVENT(STATE_TO_NORMAL, METRO_SNAP_FALSE);
402 #endif
403 TEST_EVENT(STATE_TO_NORMAL, BUBBLE_EXIT_LINK);
404 TEST_EVENT(STATE_TO_NORMAL, BUBBLE_ALLOW);
405 TEST_EVENT(STATE_TO_NORMAL, BUBBLE_DENY);
406 TEST_EVENT(STATE_TO_NORMAL, WINDOW_CHANGE);
408 TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, TOGGLE_FULLSCREEN);
409 TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, TAB_FULLSCREEN_TRUE);
410 TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, TAB_FULLSCREEN_FALSE);
411 #if defined(OS_WIN)
412 TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, METRO_SNAP_TRUE);
413 TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, METRO_SNAP_FALSE);
414 #endif
415 TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, BUBBLE_EXIT_LINK);
416 TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, BUBBLE_ALLOW);
417 TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, BUBBLE_DENY);
418 TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, WINDOW_CHANGE);
420 TEST_EVENT(STATE_TO_TAB_FULLSCREEN, TOGGLE_FULLSCREEN);
421 TEST_EVENT(STATE_TO_TAB_FULLSCREEN, TAB_FULLSCREEN_TRUE);
422 TEST_EVENT(STATE_TO_TAB_FULLSCREEN, TAB_FULLSCREEN_FALSE);
423 #if defined(OS_WIN)
424 TEST_EVENT(STATE_TO_TAB_FULLSCREEN, METRO_SNAP_TRUE);
425 TEST_EVENT(STATE_TO_TAB_FULLSCREEN, METRO_SNAP_FALSE);
426 #endif
427 TEST_EVENT(STATE_TO_TAB_FULLSCREEN, BUBBLE_EXIT_LINK);
428 TEST_EVENT(STATE_TO_TAB_FULLSCREEN, BUBBLE_ALLOW);
429 TEST_EVENT(STATE_TO_TAB_FULLSCREEN, BUBBLE_DENY);
430 TEST_EVENT(STATE_TO_TAB_FULLSCREEN, WINDOW_CHANGE);
432 // Specific one-off tests for known issues:
434 // TODO(scheib) Toggling Tab fullscreen while pending Tab or
435 // Browser fullscreen is broken currently http://crbug.com/154196
436 TEST_F(FullscreenControllerStateUnitTest,
437 DISABLED_ToggleTabWhenPendingBrowser) {
438 #if !defined(OS_WIN) // Only possible without reentrancy
439 AddTab(browser(), GURL(chrome::kAboutBlankURL));
440 ASSERT_NO_FATAL_FAILURE(
441 TransitionToState(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME))
442 << GetAndClearDebugLog();
444 ASSERT_TRUE(InvokeEvent(TAB_FULLSCREEN_TRUE)) << GetAndClearDebugLog();
445 ASSERT_TRUE(InvokeEvent(TAB_FULLSCREEN_FALSE)) << GetAndClearDebugLog();
446 ASSERT_TRUE(InvokeEvent(WINDOW_CHANGE)) << GetAndClearDebugLog();
447 #endif
450 // TODO(scheib) Toggling Tab fullscreen while pending Tab or
451 // Browser fullscreen is broken currently http://crbug.com/154196
452 TEST_F(FullscreenControllerStateUnitTest, DISABLED_ToggleTabWhenPendingTab) {
453 #if !defined(OS_WIN) // Only possible without reentrancy
454 AddTab(browser(), GURL(chrome::kAboutBlankURL));
455 ASSERT_NO_FATAL_FAILURE(
456 TransitionToState(STATE_TO_TAB_FULLSCREEN))
457 << GetAndClearDebugLog();
459 ASSERT_TRUE(InvokeEvent(TAB_FULLSCREEN_TRUE)) << GetAndClearDebugLog();
460 ASSERT_TRUE(InvokeEvent(TAB_FULLSCREEN_FALSE)) << GetAndClearDebugLog();
461 ASSERT_TRUE(InvokeEvent(WINDOW_CHANGE)) << GetAndClearDebugLog();
462 #endif
465 // Soak tests:
467 // Tests all states with all permutations of multiple events to detect lingering
468 // state issues that would bleed over to other states.
469 // I.E. for each state test all combinations of events E1, E2, E3.
471 // This produces coverage for event sequences that may happen normally but
472 // would not be exposed by traversing to each state via TransitionToState().
473 // TransitionToState() always takes the same path even when multiple paths
474 // exist.
475 TEST_F(FullscreenControllerStateUnitTest, TransitionsForEachState) {
476 // A tab is needed for tab fullscreen.
477 AddTab(browser(), GURL(chrome::kAboutBlankURL));
478 TestTransitionsForEachState();
479 // Progress of test can be examined via LOG(INFO) << GetAndClearDebugLog();