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/browser/profiles/profile.h"
8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/extensions/application_launch.h"
10 #include "content/public/browser/notification_service.h"
11 #include "content/public/test/test_utils.h"
12 #include "extensions/browser/app_window/app_window_geometry_cache.h"
13 #include "extensions/common/constants.h"
14 #include "extensions/common/extension.h"
16 using extensions::AppWindowGeometryCache
;
18 // This helper class can be used to wait for changes in the app window
19 // geometry cache registry for a specific window in a specific extension.
20 class GeometryCacheChangeHelper
: AppWindowGeometryCache::Observer
{
22 GeometryCacheChangeHelper(AppWindowGeometryCache
* cache
,
23 const std::string
& extension_id
,
24 const std::string
& window_id
,
25 const gfx::Rect
& bounds
)
27 extension_id_(extension_id
),
28 window_id_(window_id
),
32 cache_
->AddObserver(this);
35 // This method will block until the app window geometry cache registry will
36 // provide a bound for |window_id_| that is entirely different (as in x/y/w/h)
37 // from the initial |bounds_|.
38 void WaitForEntirelyChanged() {
43 content::RunMessageLoop();
46 // Implements the content::NotificationObserver interface.
47 virtual void OnGeometryCacheChanged(const std::string
& extension_id
,
48 const std::string
& window_id
,
49 const gfx::Rect
& bounds
)
51 if (extension_id
!= extension_id_
|| window_id
!= window_id_
)
54 if (bounds_
.x() != bounds
.x() &&
55 bounds_
.y() != bounds
.y() &&
56 bounds_
.width() != bounds
.width() &&
57 bounds_
.height() != bounds
.height()) {
59 cache_
->RemoveObserver(this);
62 base::MessageLoopForUI::current()->Quit();
67 AppWindowGeometryCache
* cache_
;
68 std::string extension_id_
;
69 std::string window_id_
;
75 // Helper class for tests related to the Apps Window API (chrome.app.window).
76 class AppWindowAPITest
: public extensions::PlatformAppBrowserTest
{
78 bool RunAppWindowAPITest(const char* testName
) {
79 if (!BeginAppWindowAPITest(testName
))
82 ResultCatcher catcher
;
83 if (!catcher
.GetNextResult()) {
84 message_
= catcher
.message();
91 bool RunAppWindowAPITestAndWaitForRoundTrip(const char* testName
) {
92 if (!BeginAppWindowAPITest(testName
))
95 ExtensionTestMessageListener
round_trip_listener("WaitForRoundTrip", true);
96 if (!round_trip_listener
.WaitUntilSatisfied()) {
97 message_
= "Did not get the 'WaitForRoundTrip' message.";
101 round_trip_listener
.Reply("");
103 ResultCatcher catcher
;
104 if (!catcher
.GetNextResult()) {
105 message_
= catcher
.message();
113 bool BeginAppWindowAPITest(const char* testName
) {
114 ExtensionTestMessageListener
launched_listener("Launched", true);
115 LoadAndLaunchPlatformApp("window_api", &launched_listener
);
116 if (!launched_listener
.WaitUntilSatisfied()) {
117 message_
= "Did not get the 'Launched' message.";
121 launched_listener
.Reply(testName
);
126 // These tests are flaky after https://codereview.chromium.org/57433010/.
127 // See http://crbug.com/319613.
129 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestCreate
) {
130 ASSERT_TRUE(RunAppWindowAPITest("testCreate")) << message_
;
133 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestSingleton
) {
134 ASSERT_TRUE(RunAppWindowAPITest("testSingleton")) << message_
;
137 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestCloseEvent
) {
138 ASSERT_TRUE(RunAppWindowAPITest("testCloseEvent")) << message_
;
141 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, DISABLED_TestMaximize
) {
142 ASSERT_TRUE(RunAppWindowAPITest("testMaximize")) << message_
;
145 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, DISABLED_TestRestore
) {
146 ASSERT_TRUE(RunAppWindowAPITest("testRestore")) << message_
;
149 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, DISABLED_TestRestoreAfterClose
) {
150 ASSERT_TRUE(RunAppWindowAPITest("testRestoreAfterClose")) << message_
;
153 // These tests will be flaky in Linux as window bounds change asynchronously.
154 #if defined(OS_LINUX)
155 #define MAYBE_TestDeprecatedBounds DISABLED_TestDeprecatedBounds
156 #define MAYBE_TestInitialBounds DISABLED_TestInitialBounds
157 #define MAYBE_TestInitialConstraints DISABLED_TestInitialConstraints
158 #define MAYBE_TestSetBounds DISABLED_TestSetBounds
159 #define MAYBE_TestSetSizeConstraints DISABLED_TestSetSizeConstraints
161 #define MAYBE_TestDeprecatedBounds TestDeprecatedBounds
162 #define MAYBE_TestInitialBounds TestInitialBounds
163 #define MAYBE_TestInitialConstraints TestInitialConstraints
164 #define MAYBE_TestSetBounds TestSetBounds
165 #define MAYBE_TestSetSizeConstraints TestSetSizeConstraints
168 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestDeprecatedBounds
) {
169 ASSERT_TRUE(RunAppWindowAPITest("testDeprecatedBounds")) << message_
;
172 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestInitialBounds
) {
173 ASSERT_TRUE(RunAppWindowAPITest("testInitialBounds")) << message_
;
176 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestInitialConstraints
) {
177 ASSERT_TRUE(RunAppWindowAPITest("testInitialConstraints")) << message_
;
180 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestSetBounds
) {
181 ASSERT_TRUE(RunAppWindowAPITest("testSetBounds")) << message_
;
184 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestSetSizeConstraints
) {
185 ASSERT_TRUE(RunAppWindowAPITest("testSetSizeConstraints")) << message_
;
188 // Flaky failures on mac_rel and WinXP, see http://crbug.com/324915.
189 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
,
190 DISABLED_TestRestoreGeometryCacheChange
) {
191 // This test is similar to the other AppWindowAPI tests except that at some
192 // point the app will send a 'ListenGeometryChange' message at which point the
193 // test will check if the geometry cache entry for the test window has
194 // changed. When the change happens, the test will let the app know so it can
196 ExtensionTestMessageListener
launched_listener("Launched", true);
198 content::WindowedNotificationObserver
app_loaded_observer(
199 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
,
200 content::NotificationService::AllSources());
202 const extensions::Extension
* extension
= LoadExtension(
203 test_data_dir_
.AppendASCII("platform_apps").AppendASCII("window_api"));
204 EXPECT_TRUE(extension
);
206 OpenApplication(AppLaunchParams(browser()->profile(),
208 extensions::LAUNCH_CONTAINER_NONE
,
211 ExtensionTestMessageListener
geometry_listener("ListenGeometryChange", true);
213 ASSERT_TRUE(launched_listener
.WaitUntilSatisfied());
214 launched_listener
.Reply("testRestoreAfterGeometryCacheChange");
216 ASSERT_TRUE(geometry_listener
.WaitUntilSatisfied());
218 GeometryCacheChangeHelper
geo_change_helper_1(
219 AppWindowGeometryCache::Get(browser()->profile()),
221 // The next line has information that has to stay in sync with the app.
223 gfx::Rect(200, 200, 200, 200));
225 GeometryCacheChangeHelper
geo_change_helper_2(
226 AppWindowGeometryCache::Get(browser()->profile()),
228 // The next line has information that has to stay in sync with the app.
230 gfx::Rect(200, 200, 200, 200));
232 // These calls will block until the app window geometry cache will change.
233 geo_change_helper_1
.WaitForEntirelyChanged();
234 geo_change_helper_2
.WaitForEntirelyChanged();
236 ResultCatcher catcher
;
237 geometry_listener
.Reply("");
238 ASSERT_TRUE(catcher
.GetNextResult());
241 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestBadging
) {
243 RunAppWindowAPITestAndWaitForRoundTrip("testBadging")) << message_
;
246 // TODO(benwells): Implement on Mac.
247 #if defined(USE_AURA)
248 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestFrameColors
) {
249 ASSERT_TRUE(RunAppWindowAPITest("testFrameColors")) << message_
;
252 // TODO(benwells): Remove this test once all the things are merged together. It
253 // is currently present as this feature was previously disabled on stable
254 // channel, so the test is to ensure it has all been re-enabled properly.
255 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestFrameColorsInStable
) {
256 extensions::ScopedCurrentChannel
channel(chrome::VersionInfo::CHANNEL_STABLE
);
257 ASSERT_TRUE(RunAppWindowAPITest("testFrameColors")) << message_
;