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/profiles/profile.h"
7 #include "chrome/browser/ui/browser.h"
8 #include "chrome/browser/ui/extensions/app_launch_params.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"
15 #include "extensions/test/extension_test_message_listener.h"
16 #include "extensions/test/result_catcher.h"
18 using extensions::AppWindowGeometryCache
;
19 using extensions::ResultCatcher
;
21 // This helper class can be used to wait for changes in the app window
22 // geometry cache registry for a specific window in a specific extension.
23 class GeometryCacheChangeHelper
: AppWindowGeometryCache::Observer
{
25 GeometryCacheChangeHelper(AppWindowGeometryCache
* cache
,
26 const std::string
& extension_id
,
27 const std::string
& window_id
,
28 const gfx::Rect
& bounds
)
30 extension_id_(extension_id
),
31 window_id_(window_id
),
35 cache_
->AddObserver(this);
38 // This method will block until the app window geometry cache registry will
39 // provide a bound for |window_id_| that is entirely different (as in x/y/w/h)
40 // from the initial |bounds_|.
41 void WaitForEntirelyChanged() {
46 content::RunMessageLoop();
49 // Implements the content::NotificationObserver interface.
50 void OnGeometryCacheChanged(const std::string
& extension_id
,
51 const std::string
& window_id
,
52 const gfx::Rect
& bounds
) override
{
53 if (extension_id
!= extension_id_
|| window_id
!= window_id_
)
56 if (bounds_
.x() != bounds
.x() &&
57 bounds_
.y() != bounds
.y() &&
58 bounds_
.width() != bounds
.width() &&
59 bounds_
.height() != bounds
.height()) {
61 cache_
->RemoveObserver(this);
64 base::MessageLoopForUI::current()->Quit();
69 AppWindowGeometryCache
* cache_
;
70 std::string extension_id_
;
71 std::string window_id_
;
77 // Helper class for tests related to the Apps Window API (chrome.app.window).
78 class AppWindowAPITest
: public extensions::PlatformAppBrowserTest
{
80 bool RunAppWindowAPITest(const char* testName
) {
81 if (!BeginAppWindowAPITest(testName
))
84 ResultCatcher catcher
;
85 if (!catcher
.GetNextResult()) {
86 message_
= catcher
.message();
93 bool RunAppWindowAPITestAndWaitForRoundTrip(const char* testName
) {
94 if (!BeginAppWindowAPITest(testName
))
97 ExtensionTestMessageListener
round_trip_listener("WaitForRoundTrip", true);
98 if (!round_trip_listener
.WaitUntilSatisfied()) {
99 message_
= "Did not get the 'WaitForRoundTrip' message.";
103 round_trip_listener
.Reply("");
105 ResultCatcher catcher
;
106 if (!catcher
.GetNextResult()) {
107 message_
= catcher
.message();
115 bool BeginAppWindowAPITest(const char* testName
) {
116 ExtensionTestMessageListener
launched_listener("Launched", true);
117 LoadAndLaunchPlatformApp("window_api", &launched_listener
);
118 if (!launched_listener
.WaitUntilSatisfied()) {
119 message_
= "Did not get the 'Launched' message.";
123 launched_listener
.Reply(testName
);
128 // These tests are flaky after https://codereview.chromium.org/57433010/.
129 // See http://crbug.com/319613.
131 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestCreate
) {
132 ASSERT_TRUE(RunAppWindowAPITest("testCreate")) << message_
;
135 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestSingleton
) {
136 ASSERT_TRUE(RunAppWindowAPITest("testSingleton")) << message_
;
139 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestCloseEvent
) {
140 ASSERT_TRUE(RunAppWindowAPITest("testCloseEvent")) << message_
;
143 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, DISABLED_TestMaximize
) {
144 ASSERT_TRUE(RunAppWindowAPITest("testMaximize")) << message_
;
147 // Flaky on Linux. http://crbug.com/424399.
148 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
149 #define MAYBE_TestMinimize DISABLED_TestMinimize
151 #define MAYBE_TestMinimize TestMinimize
154 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestMinimize
) {
155 ASSERT_TRUE(RunAppWindowAPITest("testMinimize")) << message_
;
158 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, DISABLED_TestRestore
) {
159 ASSERT_TRUE(RunAppWindowAPITest("testRestore")) << message_
;
162 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, DISABLED_TestRestoreAfterClose
) {
163 ASSERT_TRUE(RunAppWindowAPITest("testRestoreAfterClose")) << message_
;
166 // These tests will be flaky in Linux as window bounds change asynchronously.
167 #if defined(OS_LINUX)
168 #define MAYBE_TestDeprecatedBounds DISABLED_TestDeprecatedBounds
169 #define MAYBE_TestInitialBounds DISABLED_TestInitialBounds
170 #define MAYBE_TestInitialConstraints DISABLED_TestInitialConstraints
171 #define MAYBE_TestSetBounds DISABLED_TestSetBounds
172 #define MAYBE_TestSetSizeConstraints DISABLED_TestSetSizeConstraints
174 #define MAYBE_TestDeprecatedBounds TestDeprecatedBounds
175 #define MAYBE_TestInitialBounds TestInitialBounds
176 #define MAYBE_TestInitialConstraints TestInitialConstraints
177 #define MAYBE_TestSetBounds TestSetBounds
178 // Disabled as flakey, see http://crbug.com/434532 for details.
179 #define MAYBE_TestSetSizeConstraints DISABLED_TestSetSizeConstraints
182 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestDeprecatedBounds
) {
183 ASSERT_TRUE(RunAppWindowAPITest("testDeprecatedBounds")) << message_
;
186 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestInitialBounds
) {
187 ASSERT_TRUE(RunAppWindowAPITest("testInitialBounds")) << message_
;
190 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestInitialConstraints
) {
191 ASSERT_TRUE(RunAppWindowAPITest("testInitialConstraints")) << message_
;
194 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestSetBounds
) {
195 ASSERT_TRUE(RunAppWindowAPITest("testSetBounds")) << message_
;
198 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, MAYBE_TestSetSizeConstraints
) {
199 ASSERT_TRUE(RunAppWindowAPITest("testSetSizeConstraints")) << message_
;
202 // Flaky failures on mac_rel and WinXP, see http://crbug.com/324915.
203 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
,
204 DISABLED_TestRestoreGeometryCacheChange
) {
205 // This test is similar to the other AppWindowAPI tests except that at some
206 // point the app will send a 'ListenGeometryChange' message at which point the
207 // test will check if the geometry cache entry for the test window has
208 // changed. When the change happens, the test will let the app know so it can
210 ExtensionTestMessageListener
launched_listener("Launched", true);
212 content::WindowedNotificationObserver
app_loaded_observer(
213 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME
,
214 content::NotificationService::AllSources());
216 const extensions::Extension
* extension
= LoadExtension(
217 test_data_dir_
.AppendASCII("platform_apps").AppendASCII("window_api"));
218 EXPECT_TRUE(extension
);
220 OpenApplication(AppLaunchParams(browser()->profile(), extension
,
221 extensions::LAUNCH_CONTAINER_NONE
, NEW_WINDOW
,
222 extensions::SOURCE_TEST
));
224 ExtensionTestMessageListener
geometry_listener("ListenGeometryChange", true);
226 ASSERT_TRUE(launched_listener
.WaitUntilSatisfied());
227 launched_listener
.Reply("testRestoreAfterGeometryCacheChange");
229 ASSERT_TRUE(geometry_listener
.WaitUntilSatisfied());
231 GeometryCacheChangeHelper
geo_change_helper_1(
232 AppWindowGeometryCache::Get(browser()->profile()),
234 // The next line has information that has to stay in sync with the app.
236 gfx::Rect(200, 200, 200, 200));
238 GeometryCacheChangeHelper
geo_change_helper_2(
239 AppWindowGeometryCache::Get(browser()->profile()),
241 // The next line has information that has to stay in sync with the app.
243 gfx::Rect(200, 200, 200, 200));
245 // These calls will block until the app window geometry cache will change.
246 geo_change_helper_1
.WaitForEntirelyChanged();
247 geo_change_helper_2
.WaitForEntirelyChanged();
249 ResultCatcher catcher
;
250 geometry_listener
.Reply("");
251 ASSERT_TRUE(catcher
.GetNextResult());
254 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestBadging
) {
256 RunAppWindowAPITestAndWaitForRoundTrip("testBadging")) << message_
;
259 // TODO(benwells): Implement on Mac.
260 #if defined(USE_AURA)
261 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestFrameColors
) {
262 ASSERT_TRUE(RunAppWindowAPITest("testFrameColors")) << message_
;
266 IN_PROC_BROWSER_TEST_F(AppWindowAPITest
, TestVisibleOnAllWorkspaces
) {
268 RunAppWindowAPITestAndWaitForRoundTrip("testVisibleOnAllWorkspaces"))