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 GetFirstAppWindow()->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 GetFirstAppWindow()->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(GetFirstAppWindow()->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(GetFirstAppWindow()->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 GetFirstAppWindow()->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(GetFirstAppWindow()->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(GetFirstAppWindow()->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 GetFirstAppWindow()->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(GetFirstAppWindow()->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(GetFirstAppWindow()->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 GetFirstAppWindow()->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(GetFirstAppWindow()->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(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
278 // This test is duplicated from ESCDoesNotLeaveFullscreenWindow.
279 // It runs the same test, but uses the old permission names: 'fullscreen'
280 // and 'overrideEscFullscreen'.
281 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest
,
282 ESCDoesNotLeaveFullscreenOldPermission
) {
283 // This test is flaky on MacOS 10.6.
284 #if defined(OS_MACOSX) && !defined(OS_IOS)
285 if (base::mac::IsOSSnowLeopard())
289 ExtensionTestMessageListener
launched_listener("Launched", true);
290 LoadAndLaunchPlatformApp("prevent_leave_fullscreen_old");
291 ASSERT_TRUE(launched_listener
.WaitUntilSatisfied());
293 // We start by making sure the window is actually focused.
294 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
295 GetFirstAppWindow()->GetNativeWindow()));
297 // When receiving the reply, the application will try to go fullscreen using
298 // the Window API but there is no synchronous way to know if that actually
299 // succeeded. Also, failure will not be notified. A failure case will only be
300 // known with a timeout.
302 FullscreenChangeWaiter
fs_changed(GetFirstAppWindow()->GetBaseWindow());
304 launched_listener
.Reply("window");
309 // Depending on the platform, going fullscreen might create an animation.
310 // We want to make sure that the ESC key we will send next is actually going
311 // to be received and the application might not receive key events during the
312 // animation so we should wait for the key focus to be back.
315 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE
));
317 ExtensionTestMessageListener
second_key_listener("B_KEY_RECEIVED", false);
319 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B
));
321 ASSERT_TRUE(second_key_listener
.WaitUntilSatisfied());
323 // We assume that at that point, if we had to leave fullscreen, we should be.
324 // However, by nature, we can not guarantee that and given that we do test
325 // that nothing happens, we might end up with random-success when the feature
327 EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
330 // This test does not work on Linux Aura because ShowInactive() is not
331 // implemented. See http://crbug.com/325142
332 // It also does not work on Windows because of the document being focused even
333 // though the window is not activated. See http://crbug.com/326986
334 // It also does not work on MacOS because ::ShowInactive() ends up behaving like
335 // ::Show() because of Cocoa conventions. See http://crbug.com/326987
336 // Those tests should be disabled on Linux GTK when they are enabled on the
337 // other platforms, see http://crbug.com/328829
338 #if (defined(OS_LINUX) && defined(USE_AURA)) || \
339 defined(OS_WIN) || defined(OS_MACOSX)
340 #define MAYBE_TestCreate DISABLED_TestCreate
341 #define MAYBE_TestShow DISABLED_TestShow
343 #define MAYBE_TestCreate TestCreate
344 #define MAYBE_TestShow TestShow
347 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest
, MAYBE_TestCreate
) {
348 ASSERT_TRUE(RunAppWindowInteractiveTest("testCreate")) << message_
;
351 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest
, MAYBE_TestShow
) {
352 ASSERT_TRUE(RunAppWindowInteractiveTest("testShow")) << message_
;