1 // Copyright 2013 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 "apps/ui/native_app_window.h"
6 #include "chrome/browser/apps/app_browsertest_util.h"
7 #include "chrome/browser/extensions/extension_test_message_listener.h"
8 #include "chrome/test/base/interactive_test_utils.h"
10 #if defined(OS_MACOSX) && !defined(OS_IOS)
11 #include "base/mac/mac_util.h"
14 using apps::NativeAppWindow;
16 // Helper class that has to be created in the stack to check if the fullscreen
17 // setting of a NativeWindow has changed since the creation of the object.
18 class FullscreenChangeWaiter {
20 explicit FullscreenChangeWaiter(NativeAppWindow* window)
22 initial_fullscreen_state_(window_->IsFullscreen()) {}
25 while (initial_fullscreen_state_ == window_->IsFullscreen())
26 content::RunAllPendingInMessageLoop();
30 NativeAppWindow* window_;
31 bool initial_fullscreen_state_;
33 DISALLOW_COPY_AND_ASSIGN(FullscreenChangeWaiter);
36 class AppWindowInteractiveTest : public extensions::PlatformAppBrowserTest {
38 bool RunAppWindowInteractiveTest(const char* testName) {
39 ExtensionTestMessageListener launched_listener("Launched", true);
40 LoadAndLaunchPlatformApp("window_api_interactive");
41 if (!launched_listener.WaitUntilSatisfied()) {
42 message_ = "Did not get the 'Launched' message.";
46 ResultCatcher catcher;
47 launched_listener.Reply(testName);
49 if (!catcher.GetNextResult()) {
50 message_ = catcher.message();
57 bool SimulateKeyPress(ui::KeyboardCode key) {
58 return ui_test_utils::SendKeyPressToWindowSync(
59 GetFirstShellWindow()->GetNativeWindow(),
67 // This method will wait until the application is able to ack a key event.
68 void WaitUntilKeyFocus() {
69 ExtensionTestMessageListener key_listener("KeyReceived", false);
71 while (!key_listener.was_satisfied()) {
72 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_Z));
73 content::RunAllPendingInMessageLoop();
78 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenWindow) {
79 // This test is flaky on MacOS 10.6.
80 #if defined(OS_MACOSX) && !defined(OS_IOS)
81 if (base::mac::IsOSSnowLeopard())
85 ExtensionTestMessageListener launched_listener("Launched", true);
86 LoadAndLaunchPlatformApp("leave_fullscreen");
87 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
89 // We start by making sure the window is actually focused.
90 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
91 GetFirstShellWindow()->GetNativeWindow()));
93 // When receiving the reply, the application will try to go fullscreen using
94 // the Window API but there is no synchronous way to know if that actually
95 // succeeded. Also, failure will not be notified. A failure case will only be
96 // known with a timeout.
98 FullscreenChangeWaiter fs_changed(GetFirstShellWindow()->GetBaseWindow());
100 launched_listener.Reply("window");
105 // Depending on the platform, going fullscreen might create an animation.
106 // We want to make sure that the ESC key we will send next is actually going
107 // to be received and the application might not receive key events during the
108 // animation so we should wait for the key focus to be back.
111 // Same idea as above but for leaving fullscreen. Fullscreen mode should be
112 // left when ESC is received.
114 FullscreenChangeWaiter fs_changed(GetFirstShellWindow()->GetBaseWindow());
116 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
122 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenDOM) {
123 // This test is flaky on MacOS 10.6.
124 #if defined(OS_MACOSX) && !defined(OS_IOS)
125 if (base::mac::IsOSSnowLeopard())
129 ExtensionTestMessageListener launched_listener("Launched", true);
130 LoadAndLaunchPlatformApp("leave_fullscreen");
131 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
133 // We start by making sure the window is actually focused.
134 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
135 GetFirstShellWindow()->GetNativeWindow()));
137 launched_listener.Reply("dom");
139 // Because the DOM way to go fullscreen requires user gesture, we simulate a
140 // key event to get the window entering in fullscreen mode. The reply will
141 // make the window listen for the key event. The reply will be sent to the
142 // renderer process before the keypress and should be received in that order.
143 // When receiving the key event, the application will try to go fullscreen
144 // using the Window API but there is no synchronous way to know if that
145 // actually succeeded. Also, failure will not be notified. A failure case will
146 // only be known with a timeout.
148 FullscreenChangeWaiter fs_changed(GetFirstShellWindow()->GetBaseWindow());
151 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
156 // Depending on the platform, going fullscreen might create an animation.
157 // We want to make sure that the ESC key we will send next is actually going
158 // to be received and the application might not receive key events during the
159 // animation so we should wait for the key focus to be back.
162 // Same idea as above but for leaving fullscreen. Fullscreen mode should be
163 // left when ESC is received.
165 FullscreenChangeWaiter fs_changed(GetFirstShellWindow()->GetBaseWindow());
167 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
173 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
174 ESCDoesNotLeaveFullscreenWindow) {
175 // This test is flaky on MacOS 10.6.
176 #if defined(OS_MACOSX) && !defined(OS_IOS)
177 if (base::mac::IsOSSnowLeopard())
181 ExtensionTestMessageListener launched_listener("Launched", true);
182 LoadAndLaunchPlatformApp("prevent_leave_fullscreen");
183 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
185 // We start by making sure the window is actually focused.
186 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
187 GetFirstShellWindow()->GetNativeWindow()));
189 // When receiving the reply, the application will try to go fullscreen using
190 // the Window API but there is no synchronous way to know if that actually
191 // succeeded. Also, failure will not be notified. A failure case will only be
192 // known with a timeout.
194 FullscreenChangeWaiter fs_changed(GetFirstShellWindow()->GetBaseWindow());
196 launched_listener.Reply("window");
201 // Depending on the platform, going fullscreen might create an animation.
202 // We want to make sure that the ESC key we will send next is actually going
203 // to be received and the application might not receive key events during the
204 // animation so we should wait for the key focus to be back.
207 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
209 ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
211 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
213 ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
215 // We assume that at that point, if we had to leave fullscreen, we should be.
216 // However, by nature, we can not guarantee that and given that we do test
217 // that nothing happens, we might end up with random-success when the feature
219 EXPECT_TRUE(GetFirstShellWindow()->GetBaseWindow()->IsFullscreen());
222 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
223 ESCDoesNotLeaveFullscreenDOM) {
224 // This test is flaky on MacOS 10.6.
225 #if defined(OS_MACOSX) && !defined(OS_IOS)
226 if (base::mac::IsOSSnowLeopard())
230 ExtensionTestMessageListener launched_listener("Launched", true);
231 LoadAndLaunchPlatformApp("prevent_leave_fullscreen");
232 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
234 // We start by making sure the window is actually focused.
235 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
236 GetFirstShellWindow()->GetNativeWindow()));
238 launched_listener.Reply("dom");
240 // Because the DOM way to go fullscreen requires user gesture, we simulate a
241 // key event to get the window entering in fullscreen mode. The reply will
242 // make the window listen for the key event. The reply will be sent to the
243 // renderer process before the keypress and should be received in that order.
244 // When receiving the key event, the application will try to go fullscreen
245 // using the Window API but there is no synchronous way to know if that
246 // actually succeeded. Also, failure will not be notified. A failure case will
247 // only be known with a timeout.
249 FullscreenChangeWaiter fs_changed(GetFirstShellWindow()->GetBaseWindow());
252 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
257 // Depending on the platform, going fullscreen might create an animation.
258 // We want to make sure that the ESC key we will send next is actually going
259 // to be received and the application might not receive key events during the
260 // animation so we should wait for the key focus to be back.
263 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
265 ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
267 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
269 ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
271 // We assume that at that point, if we had to leave fullscreen, we should be.
272 // However, by nature, we can not guarantee that and given that we do test
273 // that nothing happens, we might end up with random-success when the feature
275 EXPECT_TRUE(GetFirstShellWindow()->GetBaseWindow()->IsFullscreen());
278 // This test does not work on Linux Aura because ShowInactive() is not
279 // implemented. See http://crbug.com/325142
280 // It also does not work on Windows because of the document being focused even
281 // though the window is not activated. See http://crbug.com/326986
282 // It also does not work on MacOS because ::ShowInactive() ends up behaving like
283 // ::Show() because of Cocoa conventions. See http://crbug.com/326987
284 // Those tests should be disabled on Linux GTK when they are enabled on the
285 // other platforms, see http://crbug.com/328829
286 #if (defined(OS_LINUX) && defined(USE_AURA)) || \
287 defined(OS_WIN) || defined(OS_MACOSX)
288 #define MAYBE_TestCreate DISABLED_TestCreate
289 #define MAYBE_TestShow DISABLED_TestShow
291 #define MAYBE_TestCreate TestCreate
292 #define MAYBE_TestShow TestShow
295 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestCreate) {
296 ASSERT_TRUE(RunAppWindowInteractiveTest("testCreate")) << message_;
299 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestShow) {
300 ASSERT_TRUE(RunAppWindowInteractiveTest("testShow")) << message_;