• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
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"
9 
10 #if defined(OS_MACOSX) && !defined(OS_IOS)
11 #include "base/mac/mac_util.h"
12 #endif
13 
14 using apps::NativeAppWindow;
15 
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 {
19  public:
FullscreenChangeWaiter(NativeAppWindow * window)20   explicit FullscreenChangeWaiter(NativeAppWindow* window)
21       : window_(window),
22         initial_fullscreen_state_(window_->IsFullscreen()) {}
23 
Wait()24   void Wait() {
25     while (initial_fullscreen_state_ == window_->IsFullscreen())
26       content::RunAllPendingInMessageLoop();
27   }
28 
29  private:
30   NativeAppWindow* window_;
31   bool initial_fullscreen_state_;
32 
33   DISALLOW_COPY_AND_ASSIGN(FullscreenChangeWaiter);
34 };
35 
36 class AppWindowInteractiveTest : public extensions::PlatformAppBrowserTest {
37  public:
RunAppWindowInteractiveTest(const char * testName)38   bool RunAppWindowInteractiveTest(const char* testName) {
39     ExtensionTestMessageListener launched_listener("Launched", true);
40     LoadAndLaunchPlatformApp("window_api_interactive", &launched_listener);
41 
42     ResultCatcher catcher;
43     launched_listener.Reply(testName);
44 
45     if (!catcher.GetNextResult()) {
46       message_ = catcher.message();
47       return false;
48     }
49 
50     return true;
51   }
52 
SimulateKeyPress(ui::KeyboardCode key)53   bool SimulateKeyPress(ui::KeyboardCode key) {
54     return ui_test_utils::SendKeyPressToWindowSync(
55         GetFirstAppWindow()->GetNativeWindow(),
56         key,
57         false,
58         false,
59         false,
60         false);
61   }
62 
63   // This method will wait until the application is able to ack a key event.
WaitUntilKeyFocus()64   void WaitUntilKeyFocus() {
65     ExtensionTestMessageListener key_listener("KeyReceived", false);
66 
67     while (!key_listener.was_satisfied()) {
68       ASSERT_TRUE(SimulateKeyPress(ui::VKEY_Z));
69       content::RunAllPendingInMessageLoop();
70     }
71   }
72 };
73 
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,ESCLeavesFullscreenWindow)74 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenWindow) {
75 // This test is flaky on MacOS 10.6.
76 #if defined(OS_MACOSX) && !defined(OS_IOS)
77   if (base::mac::IsOSSnowLeopard())
78     return;
79 #endif
80 
81   ExtensionTestMessageListener launched_listener("Launched", true);
82   LoadAndLaunchPlatformApp("leave_fullscreen", &launched_listener);
83 
84   // We start by making sure the window is actually focused.
85   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
86       GetFirstAppWindow()->GetNativeWindow()));
87 
88   // When receiving the reply, the application will try to go fullscreen using
89   // the Window API but there is no synchronous way to know if that actually
90   // succeeded. Also, failure will not be notified. A failure case will only be
91   // known with a timeout.
92   {
93     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
94 
95     launched_listener.Reply("window");
96 
97     fs_changed.Wait();
98   }
99 
100   // Depending on the platform, going fullscreen might create an animation.
101   // We want to make sure that the ESC key we will send next is actually going
102   // to be received and the application might not receive key events during the
103   // animation so we should wait for the key focus to be back.
104   WaitUntilKeyFocus();
105 
106   // Same idea as above but for leaving fullscreen. Fullscreen mode should be
107   // left when ESC is received.
108   {
109     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
110 
111     ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
112 
113     fs_changed.Wait();
114   }
115 }
116 
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,ESCLeavesFullscreenDOM)117 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenDOM) {
118 // This test is flaky on MacOS 10.6.
119 #if defined(OS_MACOSX) && !defined(OS_IOS)
120   if (base::mac::IsOSSnowLeopard())
121     return;
122 #endif
123 
124   ExtensionTestMessageListener launched_listener("Launched", true);
125   LoadAndLaunchPlatformApp("leave_fullscreen", &launched_listener);
126 
127   // We start by making sure the window is actually focused.
128   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
129       GetFirstAppWindow()->GetNativeWindow()));
130 
131   launched_listener.Reply("dom");
132 
133   // Because the DOM way to go fullscreen requires user gesture, we simulate a
134   // key event to get the window entering in fullscreen mode. The reply will
135   // make the window listen for the key event. The reply will be sent to the
136   // renderer process before the keypress and should be received in that order.
137   // When receiving the key event, the application will try to go fullscreen
138   // using the Window API but there is no synchronous way to know if that
139   // actually succeeded. Also, failure will not be notified. A failure case will
140   // only be known with a timeout.
141   {
142     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
143 
144     WaitUntilKeyFocus();
145     ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
146 
147     fs_changed.Wait();
148   }
149 
150   // Depending on the platform, going fullscreen might create an animation.
151   // We want to make sure that the ESC key we will send next is actually going
152   // to be received and the application might not receive key events during the
153   // animation so we should wait for the key focus to be back.
154   WaitUntilKeyFocus();
155 
156   // Same idea as above but for leaving fullscreen. Fullscreen mode should be
157   // left when ESC is received.
158   {
159     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
160 
161     ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
162 
163     fs_changed.Wait();
164   }
165 }
166 
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,ESCDoesNotLeaveFullscreenWindow)167 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
168                        ESCDoesNotLeaveFullscreenWindow) {
169 // This test is flaky on MacOS 10.6.
170 #if defined(OS_MACOSX) && !defined(OS_IOS)
171   if (base::mac::IsOSSnowLeopard())
172     return;
173 #endif
174 
175   ExtensionTestMessageListener launched_listener("Launched", true);
176   LoadAndLaunchPlatformApp("prevent_leave_fullscreen", &launched_listener);
177 
178   // We start by making sure the window is actually focused.
179   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
180       GetFirstAppWindow()->GetNativeWindow()));
181 
182   // When receiving the reply, the application will try to go fullscreen using
183   // the Window API but there is no synchronous way to know if that actually
184   // succeeded. Also, failure will not be notified. A failure case will only be
185   // known with a timeout.
186   {
187     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
188 
189     launched_listener.Reply("window");
190 
191     fs_changed.Wait();
192   }
193 
194   // Depending on the platform, going fullscreen might create an animation.
195   // We want to make sure that the ESC key we will send next is actually going
196   // to be received and the application might not receive key events during the
197   // animation so we should wait for the key focus to be back.
198   WaitUntilKeyFocus();
199 
200   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
201 
202   ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
203 
204   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
205 
206   ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
207 
208   // We assume that at that point, if we had to leave fullscreen, we should be.
209   // However, by nature, we can not guarantee that and given that we do test
210   // that nothing happens, we might end up with random-success when the feature
211   // is broken.
212   EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
213 }
214 
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,ESCDoesNotLeaveFullscreenDOM)215 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
216                        ESCDoesNotLeaveFullscreenDOM) {
217 // This test is flaky on MacOS 10.6.
218 #if defined(OS_MACOSX) && !defined(OS_IOS)
219   if (base::mac::IsOSSnowLeopard())
220     return;
221 #endif
222 
223   ExtensionTestMessageListener launched_listener("Launched", true);
224   LoadAndLaunchPlatformApp("prevent_leave_fullscreen", &launched_listener);
225 
226   // We start by making sure the window is actually focused.
227   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
228       GetFirstAppWindow()->GetNativeWindow()));
229 
230   launched_listener.Reply("dom");
231 
232   // Because the DOM way to go fullscreen requires user gesture, we simulate a
233   // key event to get the window entering in fullscreen mode. The reply will
234   // make the window listen for the key event. The reply will be sent to the
235   // renderer process before the keypress and should be received in that order.
236   // When receiving the key event, the application will try to go fullscreen
237   // using the Window API but there is no synchronous way to know if that
238   // actually succeeded. Also, failure will not be notified. A failure case will
239   // only be known with a timeout.
240   {
241     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
242 
243     WaitUntilKeyFocus();
244     ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
245 
246     fs_changed.Wait();
247   }
248 
249   // Depending on the platform, going fullscreen might create an animation.
250   // We want to make sure that the ESC key we will send next is actually going
251   // to be received and the application might not receive key events during the
252   // animation so we should wait for the key focus to be back.
253   WaitUntilKeyFocus();
254 
255   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
256 
257   ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
258 
259   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
260 
261   ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
262 
263   // We assume that at that point, if we had to leave fullscreen, we should be.
264   // However, by nature, we can not guarantee that and given that we do test
265   // that nothing happens, we might end up with random-success when the feature
266   // is broken.
267   EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
268 }
269 
270 // This test is duplicated from ESCDoesNotLeaveFullscreenWindow.
271 // It runs the same test, but uses the old permission names: 'fullscreen'
272 // and 'overrideEscFullscreen'.
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,ESCDoesNotLeaveFullscreenOldPermission)273 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
274                        ESCDoesNotLeaveFullscreenOldPermission) {
275 // This test is flaky on MacOS 10.6.
276 #if defined(OS_MACOSX) && !defined(OS_IOS)
277   if (base::mac::IsOSSnowLeopard())
278     return;
279 #endif
280 
281   ExtensionTestMessageListener launched_listener("Launched", true);
282   LoadAndLaunchPlatformApp("prevent_leave_fullscreen_old", &launched_listener);
283 
284   // We start by making sure the window is actually focused.
285   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
286       GetFirstAppWindow()->GetNativeWindow()));
287 
288   // When receiving the reply, the application will try to go fullscreen using
289   // the Window API but there is no synchronous way to know if that actually
290   // succeeded. Also, failure will not be notified. A failure case will only be
291   // known with a timeout.
292   {
293     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
294 
295     launched_listener.Reply("window");
296 
297     fs_changed.Wait();
298   }
299 
300   // Depending on the platform, going fullscreen might create an animation.
301   // We want to make sure that the ESC key we will send next is actually going
302   // to be received and the application might not receive key events during the
303   // animation so we should wait for the key focus to be back.
304   WaitUntilKeyFocus();
305 
306   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
307 
308   ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
309 
310   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
311 
312   ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
313 
314   // We assume that at that point, if we had to leave fullscreen, we should be.
315   // However, by nature, we can not guarantee that and given that we do test
316   // that nothing happens, we might end up with random-success when the feature
317   // is broken.
318   EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
319 }
320 
321 // This test does not work on Linux Aura because ShowInactive() is not
322 // implemented. See http://crbug.com/325142
323 // It also does not work on Windows because of the document being focused even
324 // though the window is not activated. See http://crbug.com/326986
325 // It also does not work on MacOS because ::ShowInactive() ends up behaving like
326 // ::Show() because of Cocoa conventions. See http://crbug.com/326987
327 // Those tests should be disabled on Linux GTK when they are enabled on the
328 // other platforms, see http://crbug.com/328829
329 #if (defined(OS_LINUX) && defined(USE_AURA)) || \
330     defined(OS_WIN) || defined(OS_MACOSX)
331 #define MAYBE_TestCreate DISABLED_TestCreate
332 #define MAYBE_TestShow DISABLED_TestShow
333 #else
334 #define MAYBE_TestCreate TestCreate
335 #define MAYBE_TestShow TestShow
336 #endif
337 
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,MAYBE_TestCreate)338 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestCreate) {
339   ASSERT_TRUE(RunAppWindowInteractiveTest("testCreate")) << message_;
340 }
341 
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,MAYBE_TestShow)342 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestShow) {
343   ASSERT_TRUE(RunAppWindowInteractiveTest("testShow")) << message_;
344 }
345