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