Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / apps / app_window_interactive_uitest.cc
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 #if defined(OS_WIN)
15 #include <windows.h>
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_tree_host.h"
18 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
19 #include "ui/views/win/hwnd_message_handler_delegate.h"
20 #include "ui/views/win/hwnd_util.h"
21 #endif
22
23 using apps::NativeAppWindow;
24
25 // Helper class that has to be created in the stack to check if the fullscreen
26 // setting of a NativeWindow has changed since the creation of the object.
27 class FullscreenChangeWaiter {
28  public:
29   explicit FullscreenChangeWaiter(NativeAppWindow* window)
30       : window_(window),
31         initial_fullscreen_state_(window_->IsFullscreen()) {}
32
33   void Wait() {
34     while (initial_fullscreen_state_ == window_->IsFullscreen())
35       content::RunAllPendingInMessageLoop();
36   }
37
38  private:
39   NativeAppWindow* window_;
40   bool initial_fullscreen_state_;
41
42   DISALLOW_COPY_AND_ASSIGN(FullscreenChangeWaiter);
43 };
44
45 class AppWindowInteractiveTest : public extensions::PlatformAppBrowserTest {
46  public:
47   bool RunAppWindowInteractiveTest(const char* testName) {
48     ExtensionTestMessageListener launched_listener("Launched", true);
49     LoadAndLaunchPlatformApp("window_api_interactive", &launched_listener);
50
51     ResultCatcher catcher;
52     launched_listener.Reply(testName);
53
54     if (!catcher.GetNextResult()) {
55       message_ = catcher.message();
56       return false;
57     }
58
59     return true;
60   }
61
62   bool SimulateKeyPress(ui::KeyboardCode key) {
63     return ui_test_utils::SendKeyPressToWindowSync(
64         GetFirstAppWindow()->GetNativeWindow(),
65         key,
66         false,
67         false,
68         false,
69         false);
70   }
71
72   // This method will wait until the application is able to ack a key event.
73   void WaitUntilKeyFocus() {
74     ExtensionTestMessageListener key_listener("KeyReceived", false);
75
76     while (!key_listener.was_satisfied()) {
77       ASSERT_TRUE(SimulateKeyPress(ui::VKEY_Z));
78       content::RunAllPendingInMessageLoop();
79     }
80   }
81
82   // This test is a method so that we can test with each frame type.
83   void TestOuterBoundsHelper(const std::string& frame_type);
84 };
85
86 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenWindow) {
87 // This test is flaky on MacOS 10.6.
88 #if defined(OS_MACOSX) && !defined(OS_IOS)
89   if (base::mac::IsOSSnowLeopard())
90     return;
91 #endif
92
93   ExtensionTestMessageListener launched_listener("Launched", true);
94   LoadAndLaunchPlatformApp("leave_fullscreen", &launched_listener);
95
96   // We start by making sure the window is actually focused.
97   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
98       GetFirstAppWindow()->GetNativeWindow()));
99
100   // When receiving the reply, the application will try to go fullscreen using
101   // the Window API but there is no synchronous way to know if that actually
102   // succeeded. Also, failure will not be notified. A failure case will only be
103   // known with a timeout.
104   {
105     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
106
107     launched_listener.Reply("window");
108
109     fs_changed.Wait();
110   }
111
112   // Depending on the platform, going fullscreen might create an animation.
113   // We want to make sure that the ESC key we will send next is actually going
114   // to be received and the application might not receive key events during the
115   // animation so we should wait for the key focus to be back.
116   WaitUntilKeyFocus();
117
118   // Same idea as above but for leaving fullscreen. Fullscreen mode should be
119   // left when ESC is received.
120   {
121     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
122
123     ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
124
125     fs_changed.Wait();
126   }
127 }
128
129 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenDOM) {
130 // This test is flaky on MacOS 10.6.
131 #if defined(OS_MACOSX) && !defined(OS_IOS)
132   if (base::mac::IsOSSnowLeopard())
133     return;
134 #endif
135
136   ExtensionTestMessageListener launched_listener("Launched", true);
137   LoadAndLaunchPlatformApp("leave_fullscreen", &launched_listener);
138
139   // We start by making sure the window is actually focused.
140   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
141       GetFirstAppWindow()->GetNativeWindow()));
142
143   launched_listener.Reply("dom");
144
145   // Because the DOM way to go fullscreen requires user gesture, we simulate a
146   // key event to get the window entering in fullscreen mode. The reply will
147   // make the window listen for the key event. The reply will be sent to the
148   // renderer process before the keypress and should be received in that order.
149   // When receiving the key event, the application will try to go fullscreen
150   // using the Window API but there is no synchronous way to know if that
151   // actually succeeded. Also, failure will not be notified. A failure case will
152   // only be known with a timeout.
153   {
154     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
155
156     WaitUntilKeyFocus();
157     ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
158
159     fs_changed.Wait();
160   }
161
162   // Depending on the platform, going fullscreen might create an animation.
163   // We want to make sure that the ESC key we will send next is actually going
164   // to be received and the application might not receive key events during the
165   // animation so we should wait for the key focus to be back.
166   WaitUntilKeyFocus();
167
168   // Same idea as above but for leaving fullscreen. Fullscreen mode should be
169   // left when ESC is received.
170   {
171     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
172
173     ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
174
175     fs_changed.Wait();
176   }
177 }
178
179 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
180                        ESCDoesNotLeaveFullscreenWindow) {
181 // This test is flaky on MacOS 10.6.
182 #if defined(OS_MACOSX) && !defined(OS_IOS)
183   if (base::mac::IsOSSnowLeopard())
184     return;
185 #endif
186
187   ExtensionTestMessageListener launched_listener("Launched", true);
188   LoadAndLaunchPlatformApp("prevent_leave_fullscreen", &launched_listener);
189
190   // We start by making sure the window is actually focused.
191   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
192       GetFirstAppWindow()->GetNativeWindow()));
193
194   // When receiving the reply, the application will try to go fullscreen using
195   // the Window API but there is no synchronous way to know if that actually
196   // succeeded. Also, failure will not be notified. A failure case will only be
197   // known with a timeout.
198   {
199     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
200
201     launched_listener.Reply("window");
202
203     fs_changed.Wait();
204   }
205
206   // Depending on the platform, going fullscreen might create an animation.
207   // We want to make sure that the ESC key we will send next is actually going
208   // to be received and the application might not receive key events during the
209   // animation so we should wait for the key focus to be back.
210   WaitUntilKeyFocus();
211
212   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
213
214   ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
215
216   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
217
218   ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
219
220   // We assume that at that point, if we had to leave fullscreen, we should be.
221   // However, by nature, we can not guarantee that and given that we do test
222   // that nothing happens, we might end up with random-success when the feature
223   // is broken.
224   EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
225 }
226
227 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
228                        ESCDoesNotLeaveFullscreenDOM) {
229 // This test is flaky on MacOS 10.6.
230 #if defined(OS_MACOSX) && !defined(OS_IOS)
231   if (base::mac::IsOSSnowLeopard())
232     return;
233 #endif
234
235   ExtensionTestMessageListener launched_listener("Launched", true);
236   LoadAndLaunchPlatformApp("prevent_leave_fullscreen", &launched_listener);
237
238   // We start by making sure the window is actually focused.
239   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
240       GetFirstAppWindow()->GetNativeWindow()));
241
242   launched_listener.Reply("dom");
243
244   // Because the DOM way to go fullscreen requires user gesture, we simulate a
245   // key event to get the window entering in fullscreen mode. The reply will
246   // make the window listen for the key event. The reply will be sent to the
247   // renderer process before the keypress and should be received in that order.
248   // When receiving the key event, the application will try to go fullscreen
249   // using the Window API but there is no synchronous way to know if that
250   // actually succeeded. Also, failure will not be notified. A failure case will
251   // only be known with a timeout.
252   {
253     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
254
255     WaitUntilKeyFocus();
256     ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
257
258     fs_changed.Wait();
259   }
260
261   // Depending on the platform, going fullscreen might create an animation.
262   // We want to make sure that the ESC key we will send next is actually going
263   // to be received and the application might not receive key events during the
264   // animation so we should wait for the key focus to be back.
265   WaitUntilKeyFocus();
266
267   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
268
269   ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
270
271   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
272
273   ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
274
275   // We assume that at that point, if we had to leave fullscreen, we should be.
276   // However, by nature, we can not guarantee that and given that we do test
277   // that nothing happens, we might end up with random-success when the feature
278   // is broken.
279   EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
280 }
281
282 // This test is duplicated from ESCDoesNotLeaveFullscreenWindow.
283 // It runs the same test, but uses the old permission names: 'fullscreen'
284 // and 'overrideEscFullscreen'.
285 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
286                        ESCDoesNotLeaveFullscreenOldPermission) {
287 // This test is flaky on MacOS 10.6.
288 #if defined(OS_MACOSX) && !defined(OS_IOS)
289   if (base::mac::IsOSSnowLeopard())
290     return;
291 #endif
292
293   ExtensionTestMessageListener launched_listener("Launched", true);
294   LoadAndLaunchPlatformApp("prevent_leave_fullscreen_old", &launched_listener);
295
296   // We start by making sure the window is actually focused.
297   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
298       GetFirstAppWindow()->GetNativeWindow()));
299
300   // When receiving the reply, the application will try to go fullscreen using
301   // the Window API but there is no synchronous way to know if that actually
302   // succeeded. Also, failure will not be notified. A failure case will only be
303   // known with a timeout.
304   {
305     FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
306
307     launched_listener.Reply("window");
308
309     fs_changed.Wait();
310   }
311
312   // Depending on the platform, going fullscreen might create an animation.
313   // We want to make sure that the ESC key we will send next is actually going
314   // to be received and the application might not receive key events during the
315   // animation so we should wait for the key focus to be back.
316   WaitUntilKeyFocus();
317
318   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
319
320   ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
321
322   ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
323
324   ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
325
326   // We assume that at that point, if we had to leave fullscreen, we should be.
327   // However, by nature, we can not guarantee that and given that we do test
328   // that nothing happens, we might end up with random-success when the feature
329   // is broken.
330   EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
331 }
332
333 #if defined(OS_MACOSX)
334 // http://crbug.com/404081
335 #define MAYBE_TestInnerBounds DISABLED_TestInnerBounds
336 #else
337 #define MAYBE_TestInnerBounds TestInnerBounds
338 #endif
339 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestInnerBounds) {
340   ASSERT_TRUE(RunAppWindowInteractiveTest("testInnerBounds")) << message_;
341 }
342
343 void AppWindowInteractiveTest::TestOuterBoundsHelper(
344     const std::string& frame_type) {
345   ExtensionTestMessageListener launched_listener("Launched", true);
346   const extensions::Extension* app =
347       LoadAndLaunchPlatformApp("outer_bounds", &launched_listener);
348
349   launched_listener.Reply(frame_type);
350   launched_listener.Reset();
351   ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
352
353   apps::AppWindow* window = GetFirstAppWindowForApp(app->id());
354   gfx::Rect window_bounds;
355   gfx::Size min_size, max_size;
356
357 #if defined(OS_WIN)
358   // Get the bounds from the HWND.
359   HWND hwnd = views::HWNDForNativeWindow(window->GetNativeWindow());
360   RECT rect;
361   ::GetWindowRect(hwnd, &rect);
362   window_bounds = gfx::Rect(
363       rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
364
365   // HWNDMessageHandler calls this when responding to WM_GETMINMAXSIZE, so it's
366   // the closest to what the window will see.
367   views::HWNDMessageHandlerDelegate* host =
368       static_cast<views::HWNDMessageHandlerDelegate*>(
369           static_cast<views::DesktopWindowTreeHostWin*>(
370               aura::WindowTreeHost::GetForAcceleratedWidget(hwnd)));
371   host->GetMinMaxSize(&min_size, &max_size);
372   // Note that this does not include the the client area insets so we need to
373   // add them.
374   gfx::Insets insets;
375   host->GetClientAreaInsets(&insets);
376   min_size = gfx::Size(min_size.width() + insets.left() + insets.right(),
377                        min_size.height() + insets.top() + insets.bottom());
378   max_size = gfx::Size(
379       max_size.width() ? max_size.width() + insets.left() + insets.right() : 0,
380       max_size.height() ? max_size.height() + insets.top() + insets.bottom()
381                         : 0);
382 #endif  // defined(OS_WIN)
383
384   // These match the values in the outer_bounds/test.js
385   EXPECT_EQ(gfx::Rect(10, 11, 300, 301), window_bounds);
386   EXPECT_EQ(window->GetBaseWindow()->GetBounds(), window_bounds);
387   EXPECT_EQ(200, min_size.width());
388   EXPECT_EQ(201, min_size.height());
389   EXPECT_EQ(400, max_size.width());
390   EXPECT_EQ(401, max_size.height());
391 }
392
393 // TODO(jackhou): Make this test work for other OSes.
394 #if !defined(OS_WIN)
395 #define MAYBE_TestOuterBoundsFrameChrome DISABLED_TestOuterBoundsFrameChrome
396 #define MAYBE_TestOuterBoundsFrameNone DISABLED_TestOuterBoundsFrameNone
397 #define MAYBE_TestOuterBoundsFrameColor DISABLED_TestOuterBoundsFrameColor
398 #else
399 #define MAYBE_TestOuterBoundsFrameChrome TestOuterBoundsFrameChrome
400 #define MAYBE_TestOuterBoundsFrameNone TestOuterBoundsFrameNone
401 #define MAYBE_TestOuterBoundsFrameColor TestOuterBoundsFrameColor
402 #endif
403
404 // Test that the outer bounds match that of the native window.
405 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
406                        MAYBE_TestOuterBoundsFrameChrome) {
407   TestOuterBoundsHelper("chrome");
408 }
409 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
410                        MAYBE_TestOuterBoundsFrameNone) {
411   TestOuterBoundsHelper("none");
412 }
413 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
414                        MAYBE_TestOuterBoundsFrameColor) {
415   TestOuterBoundsHelper("color");
416 }
417
418 // This test does not work on Linux Aura because ShowInactive() is not
419 // implemented. See http://crbug.com/325142
420 // It also does not work on Windows because of the document being focused even
421 // though the window is not activated. See http://crbug.com/326986
422 // It also does not work on MacOS because ::ShowInactive() ends up behaving like
423 // ::Show() because of Cocoa conventions. See http://crbug.com/326987
424 // Those tests should be disabled on Linux GTK when they are enabled on the
425 // other platforms, see http://crbug.com/328829
426 #if (defined(OS_LINUX) && defined(USE_AURA)) || \
427     defined(OS_WIN) || defined(OS_MACOSX)
428 #define MAYBE_TestCreate DISABLED_TestCreate
429 #define MAYBE_TestShow DISABLED_TestShow
430 #else
431 #define MAYBE_TestCreate TestCreate
432 #define MAYBE_TestShow TestShow
433 #endif
434
435 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestCreate) {
436   ASSERT_TRUE(RunAppWindowInteractiveTest("testCreate")) << message_;
437 }
438
439 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestShow) {
440   ASSERT_TRUE(RunAppWindowInteractiveTest("testShow")) << message_;
441 }