Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / chrome / browser / apps / app_window_interactive_uitest.cc
blobcd1158ef0a8f299988b81791b2e148b84c9d78b4
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 "chrome/browser/apps/app_browsertest_util.h"
6 #include "chrome/browser/extensions/extension_test_message_listener.h"
7 #include "chrome/test/base/interactive_test_utils.h"
8 #include "extensions/browser/app_window/native_app_window.h"
10 #if defined(OS_MACOSX) && !defined(OS_IOS)
11 #include "base/mac/mac_util.h"
12 #endif
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
23 using extensions::NativeAppWindow;
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()) {}
33 void Wait() {
34 while (initial_fullscreen_state_ == window_->IsFullscreen())
35 content::RunAllPendingInMessageLoop();
38 private:
39 NativeAppWindow* window_;
40 bool initial_fullscreen_state_;
42 DISALLOW_COPY_AND_ASSIGN(FullscreenChangeWaiter);
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);
51 ResultCatcher catcher;
52 launched_listener.Reply(testName);
54 if (!catcher.GetNextResult()) {
55 message_ = catcher.message();
56 return false;
59 return true;
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);
72 // This method will wait until the application is able to ack a key event.
73 void WaitUntilKeyFocus() {
74 ExtensionTestMessageListener key_listener("KeyReceived", false);
76 while (!key_listener.was_satisfied()) {
77 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_Z));
78 content::RunAllPendingInMessageLoop();
82 // This test is a method so that we can test with each frame type.
83 void TestOuterBoundsHelper(const std::string& frame_type);
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
93 ExtensionTestMessageListener launched_listener("Launched", true);
94 LoadAndLaunchPlatformApp("leave_fullscreen", &launched_listener);
96 // We start by making sure the window is actually focused.
97 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
98 GetFirstAppWindow()->GetNativeWindow()));
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.
105 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
107 launched_listener.Reply("window");
109 fs_changed.Wait();
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();
118 // Same idea as above but for leaving fullscreen. Fullscreen mode should be
119 // left when ESC is received.
121 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
123 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
125 fs_changed.Wait();
129 #if defined(OS_MACOSX)
130 // http://crbug.com/406009
131 #define MAYBE_ESCLeavesFullscreenDOM DISABLED_ESCLeavesFullscreenDOM
132 #else
133 #define MAYBE_ESCLeavesFullscreenDOM ESCLeavesFullscreenDOM
134 #endif
135 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_ESCLeavesFullscreenDOM) {
136 // This test is flaky on MacOS 10.6.
137 #if defined(OS_MACOSX) && !defined(OS_IOS)
138 if (base::mac::IsOSSnowLeopard())
139 return;
140 #endif
142 ExtensionTestMessageListener launched_listener("Launched", true);
143 LoadAndLaunchPlatformApp("leave_fullscreen", &launched_listener);
145 // We start by making sure the window is actually focused.
146 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
147 GetFirstAppWindow()->GetNativeWindow()));
149 launched_listener.Reply("dom");
151 // Because the DOM way to go fullscreen requires user gesture, we simulate a
152 // key event to get the window entering in fullscreen mode. The reply will
153 // make the window listen for the key event. The reply will be sent to the
154 // renderer process before the keypress and should be received in that order.
155 // When receiving the key event, the application will try to go fullscreen
156 // using the Window API but there is no synchronous way to know if that
157 // actually succeeded. Also, failure will not be notified. A failure case will
158 // only be known with a timeout.
160 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
162 WaitUntilKeyFocus();
163 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
165 fs_changed.Wait();
168 // Depending on the platform, going fullscreen might create an animation.
169 // We want to make sure that the ESC key we will send next is actually going
170 // to be received and the application might not receive key events during the
171 // animation so we should wait for the key focus to be back.
172 WaitUntilKeyFocus();
174 // Same idea as above but for leaving fullscreen. Fullscreen mode should be
175 // left when ESC is received.
177 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
179 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
181 fs_changed.Wait();
185 #if defined(OS_MACOSX)
186 // http://crbug.com/406009
187 #define MAYBE_ESCDoesNotLeaveFullscreenWindow DISABLED_ESCDoesNotLeaveFullscreenWindow
188 #else
189 #define MAYBE_ESCDoesNotLeaveFullscreenWindow ESCDoesNotLeaveFullscreenWindow
190 #endif
191 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
192 MAYBE_ESCDoesNotLeaveFullscreenWindow) {
193 // This test is flaky on MacOS 10.6.
194 #if defined(OS_MACOSX) && !defined(OS_IOS)
195 if (base::mac::IsOSSnowLeopard())
196 return;
197 #endif
199 ExtensionTestMessageListener launched_listener("Launched", true);
200 LoadAndLaunchPlatformApp("prevent_leave_fullscreen", &launched_listener);
202 // We start by making sure the window is actually focused.
203 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
204 GetFirstAppWindow()->GetNativeWindow()));
206 // When receiving the reply, the application will try to go fullscreen using
207 // the Window API but there is no synchronous way to know if that actually
208 // succeeded. Also, failure will not be notified. A failure case will only be
209 // known with a timeout.
211 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
213 launched_listener.Reply("window");
215 fs_changed.Wait();
218 // Depending on the platform, going fullscreen might create an animation.
219 // We want to make sure that the ESC key we will send next is actually going
220 // to be received and the application might not receive key events during the
221 // animation so we should wait for the key focus to be back.
222 WaitUntilKeyFocus();
224 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
226 ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
228 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
230 ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
232 // We assume that at that point, if we had to leave fullscreen, we should be.
233 // However, by nature, we can not guarantee that and given that we do test
234 // that nothing happens, we might end up with random-success when the feature
235 // is broken.
236 EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
239 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
240 ESCDoesNotLeaveFullscreenDOM) {
241 // This test is flaky on MacOS 10.6.
242 #if defined(OS_MACOSX) && !defined(OS_IOS)
243 if (base::mac::IsOSSnowLeopard())
244 return;
245 #endif
247 ExtensionTestMessageListener launched_listener("Launched", true);
248 LoadAndLaunchPlatformApp("prevent_leave_fullscreen", &launched_listener);
250 // We start by making sure the window is actually focused.
251 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
252 GetFirstAppWindow()->GetNativeWindow()));
254 launched_listener.Reply("dom");
256 // Because the DOM way to go fullscreen requires user gesture, we simulate a
257 // key event to get the window entering in fullscreen mode. The reply will
258 // make the window listen for the key event. The reply will be sent to the
259 // renderer process before the keypress and should be received in that order.
260 // When receiving the key event, the application will try to go fullscreen
261 // using the Window API but there is no synchronous way to know if that
262 // actually succeeded. Also, failure will not be notified. A failure case will
263 // only be known with a timeout.
265 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
267 WaitUntilKeyFocus();
268 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
270 fs_changed.Wait();
273 // Depending on the platform, going fullscreen might create an animation.
274 // We want to make sure that the ESC key we will send next is actually going
275 // to be received and the application might not receive key events during the
276 // animation so we should wait for the key focus to be back.
277 WaitUntilKeyFocus();
279 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
281 ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
283 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
285 ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
287 // We assume that at that point, if we had to leave fullscreen, we should be.
288 // However, by nature, we can not guarantee that and given that we do test
289 // that nothing happens, we might end up with random-success when the feature
290 // is broken.
291 EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
294 // This test is duplicated from ESCDoesNotLeaveFullscreenWindow.
295 // It runs the same test, but uses the old permission names: 'fullscreen'
296 // and 'overrideEscFullscreen'.
297 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
298 ESCDoesNotLeaveFullscreenOldPermission) {
299 // This test is flaky on MacOS 10.6.
300 #if defined(OS_MACOSX) && !defined(OS_IOS)
301 if (base::mac::IsOSSnowLeopard())
302 return;
303 #endif
305 ExtensionTestMessageListener launched_listener("Launched", true);
306 LoadAndLaunchPlatformApp("prevent_leave_fullscreen_old", &launched_listener);
308 // We start by making sure the window is actually focused.
309 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
310 GetFirstAppWindow()->GetNativeWindow()));
312 // When receiving the reply, the application will try to go fullscreen using
313 // the Window API but there is no synchronous way to know if that actually
314 // succeeded. Also, failure will not be notified. A failure case will only be
315 // known with a timeout.
317 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
319 launched_listener.Reply("window");
321 fs_changed.Wait();
324 // Depending on the platform, going fullscreen might create an animation.
325 // We want to make sure that the ESC key we will send next is actually going
326 // to be received and the application might not receive key events during the
327 // animation so we should wait for the key focus to be back.
328 WaitUntilKeyFocus();
330 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
332 ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
334 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
336 ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
338 // We assume that at that point, if we had to leave fullscreen, we should be.
339 // However, by nature, we can not guarantee that and given that we do test
340 // that nothing happens, we might end up with random-success when the feature
341 // is broken.
342 EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
345 #if defined(OS_MACOSX)
346 // http://crbug.com/404081
347 #define MAYBE_TestInnerBounds DISABLED_TestInnerBounds
348 #else
349 #define MAYBE_TestInnerBounds TestInnerBounds
350 #endif
351 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestInnerBounds) {
352 ASSERT_TRUE(RunAppWindowInteractiveTest("testInnerBounds")) << message_;
355 void AppWindowInteractiveTest::TestOuterBoundsHelper(
356 const std::string& frame_type) {
357 ExtensionTestMessageListener launched_listener("Launched", true);
358 const extensions::Extension* app =
359 LoadAndLaunchPlatformApp("outer_bounds", &launched_listener);
361 launched_listener.Reply(frame_type);
362 launched_listener.Reset();
363 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
365 apps::AppWindow* window = GetFirstAppWindowForApp(app->id());
366 gfx::Rect window_bounds;
367 gfx::Size min_size, max_size;
369 #if defined(OS_WIN)
370 // Get the bounds from the HWND.
371 HWND hwnd = views::HWNDForNativeWindow(window->GetNativeWindow());
372 RECT rect;
373 ::GetWindowRect(hwnd, &rect);
374 window_bounds = gfx::Rect(
375 rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
377 // HWNDMessageHandler calls this when responding to WM_GETMINMAXSIZE, so it's
378 // the closest to what the window will see.
379 views::HWNDMessageHandlerDelegate* host =
380 static_cast<views::HWNDMessageHandlerDelegate*>(
381 static_cast<views::DesktopWindowTreeHostWin*>(
382 aura::WindowTreeHost::GetForAcceleratedWidget(hwnd)));
383 host->GetMinMaxSize(&min_size, &max_size);
384 // Note that this does not include the the client area insets so we need to
385 // add them.
386 gfx::Insets insets;
387 host->GetClientAreaInsets(&insets);
388 min_size = gfx::Size(min_size.width() + insets.left() + insets.right(),
389 min_size.height() + insets.top() + insets.bottom());
390 max_size = gfx::Size(
391 max_size.width() ? max_size.width() + insets.left() + insets.right() : 0,
392 max_size.height() ? max_size.height() + insets.top() + insets.bottom()
393 : 0);
394 #endif // defined(OS_WIN)
396 // These match the values in the outer_bounds/test.js
397 EXPECT_EQ(gfx::Rect(10, 11, 300, 301), window_bounds);
398 EXPECT_EQ(window->GetBaseWindow()->GetBounds(), window_bounds);
399 EXPECT_EQ(200, min_size.width());
400 EXPECT_EQ(201, min_size.height());
401 EXPECT_EQ(400, max_size.width());
402 EXPECT_EQ(401, max_size.height());
405 // TODO(jackhou): Make this test work for other OSes.
406 #if !defined(OS_WIN)
407 #define MAYBE_TestOuterBoundsFrameChrome DISABLED_TestOuterBoundsFrameChrome
408 #define MAYBE_TestOuterBoundsFrameNone DISABLED_TestOuterBoundsFrameNone
409 #define MAYBE_TestOuterBoundsFrameColor DISABLED_TestOuterBoundsFrameColor
410 #else
411 #define MAYBE_TestOuterBoundsFrameChrome TestOuterBoundsFrameChrome
412 #define MAYBE_TestOuterBoundsFrameNone TestOuterBoundsFrameNone
413 #define MAYBE_TestOuterBoundsFrameColor TestOuterBoundsFrameColor
414 #endif
416 // Test that the outer bounds match that of the native window.
417 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
418 MAYBE_TestOuterBoundsFrameChrome) {
419 TestOuterBoundsHelper("chrome");
421 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
422 MAYBE_TestOuterBoundsFrameNone) {
423 TestOuterBoundsHelper("none");
425 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
426 MAYBE_TestOuterBoundsFrameColor) {
427 TestOuterBoundsHelper("color");
430 // This test does not work on Linux Aura because ShowInactive() is not
431 // implemented. See http://crbug.com/325142
432 // It also does not work on Windows because of the document being focused even
433 // though the window is not activated. See http://crbug.com/326986
434 // It also does not work on MacOS because ::ShowInactive() ends up behaving like
435 // ::Show() because of Cocoa conventions. See http://crbug.com/326987
436 // Those tests should be disabled on Linux GTK when they are enabled on the
437 // other platforms, see http://crbug.com/328829
438 #if (defined(OS_LINUX) && defined(USE_AURA)) || \
439 defined(OS_WIN) || defined(OS_MACOSX)
440 #define MAYBE_TestCreate DISABLED_TestCreate
441 #define MAYBE_TestShow DISABLED_TestShow
442 #else
443 #define MAYBE_TestCreate TestCreate
444 #define MAYBE_TestShow TestShow
445 #endif
447 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestCreate) {
448 ASSERT_TRUE(RunAppWindowInteractiveTest("testCreate")) << message_;
451 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestShow) {
452 ASSERT_TRUE(RunAppWindowInteractiveTest("testShow")) << message_;
455 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, TestDrawAttention) {
456 ASSERT_TRUE(RunAppWindowInteractiveTest("testDrawAttention")) << message_;