Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / apps / app_window_interactive_uitest.cc
blobfa7d6d76486485c9879bea6d99269e96938e312e
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/lifetime/application_lifetime.h"
7 #include "chrome/browser/ui/browser_iterator.h"
8 #include "chrome/browser/ui/browser_window.h"
9 #include "chrome/test/base/interactive_test_utils.h"
10 #include "extensions/browser/app_window/native_app_window.h"
11 #include "extensions/test/extension_test_message_listener.h"
12 #include "extensions/test/result_catcher.h"
14 #if defined(OS_MACOSX)
15 #include "base/mac/mac_util.h"
16 #include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
17 #endif
19 #if defined(OS_WIN)
20 #include <windows.h>
21 #include "ui/aura/window.h"
22 #include "ui/aura/window_tree_host.h"
23 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
24 #include "ui/views/win/hwnd_message_handler_delegate.h"
25 #include "ui/views/win/hwnd_util.h"
26 #endif
28 using extensions::AppWindow;
29 using extensions::NativeAppWindow;
31 // Helper class that has to be created in the stack to check if the fullscreen
32 // setting of a NativeWindow has changed since the creation of the object.
33 class FullscreenChangeWaiter {
34 public:
35 explicit FullscreenChangeWaiter(NativeAppWindow* window)
36 : window_(window),
37 initial_fullscreen_state_(window_->IsFullscreen()) {}
39 void Wait() {
40 while (initial_fullscreen_state_ == window_->IsFullscreen())
41 content::RunAllPendingInMessageLoop();
44 private:
45 NativeAppWindow* window_;
46 bool initial_fullscreen_state_;
48 DISALLOW_COPY_AND_ASSIGN(FullscreenChangeWaiter);
51 class AppWindowInteractiveTest : public extensions::PlatformAppBrowserTest {
52 public:
53 bool RunAppWindowInteractiveTest(const char* testName) {
54 ExtensionTestMessageListener launched_listener("Launched", true);
55 LoadAndLaunchPlatformApp("window_api_interactive", &launched_listener);
57 extensions::ResultCatcher catcher;
58 launched_listener.Reply(testName);
60 if (!catcher.GetNextResult()) {
61 message_ = catcher.message();
62 return false;
65 return true;
68 bool SimulateKeyPress(ui::KeyboardCode key) {
69 return ui_test_utils::SendKeyPressToWindowSync(
70 GetFirstAppWindow()->GetNativeWindow(),
71 key,
72 false,
73 false,
74 false,
75 false);
78 // This method will wait until the application is able to ack a key event.
79 void WaitUntilKeyFocus() {
80 ExtensionTestMessageListener key_listener("KeyReceived", false);
82 while (!key_listener.was_satisfied()) {
83 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_Z));
84 content::RunAllPendingInMessageLoop();
88 // This test is a method so that we can test with each frame type.
89 void TestOuterBoundsHelper(const std::string& frame_type);
92 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenWindow) {
93 // This test is flaky on MacOS 10.6.
94 #if defined(OS_MACOSX)
95 if (base::mac::IsOSSnowLeopard())
96 return;
98 ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
99 #endif
101 ExtensionTestMessageListener launched_listener("Launched", true);
102 LoadAndLaunchPlatformApp("leave_fullscreen", &launched_listener);
104 // We start by making sure the window is actually focused.
105 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
106 GetFirstAppWindow()->GetNativeWindow()));
108 // When receiving the reply, the application will try to go fullscreen using
109 // the Window API but there is no synchronous way to know if that actually
110 // succeeded. Also, failure will not be notified. A failure case will only be
111 // known with a timeout.
113 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
115 launched_listener.Reply("window");
117 fs_changed.Wait();
120 // Depending on the platform, going fullscreen might create an animation.
121 // We want to make sure that the ESC key we will send next is actually going
122 // to be received and the application might not receive key events during the
123 // animation so we should wait for the key focus to be back.
124 WaitUntilKeyFocus();
126 // Same idea as above but for leaving fullscreen. Fullscreen mode should be
127 // left when ESC is received.
129 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
131 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
133 fs_changed.Wait();
137 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenDOM) {
138 // This test is flaky on MacOS 10.6.
139 #if defined(OS_MACOSX)
140 if (base::mac::IsOSSnowLeopard())
141 return;
143 ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
144 #endif
146 ExtensionTestMessageListener launched_listener("Launched", true);
147 LoadAndLaunchPlatformApp("leave_fullscreen", &launched_listener);
149 // We start by making sure the window is actually focused.
150 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
151 GetFirstAppWindow()->GetNativeWindow()));
153 launched_listener.Reply("dom");
155 // Because the DOM way to go fullscreen requires user gesture, we simulate a
156 // key event to get the window entering in fullscreen mode. The reply will
157 // make the window listen for the key event. The reply will be sent to the
158 // renderer process before the keypress and should be received in that order.
159 // When receiving the key event, the application will try to go fullscreen
160 // using the Window API but there is no synchronous way to know if that
161 // actually succeeded. Also, failure will not be notified. A failure case will
162 // only be known with a timeout.
164 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
166 WaitUntilKeyFocus();
167 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
169 fs_changed.Wait();
172 // Depending on the platform, going fullscreen might create an animation.
173 // We want to make sure that the ESC key we will send next is actually going
174 // to be received and the application might not receive key events during the
175 // animation so we should wait for the key focus to be back.
176 WaitUntilKeyFocus();
178 // Same idea as above but for leaving fullscreen. Fullscreen mode should be
179 // left when ESC is received.
181 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
183 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
185 fs_changed.Wait();
189 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
190 ESCDoesNotLeaveFullscreenWindow) {
191 // This test is flaky on MacOS 10.6.
192 #if defined(OS_MACOSX)
193 if (base::mac::IsOSSnowLeopard())
194 return;
196 ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
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)
243 if (base::mac::IsOSSnowLeopard())
244 return;
246 ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
247 #endif
249 ExtensionTestMessageListener launched_listener("Launched", true);
250 LoadAndLaunchPlatformApp("prevent_leave_fullscreen", &launched_listener);
252 // We start by making sure the window is actually focused.
253 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
254 GetFirstAppWindow()->GetNativeWindow()));
256 launched_listener.Reply("dom");
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.
267 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
269 WaitUntilKeyFocus();
270 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_A));
272 fs_changed.Wait();
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();
281 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
283 ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
285 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
287 ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
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());
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)
303 if (base::mac::IsOSSnowLeopard())
304 return;
306 ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
307 #endif
309 ExtensionTestMessageListener launched_listener("Launched", true);
310 LoadAndLaunchPlatformApp("prevent_leave_fullscreen_old", &launched_listener);
312 // We start by making sure the window is actually focused.
313 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
314 GetFirstAppWindow()->GetNativeWindow()));
316 // When receiving the reply, the application will try to go fullscreen using
317 // the Window API but there is no synchronous way to know if that actually
318 // succeeded. Also, failure will not be notified. A failure case will only be
319 // known with a timeout.
321 FullscreenChangeWaiter fs_changed(GetFirstAppWindow()->GetBaseWindow());
323 launched_listener.Reply("window");
325 fs_changed.Wait();
328 // Depending on the platform, going fullscreen might create an animation.
329 // We want to make sure that the ESC key we will send next is actually going
330 // to be received and the application might not receive key events during the
331 // animation so we should wait for the key focus to be back.
332 WaitUntilKeyFocus();
334 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_ESCAPE));
336 ExtensionTestMessageListener second_key_listener("B_KEY_RECEIVED", false);
338 ASSERT_TRUE(SimulateKeyPress(ui::VKEY_B));
340 ASSERT_TRUE(second_key_listener.WaitUntilSatisfied());
342 // We assume that at that point, if we had to leave fullscreen, we should be.
343 // However, by nature, we can not guarantee that and given that we do test
344 // that nothing happens, we might end up with random-success when the feature
345 // is broken.
346 EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
349 #if defined(OS_MACOSX) || defined(OS_WIN)
350 // http://crbug.com/404081
351 #define MAYBE_TestInnerBounds DISABLED_TestInnerBounds
352 #else
353 #define MAYBE_TestInnerBounds TestInnerBounds
354 #endif
355 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestInnerBounds) {
356 ASSERT_TRUE(RunAppWindowInteractiveTest("testInnerBounds")) << message_;
359 void AppWindowInteractiveTest::TestOuterBoundsHelper(
360 const std::string& frame_type) {
361 ExtensionTestMessageListener launched_listener("Launched", true);
362 const extensions::Extension* app =
363 LoadAndLaunchPlatformApp("outer_bounds", &launched_listener);
365 launched_listener.Reply(frame_type);
366 launched_listener.Reset();
367 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
369 AppWindow* window = GetFirstAppWindowForApp(app->id());
370 gfx::Rect window_bounds;
371 gfx::Size min_size, max_size;
373 #if defined(OS_WIN)
374 // Get the bounds from the HWND.
375 HWND hwnd = views::HWNDForNativeWindow(window->GetNativeWindow());
376 RECT rect;
377 ::GetWindowRect(hwnd, &rect);
378 window_bounds = gfx::Rect(
379 rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
381 // HWNDMessageHandler calls this when responding to WM_GETMINMAXSIZE, so it's
382 // the closest to what the window will see.
383 views::HWNDMessageHandlerDelegate* host =
384 static_cast<views::HWNDMessageHandlerDelegate*>(
385 static_cast<views::DesktopWindowTreeHostWin*>(
386 aura::WindowTreeHost::GetForAcceleratedWidget(hwnd)));
387 host->GetMinMaxSize(&min_size, &max_size);
388 // Note that this does not include the the client area insets so we need to
389 // add them.
390 gfx::Insets insets;
391 host->GetClientAreaInsets(&insets);
392 min_size = gfx::Size(min_size.width() + insets.left() + insets.right(),
393 min_size.height() + insets.top() + insets.bottom());
394 max_size = gfx::Size(
395 max_size.width() ? max_size.width() + insets.left() + insets.right() : 0,
396 max_size.height() ? max_size.height() + insets.top() + insets.bottom()
397 : 0);
398 #endif // defined(OS_WIN)
400 // These match the values in the outer_bounds/test.js
401 EXPECT_EQ(gfx::Rect(10, 11, 300, 301), window_bounds);
402 EXPECT_EQ(window->GetBaseWindow()->GetBounds(), window_bounds);
403 EXPECT_EQ(200, min_size.width());
404 EXPECT_EQ(201, min_size.height());
405 EXPECT_EQ(400, max_size.width());
406 EXPECT_EQ(401, max_size.height());
409 // TODO(jackhou): Make this test work for other OSes.
410 #if !defined(OS_WIN)
411 #define MAYBE_TestOuterBoundsFrameChrome DISABLED_TestOuterBoundsFrameChrome
412 #define MAYBE_TestOuterBoundsFrameNone DISABLED_TestOuterBoundsFrameNone
413 #define MAYBE_TestOuterBoundsFrameColor DISABLED_TestOuterBoundsFrameColor
414 #else
415 #define MAYBE_TestOuterBoundsFrameChrome TestOuterBoundsFrameChrome
416 #define MAYBE_TestOuterBoundsFrameNone TestOuterBoundsFrameNone
417 #define MAYBE_TestOuterBoundsFrameColor TestOuterBoundsFrameColor
418 #endif
420 // Test that the outer bounds match that of the native window.
421 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
422 MAYBE_TestOuterBoundsFrameChrome) {
423 TestOuterBoundsHelper("chrome");
425 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
426 MAYBE_TestOuterBoundsFrameNone) {
427 TestOuterBoundsHelper("none");
429 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
430 MAYBE_TestOuterBoundsFrameColor) {
431 TestOuterBoundsHelper("color");
434 // This test does not work on Linux Aura because ShowInactive() is not
435 // implemented. See http://crbug.com/325142
436 // It also does not work on Windows because of the document being focused even
437 // though the window is not activated. See http://crbug.com/326986
438 // It also does not work on MacOS because ::ShowInactive() ends up behaving like
439 // ::Show() because of Cocoa conventions. See http://crbug.com/326987
440 // Those tests should be disabled on Linux GTK when they are enabled on the
441 // other platforms, see http://crbug.com/328829
442 #if (defined(OS_LINUX) && defined(USE_AURA)) || \
443 defined(OS_WIN) || defined(OS_MACOSX)
444 #define MAYBE_TestCreate DISABLED_TestCreate
445 #define MAYBE_TestShow DISABLED_TestShow
446 #else
447 #define MAYBE_TestCreate TestCreate
448 #define MAYBE_TestShow TestShow
449 #endif
451 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestCreate) {
452 ASSERT_TRUE(RunAppWindowInteractiveTest("testCreate")) << message_;
455 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestShow) {
456 ASSERT_TRUE(RunAppWindowInteractiveTest("testShow")) << message_;
459 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, TestDrawAttention) {
460 ASSERT_TRUE(RunAppWindowInteractiveTest("testDrawAttention")) << message_;
463 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, TestCreateHidden) {
464 // Created hidden both times.
466 ExtensionTestMessageListener launched_listener("Launched", true);
467 LoadAndLaunchPlatformApp("hidden_with_id", &launched_listener);
468 EXPECT_TRUE(launched_listener.WaitUntilSatisfied());
469 ExtensionTestMessageListener create_listener_1("Launched", true);
470 launched_listener.Reply("createHidden");
471 EXPECT_TRUE(create_listener_1.WaitUntilSatisfied());
472 AppWindow* app_window = GetFirstAppWindow();
473 EXPECT_TRUE(app_window->is_hidden());
474 ExtensionTestMessageListener create_listener_2("Launched", false);
475 create_listener_1.Reply("createHidden");
476 EXPECT_TRUE(create_listener_2.WaitUntilSatisfied());
477 EXPECT_TRUE(app_window->is_hidden());
478 app_window->GetBaseWindow()->Close();
481 // Created hidden, then visible. The second create should show the window.
483 ExtensionTestMessageListener launched_listener("Launched", true);
484 LoadAndLaunchPlatformApp("hidden_with_id", &launched_listener);
485 EXPECT_TRUE(launched_listener.WaitUntilSatisfied());
486 ExtensionTestMessageListener create_listener_1("Launched", true);
487 launched_listener.Reply("createHidden");
488 EXPECT_TRUE(create_listener_1.WaitUntilSatisfied());
489 AppWindow* app_window = GetFirstAppWindow();
490 EXPECT_TRUE(app_window->is_hidden());
491 ExtensionTestMessageListener create_listener_2("Launched", false);
492 create_listener_1.Reply("createVisible");
493 EXPECT_TRUE(create_listener_2.WaitUntilSatisfied());
494 EXPECT_FALSE(app_window->is_hidden());
495 app_window->GetBaseWindow()->Close();
499 #if defined(OS_MACOSX)
500 // http://crbug.com/502516
501 #define MAYBE_TestFullscreen DISABLED_TestFullscreen
502 #else
503 #define MAYBE_TestFullscreen TestFullscreen
504 #endif
505 IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, MAYBE_TestFullscreen) {
506 ASSERT_TRUE(RunAppWindowInteractiveTest("testFullscreen")) << message_;
509 // Only Linux and Windows use keep-alive to determine when to shut down.
510 #if defined(OS_LINUX) || defined(OS_WIN)
512 // In general, hidden windows should not keep Chrome alive. The exception is
513 // when windows are created hidden, we allow the app some time to show the
514 // the window.
515 class AppWindowHiddenKeepAliveTest : public extensions::PlatformAppBrowserTest {
516 protected:
517 AppWindowHiddenKeepAliveTest() {}
519 private:
520 DISALLOW_COPY_AND_ASSIGN(AppWindowHiddenKeepAliveTest);
523 // A window that becomes hidden should not keep Chrome alive.
524 IN_PROC_BROWSER_TEST_F(AppWindowHiddenKeepAliveTest, ShownThenHidden) {
525 LoadAndLaunchPlatformApp("minimal", "Launched");
526 for (chrome::BrowserIterator it; !it.done(); it.Next())
527 it->window()->Close();
529 EXPECT_TRUE(chrome::WillKeepAlive());
530 GetFirstAppWindow()->Hide();
531 EXPECT_FALSE(chrome::WillKeepAlive());
534 // A window that is hidden but re-shown should still keep Chrome alive.
535 IN_PROC_BROWSER_TEST_F(AppWindowHiddenKeepAliveTest, ShownThenHiddenThenShown) {
536 LoadAndLaunchPlatformApp("minimal", "Launched");
537 AppWindow* app_window = GetFirstAppWindow();
538 app_window->Hide();
539 app_window->Show(AppWindow::SHOW_ACTIVE);
541 EXPECT_TRUE(chrome::WillKeepAlive());
542 for (chrome::BrowserIterator it; !it.done(); it.Next())
543 it->window()->Close();
544 EXPECT_TRUE(chrome::WillKeepAlive());
545 app_window->GetBaseWindow()->Close();
548 // A window that is created hidden and stays hidden should not keep Chrome
549 // alive.
550 IN_PROC_BROWSER_TEST_F(AppWindowHiddenKeepAliveTest, StaysHidden) {
551 LoadAndLaunchPlatformApp("hidden", "Launched");
552 AppWindow* app_window = GetFirstAppWindow();
553 EXPECT_TRUE(app_window->is_hidden());
555 for (chrome::BrowserIterator it; !it.done(); it.Next())
556 it->window()->Close();
557 // This will time out if the command above does not terminate Chrome.
558 content::RunMessageLoop();
561 // A window that is created hidden but shown soon after should keep Chrome
562 // alive.
563 IN_PROC_BROWSER_TEST_F(AppWindowHiddenKeepAliveTest, HiddenThenShown) {
564 ExtensionTestMessageListener launched_listener("Launched", true);
565 LoadAndLaunchPlatformApp("hidden_then_shown", &launched_listener);
566 AppWindow* app_window = GetFirstAppWindow();
567 EXPECT_TRUE(app_window->is_hidden());
569 // Close all browser windows.
570 for (chrome::BrowserIterator it; !it.done(); it.Next())
571 it->window()->Close();
573 // The app window will show after 3 seconds.
574 ExtensionTestMessageListener shown_listener("Shown", false);
575 launched_listener.Reply("");
576 EXPECT_TRUE(shown_listener.WaitUntilSatisfied());
577 EXPECT_FALSE(app_window->is_hidden());
578 EXPECT_TRUE(chrome::WillKeepAlive());
579 app_window->GetBaseWindow()->Close();
582 #endif