1 // Copyright (c) 2012 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.
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/pattern.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/values.h"
16 #include "chrome/browser/devtools/devtools_window_testing.h"
17 #include "chrome/browser/extensions/api/tabs/tabs_api.h"
18 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
19 #include "chrome/browser/extensions/extension_function_test_utils.h"
20 #include "chrome/browser/extensions/extension_tab_util.h"
21 #include "chrome/browser/prefs/incognito_mode_prefs.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_commands.h"
25 #include "chrome/browser/ui/browser_window.h"
26 #include "chrome/browser/ui/tabs/tab_strip_model.h"
27 #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
28 #include "chrome/test/base/in_process_browser_test.h"
29 #include "chrome/test/base/ui_test_utils.h"
30 #include "content/public/browser/browser_context.h"
31 #include "content/public/browser/storage_partition.h"
32 #include "content/public/common/page_zoom.h"
33 #include "content/public/common/url_constants.h"
34 #include "extensions/browser/api_test_utils.h"
35 #include "extensions/common/manifest_constants.h"
36 #include "extensions/common/test_util.h"
37 #include "net/test/spawned_test_server/spawned_test_server.h"
38 #include "ui/gfx/geometry/rect.h"
40 namespace extensions
{
42 namespace keys
= tabs_constants
;
43 namespace utils
= extension_function_test_utils
;
46 using ExtensionTabsTest
= InProcessBrowserTest
;
48 class ExtensionWindowCreateTest
: public InProcessBrowserTest
{
50 // Runs chrome.windows.create(), expecting an error.
51 std::string
RunCreateWindowExpectError(const std::string
& args
) {
52 scoped_refptr
<WindowsCreateFunction
> function(new WindowsCreateFunction
);
53 function
->set_extension(test_util::CreateEmptyExtension().get());
54 return api_test_utils::RunFunctionAndReturnError(function
.get(), args
,
55 browser()->profile());
61 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, GetWindow
) {
62 int window_id
= ExtensionTabUtil::GetWindowId(browser());
64 // Invalid window ID error.
65 scoped_refptr
<WindowsGetFunction
> function
= new WindowsGetFunction();
66 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
67 function
->set_extension(extension
.get());
68 EXPECT_TRUE(base::MatchPattern(
69 utils::RunFunctionAndReturnError(
70 function
.get(), base::StringPrintf("[%u]", window_id
+ 1), browser()),
71 keys::kWindowNotFoundError
));
73 // Basic window details.
75 if (browser()->window()->IsMinimized())
76 bounds
= browser()->window()->GetRestoredBounds();
78 bounds
= browser()->window()->GetBounds();
80 function
= new WindowsGetFunction();
81 function
->set_extension(extension
.get());
82 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
83 utils::RunFunctionAndReturnSingleResult(
85 base::StringPrintf("[%u]", window_id
),
87 EXPECT_EQ(window_id
, api_test_utils::GetInteger(result
.get(), "id"));
88 EXPECT_FALSE(api_test_utils::GetBoolean(result
.get(), "incognito"));
89 EXPECT_EQ("normal", api_test_utils::GetString(result
.get(), "type"));
90 EXPECT_EQ(bounds
.x(), api_test_utils::GetInteger(result
.get(), "left"));
91 EXPECT_EQ(bounds
.y(), api_test_utils::GetInteger(result
.get(), "top"));
92 EXPECT_EQ(bounds
.width(), api_test_utils::GetInteger(result
.get(), "width"));
93 EXPECT_EQ(bounds
.height(),
94 api_test_utils::GetInteger(result
.get(), "height"));
96 // With "populate" enabled.
97 function
= new WindowsGetFunction();
98 function
->set_extension(extension
.get());
99 result
.reset(utils::ToDictionary(
100 utils::RunFunctionAndReturnSingleResult(
102 base::StringPrintf("[%u, {\"populate\": true}]", window_id
),
105 EXPECT_EQ(window_id
, api_test_utils::GetInteger(result
.get(), "id"));
106 // "populate" was enabled so tabs should be populated.
107 base::ListValue
* tabs
= NULL
;
108 EXPECT_TRUE(result
.get()->GetList(keys::kTabsKey
, &tabs
));
110 // TODO(aa): Can't assume window is focused. On mac, calling Activate() from a
111 // browser test doesn't seem to do anything, so can't test the opposite
113 EXPECT_EQ(browser()->window()->IsActive(),
114 api_test_utils::GetBoolean(result
.get(), "focused"));
116 // TODO(aa): Minimized and maximized dimensions. Is there a way to set
117 // minimize/maximize programmatically?
120 Browser
* popup_browser
= new Browser(
121 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
122 browser()->host_desktop_type()));
123 function
= new WindowsGetFunction();
124 function
->set_extension(extension
.get());
125 result
.reset(utils::ToDictionary(
126 utils::RunFunctionAndReturnSingleResult(
129 "[%u]", ExtensionTabUtil::GetWindowId(popup_browser
)),
131 EXPECT_EQ("popup", api_test_utils::GetString(result
.get(), "type"));
134 Browser
* incognito_browser
= CreateIncognitoBrowser();
135 int incognito_window_id
= ExtensionTabUtil::GetWindowId(incognito_browser
);
137 // Without "include_incognito".
138 function
= new WindowsGetFunction();
139 function
->set_extension(extension
.get());
140 EXPECT_TRUE(base::MatchPattern(
141 utils::RunFunctionAndReturnError(
142 function
.get(), base::StringPrintf("[%u]", incognito_window_id
),
144 keys::kWindowNotFoundError
));
146 // With "include_incognito".
147 function
= new WindowsGetFunction();
148 function
->set_extension(extension
.get());
149 result
.reset(utils::ToDictionary(
150 utils::RunFunctionAndReturnSingleResult(
152 base::StringPrintf("[%u]", incognito_window_id
),
154 utils::INCLUDE_INCOGNITO
)));
155 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
158 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, GetCurrentWindow
) {
159 int window_id
= ExtensionTabUtil::GetWindowId(browser());
160 Browser
* new_browser
= CreateBrowser(browser()->profile());
161 int new_id
= ExtensionTabUtil::GetWindowId(new_browser
);
163 // Get the current window using new_browser.
164 scoped_refptr
<WindowsGetCurrentFunction
> function
=
165 new WindowsGetCurrentFunction();
166 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
167 function
->set_extension(extension
.get());
168 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
169 utils::RunFunctionAndReturnSingleResult(function
.get(),
173 // The id should match the window id of the browser instance that was passed
174 // to RunFunctionAndReturnSingleResult.
175 EXPECT_EQ(new_id
, api_test_utils::GetInteger(result
.get(), "id"));
176 base::ListValue
* tabs
= NULL
;
177 EXPECT_FALSE(result
.get()->GetList(keys::kTabsKey
, &tabs
));
179 // Get the current window using the old window and make the tabs populated.
180 function
= new WindowsGetCurrentFunction();
181 function
->set_extension(extension
.get());
182 result
.reset(utils::ToDictionary(
183 utils::RunFunctionAndReturnSingleResult(function
.get(),
184 "[{\"populate\": true}]",
187 // The id should match the window id of the browser instance that was passed
188 // to RunFunctionAndReturnSingleResult.
189 EXPECT_EQ(window_id
, api_test_utils::GetInteger(result
.get(), "id"));
190 // "populate" was enabled so tabs should be populated.
191 EXPECT_TRUE(result
.get()->GetList(keys::kTabsKey
, &tabs
));
194 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, GetAllWindows
) {
195 const size_t NUM_WINDOWS
= 5;
196 std::set
<int> window_ids
;
197 std::set
<int> result_ids
;
198 window_ids
.insert(ExtensionTabUtil::GetWindowId(browser()));
200 for (size_t i
= 0; i
< NUM_WINDOWS
- 1; ++i
) {
201 Browser
* new_browser
= CreateBrowser(browser()->profile());
202 window_ids
.insert(ExtensionTabUtil::GetWindowId(new_browser
));
205 // Undocked DevTools window should not be accessible.
206 DevToolsWindow
* devtools
= DevToolsWindowTesting::OpenDevToolsWindowSync(
207 browser()->tab_strip_model()->GetWebContentsAt(0), false /* is_docked */);
209 scoped_refptr
<WindowsGetAllFunction
> function
= new WindowsGetAllFunction();
210 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
211 function
->set_extension(extension
.get());
212 scoped_ptr
<base::ListValue
> result(utils::ToList(
213 utils::RunFunctionAndReturnSingleResult(function
.get(),
217 base::ListValue
* windows
= result
.get();
218 EXPECT_EQ(NUM_WINDOWS
, windows
->GetSize());
219 for (size_t i
= 0; i
< NUM_WINDOWS
; ++i
) {
220 base::DictionaryValue
* result_window
= NULL
;
221 EXPECT_TRUE(windows
->GetDictionary(i
, &result_window
));
222 result_ids
.insert(api_test_utils::GetInteger(result_window
, "id"));
224 // "populate" was not passed in so tabs are not populated.
225 base::ListValue
* tabs
= NULL
;
226 EXPECT_FALSE(result_window
->GetList(keys::kTabsKey
, &tabs
));
228 // The returned ids should contain all the current browser instance ids.
229 EXPECT_EQ(window_ids
, result_ids
);
232 function
= new WindowsGetAllFunction();
233 function
->set_extension(extension
.get());
234 result
.reset(utils::ToList(
235 utils::RunFunctionAndReturnSingleResult(function
.get(),
236 "[{\"populate\": true}]",
239 windows
= result
.get();
240 EXPECT_EQ(NUM_WINDOWS
, windows
->GetSize());
241 for (size_t i
= 0; i
< windows
->GetSize(); ++i
) {
242 base::DictionaryValue
* result_window
= NULL
;
243 EXPECT_TRUE(windows
->GetDictionary(i
, &result_window
));
244 result_ids
.insert(api_test_utils::GetInteger(result_window
, "id"));
246 // "populate" was enabled so tabs should be populated.
247 base::ListValue
* tabs
= NULL
;
248 EXPECT_TRUE(result_window
->GetList(keys::kTabsKey
, &tabs
));
250 // The returned ids should contain all the current browser instance ids.
251 EXPECT_EQ(window_ids
, result_ids
);
253 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools
);
256 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, UpdateNoPermissions
) {
257 // The test empty extension has no permissions, therefore it should not get
258 // tab data in the function result.
259 scoped_refptr
<TabsUpdateFunction
> update_tab_function(
260 new TabsUpdateFunction());
261 scoped_refptr
<Extension
> empty_extension(test_util::CreateEmptyExtension());
262 update_tab_function
->set_extension(empty_extension
.get());
263 // Without a callback the function will not generate a result.
264 update_tab_function
->set_has_callback(true);
266 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
267 utils::RunFunctionAndReturnSingleResult(
268 update_tab_function
.get(),
269 "[null, {\"url\": \"about:blank\", \"pinned\": true}]",
271 // The url is stripped since the extension does not have tab permissions.
272 EXPECT_FALSE(result
->HasKey("url"));
273 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "pinned"));
276 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
,
277 DefaultToIncognitoWhenItIsForced
) {
278 static const char kArgsWithoutExplicitIncognitoParam
[] =
279 "[{\"url\": \"about:blank\"}]";
280 // Force Incognito mode.
281 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
282 IncognitoModePrefs::FORCED
);
283 // Run without an explicit "incognito" param.
284 scoped_refptr
<WindowsCreateFunction
> function(new WindowsCreateFunction());
285 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
286 function
->set_extension(extension
.get());
287 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
288 utils::RunFunctionAndReturnSingleResult(
290 kArgsWithoutExplicitIncognitoParam
,
292 utils::INCLUDE_INCOGNITO
)));
294 // Make sure it is a new(different) window.
295 EXPECT_NE(ExtensionTabUtil::GetWindowId(browser()),
296 api_test_utils::GetInteger(result
.get(), "id"));
297 // ... and it is incognito.
298 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
300 // Now try creating a window from incognito window.
301 Browser
* incognito_browser
= CreateIncognitoBrowser();
302 // Run without an explicit "incognito" param.
303 function
= new WindowsCreateFunction();
304 function
->set_extension(extension
.get());
305 result
.reset(utils::ToDictionary(
306 utils::RunFunctionAndReturnSingleResult(
308 kArgsWithoutExplicitIncognitoParam
,
310 utils::INCLUDE_INCOGNITO
)));
311 // Make sure it is a new(different) window.
312 EXPECT_NE(ExtensionTabUtil::GetWindowId(incognito_browser
),
313 api_test_utils::GetInteger(result
.get(), "id"));
314 // ... and it is incognito.
315 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
318 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
,
319 DefaultToIncognitoWhenItIsForcedAndNoArgs
) {
320 static const char kEmptyArgs
[] = "[]";
321 // Force Incognito mode.
322 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
323 IncognitoModePrefs::FORCED
);
324 // Run without an explicit "incognito" param.
325 scoped_refptr
<WindowsCreateFunction
> function
= new WindowsCreateFunction();
326 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
327 function
->set_extension(extension
.get());
328 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
329 utils::RunFunctionAndReturnSingleResult(function
.get(),
332 utils::INCLUDE_INCOGNITO
)));
334 // Make sure it is a new(different) window.
335 EXPECT_NE(ExtensionTabUtil::GetWindowId(browser()),
336 api_test_utils::GetInteger(result
.get(), "id"));
337 // ... and it is incognito.
338 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
340 // Now try creating a window from incognito window.
341 Browser
* incognito_browser
= CreateIncognitoBrowser();
342 // Run without an explicit "incognito" param.
343 function
= new WindowsCreateFunction();
344 function
->set_extension(extension
.get());
345 result
.reset(utils::ToDictionary(
346 utils::RunFunctionAndReturnSingleResult(function
.get(),
349 utils::INCLUDE_INCOGNITO
)));
350 // Make sure it is a new(different) window.
351 EXPECT_NE(ExtensionTabUtil::GetWindowId(incognito_browser
),
352 api_test_utils::GetInteger(result
.get(), "id"));
353 // ... and it is incognito.
354 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
357 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
,
358 DontCreateNormalWindowWhenIncognitoForced
) {
359 static const char kArgsWithExplicitIncognitoParam
[] =
360 "[{\"url\": \"about:blank\", \"incognito\": false }]";
361 // Force Incognito mode.
362 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
363 IncognitoModePrefs::FORCED
);
365 // Run with an explicit "incognito" param.
366 scoped_refptr
<WindowsCreateFunction
> function
= new WindowsCreateFunction();
367 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
368 function
->set_extension(extension
.get());
369 EXPECT_TRUE(base::MatchPattern(
370 utils::RunFunctionAndReturnError(
371 function
.get(), kArgsWithExplicitIncognitoParam
, browser()),
372 keys::kIncognitoModeIsForced
));
374 // Now try opening a normal window from incognito window.
375 Browser
* incognito_browser
= CreateIncognitoBrowser();
376 // Run with an explicit "incognito" param.
377 function
= new WindowsCreateFunction();
378 function
->set_extension(extension
.get());
379 EXPECT_TRUE(base::MatchPattern(
380 utils::RunFunctionAndReturnError(
381 function
.get(), kArgsWithExplicitIncognitoParam
, incognito_browser
),
382 keys::kIncognitoModeIsForced
));
385 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
,
386 DontCreateIncognitoWindowWhenIncognitoDisabled
) {
387 static const char kArgs
[] =
388 "[{\"url\": \"about:blank\", \"incognito\": true }]";
390 Browser
* incognito_browser
= CreateIncognitoBrowser();
391 // Disable Incognito mode.
392 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
393 IncognitoModePrefs::DISABLED
);
394 // Run in normal window.
395 scoped_refptr
<WindowsCreateFunction
> function
= new WindowsCreateFunction();
396 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
397 function
->set_extension(extension
.get());
398 EXPECT_TRUE(base::MatchPattern(
399 utils::RunFunctionAndReturnError(function
.get(), kArgs
, browser()),
400 keys::kIncognitoModeIsDisabled
));
402 // Run in incognito window.
403 function
= new WindowsCreateFunction();
404 function
->set_extension(extension
.get());
405 EXPECT_TRUE(base::MatchPattern(utils::RunFunctionAndReturnError(
406 function
.get(), kArgs
, incognito_browser
),
407 keys::kIncognitoModeIsDisabled
));
410 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, QueryCurrentWindowTabs
) {
411 const size_t kExtraWindows
= 3;
412 for (size_t i
= 0; i
< kExtraWindows
; ++i
)
413 CreateBrowser(browser()->profile());
415 GURL
url(url::kAboutBlankURL
);
416 AddTabAtIndex(0, url
, ui::PAGE_TRANSITION_LINK
);
417 int window_id
= ExtensionTabUtil::GetWindowId(browser());
419 // Get tabs in the 'current' window called from non-focused browser.
420 scoped_refptr
<TabsQueryFunction
> function
= new TabsQueryFunction();
421 function
->set_extension(test_util::CreateEmptyExtension().get());
422 scoped_ptr
<base::ListValue
> result(utils::ToList(
423 utils::RunFunctionAndReturnSingleResult(function
.get(),
424 "[{\"currentWindow\":true}]",
427 base::ListValue
* result_tabs
= result
.get();
428 // We should have one initial tab and one added tab.
429 EXPECT_EQ(2u, result_tabs
->GetSize());
430 for (size_t i
= 0; i
< result_tabs
->GetSize(); ++i
) {
431 base::DictionaryValue
* result_tab
= NULL
;
432 EXPECT_TRUE(result_tabs
->GetDictionary(i
, &result_tab
));
434 api_test_utils::GetInteger(result_tab
, keys::kWindowIdKey
));
437 // Get tabs NOT in the 'current' window called from non-focused browser.
438 function
= new TabsQueryFunction();
439 function
->set_extension(test_util::CreateEmptyExtension().get());
440 result
.reset(utils::ToList(
441 utils::RunFunctionAndReturnSingleResult(function
.get(),
442 "[{\"currentWindow\":false}]",
445 result_tabs
= result
.get();
446 // We should have one tab for each extra window.
447 EXPECT_EQ(kExtraWindows
, result_tabs
->GetSize());
448 for (size_t i
= 0; i
< kExtraWindows
; ++i
) {
449 base::DictionaryValue
* result_tab
= NULL
;
450 EXPECT_TRUE(result_tabs
->GetDictionary(i
, &result_tab
));
452 api_test_utils::GetInteger(result_tab
, keys::kWindowIdKey
));
456 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, QueryAllTabsWithDevTools
) {
457 const size_t kNumWindows
= 3;
458 std::set
<int> window_ids
;
459 window_ids
.insert(ExtensionTabUtil::GetWindowId(browser()));
460 for (size_t i
= 0; i
< kNumWindows
- 1; ++i
) {
461 Browser
* new_browser
= CreateBrowser(browser()->profile());
462 window_ids
.insert(ExtensionTabUtil::GetWindowId(new_browser
));
465 // Undocked DevTools window should not be accessible.
466 DevToolsWindow
* devtools
= DevToolsWindowTesting::OpenDevToolsWindowSync(
467 browser()->tab_strip_model()->GetWebContentsAt(0), false /* is_docked */);
469 // Get tabs in the 'current' window called from non-focused browser.
470 scoped_refptr
<TabsQueryFunction
> function
= new TabsQueryFunction();
471 function
->set_extension(test_util::CreateEmptyExtension().get());
472 scoped_ptr
<base::ListValue
> result(utils::ToList(
473 utils::RunFunctionAndReturnSingleResult(function
.get(),
477 std::set
<int> result_ids
;
478 base::ListValue
* result_tabs
= result
.get();
479 // We should have one tab per browser except for DevTools.
480 EXPECT_EQ(kNumWindows
, result_tabs
->GetSize());
481 for (size_t i
= 0; i
< result_tabs
->GetSize(); ++i
) {
482 base::DictionaryValue
* result_tab
= NULL
;
483 EXPECT_TRUE(result_tabs
->GetDictionary(i
, &result_tab
));
485 api_test_utils::GetInteger(result_tab
, keys::kWindowIdKey
));
487 EXPECT_EQ(window_ids
, result_ids
);
489 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools
);
492 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, DontCreateTabInClosingPopupWindow
) {
493 // Test creates new popup window, closes it right away and then tries to open
494 // a new tab in it. Tab should not be opened in the popup window, but in a
495 // tabbed browser window.
496 Browser
* popup_browser
= new Browser(
497 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
498 browser()->host_desktop_type()));
499 int window_id
= ExtensionTabUtil::GetWindowId(popup_browser
);
500 chrome::CloseWindow(popup_browser
);
502 scoped_refptr
<TabsCreateFunction
> create_tab_function(
503 new TabsCreateFunction());
504 create_tab_function
->set_extension(test_util::CreateEmptyExtension().get());
505 // Without a callback the function will not generate a result.
506 create_tab_function
->set_has_callback(true);
508 static const char kNewBlankTabArgs
[] =
509 "[{\"url\": \"about:blank\", \"windowId\": %u}]";
511 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
512 utils::RunFunctionAndReturnSingleResult(
513 create_tab_function
.get(),
514 base::StringPrintf(kNewBlankTabArgs
, window_id
),
517 EXPECT_NE(window_id
, api_test_utils::GetInteger(result
.get(), "windowId"));
520 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, InvalidUpdateWindowState
) {
521 int window_id
= ExtensionTabUtil::GetWindowId(browser());
523 static const char kArgsMinimizedWithFocus
[] =
524 "[%u, {\"state\": \"minimized\", \"focused\": true}]";
525 scoped_refptr
<WindowsUpdateFunction
> function
= new WindowsUpdateFunction();
526 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
527 function
->set_extension(extension
.get());
528 EXPECT_TRUE(base::MatchPattern(
529 utils::RunFunctionAndReturnError(
531 base::StringPrintf(kArgsMinimizedWithFocus
, window_id
), browser()),
532 keys::kInvalidWindowStateError
));
534 static const char kArgsMaximizedWithoutFocus
[] =
535 "[%u, {\"state\": \"maximized\", \"focused\": false}]";
536 function
= new WindowsUpdateFunction();
537 function
->set_extension(extension
.get());
538 EXPECT_TRUE(base::MatchPattern(
539 utils::RunFunctionAndReturnError(
541 base::StringPrintf(kArgsMaximizedWithoutFocus
, window_id
), browser()),
542 keys::kInvalidWindowStateError
));
544 static const char kArgsMinimizedWithBounds
[] =
545 "[%u, {\"state\": \"minimized\", \"width\": 500}]";
546 function
= new WindowsUpdateFunction();
547 function
->set_extension(extension
.get());
548 EXPECT_TRUE(base::MatchPattern(
549 utils::RunFunctionAndReturnError(
551 base::StringPrintf(kArgsMinimizedWithBounds
, window_id
), browser()),
552 keys::kInvalidWindowStateError
));
554 static const char kArgsMaximizedWithBounds
[] =
555 "[%u, {\"state\": \"maximized\", \"width\": 500}]";
556 function
= new WindowsUpdateFunction();
557 function
->set_extension(extension
.get());
558 EXPECT_TRUE(base::MatchPattern(
559 utils::RunFunctionAndReturnError(
561 base::StringPrintf(kArgsMaximizedWithBounds
, window_id
), browser()),
562 keys::kInvalidWindowStateError
));
565 IN_PROC_BROWSER_TEST_F(ExtensionWindowCreateTest
, AcceptState
) {
566 scoped_refptr
<WindowsCreateFunction
> function(new WindowsCreateFunction());
567 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
568 function
->set_extension(extension
.get());
570 scoped_ptr
<base::DictionaryValue
> result(
571 utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
572 function
.get(), "[{\"state\": \"minimized\"}]", browser(),
573 utils::INCLUDE_INCOGNITO
)));
574 int window_id
= api_test_utils::GetInteger(result
.get(), "id");
576 Browser
* new_window
= ExtensionTabUtil::GetBrowserFromWindowID(
577 function
.get(), window_id
, &error
);
578 EXPECT_TRUE(error
.empty());
579 #if !defined(OS_LINUX) || defined(OS_CHROMEOS)
580 // DesktopWindowTreeHostX11::IsMinimized() relies on an asynchronous update
581 // from the window server.
582 EXPECT_TRUE(new_window
->window()->IsMinimized());
585 // TODO(limasdf): Flaky on mac. See http://crbug.com/482433.
586 #if !defined(OS_MACOSX)
587 function
= new WindowsCreateFunction();
588 function
->set_extension(extension
.get());
589 result
.reset(utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
590 function
.get(), "[{\"state\": \"fullscreen\"}]", browser(),
591 utils::INCLUDE_INCOGNITO
)));
592 window_id
= api_test_utils::GetInteger(result
.get(), "id");
593 new_window
= ExtensionTabUtil::GetBrowserFromWindowID(function
.get(),
595 EXPECT_TRUE(error
.empty());
596 EXPECT_TRUE(new_window
->window()->IsFullscreen());
597 #endif // !defined(OS_MACOSX)
600 IN_PROC_BROWSER_TEST_F(ExtensionWindowCreateTest
, ValidateCreateWindowState
) {
601 EXPECT_TRUE(base::MatchPattern(
602 RunCreateWindowExpectError(
603 "[{\"state\": \"fullscreen\", \"type\": \"panel\"}]"),
604 keys::kInvalidWindowStateError
));
605 EXPECT_TRUE(base::MatchPattern(
606 RunCreateWindowExpectError(
607 "[{\"state\": \"maximized\", \"type\": \"panel\"}]"),
608 keys::kInvalidWindowStateError
));
609 EXPECT_TRUE(base::MatchPattern(
610 RunCreateWindowExpectError(
611 "[{\"state\": \"minimized\", \"type\": \"panel\"}]"),
612 keys::kInvalidWindowStateError
));
614 base::MatchPattern(RunCreateWindowExpectError(
615 "[{\"state\": \"minimized\", \"focused\": true}]"),
616 keys::kInvalidWindowStateError
));
617 EXPECT_TRUE(base::MatchPattern(
618 RunCreateWindowExpectError(
619 "[{\"state\": \"maximized\", \"focused\": false}]"),
620 keys::kInvalidWindowStateError
));
621 EXPECT_TRUE(base::MatchPattern(
622 RunCreateWindowExpectError(
623 "[{\"state\": \"fullscreen\", \"focused\": false}]"),
624 keys::kInvalidWindowStateError
));
626 base::MatchPattern(RunCreateWindowExpectError(
627 "[{\"state\": \"minimized\", \"width\": 500}]"),
628 keys::kInvalidWindowStateError
));
630 base::MatchPattern(RunCreateWindowExpectError(
631 "[{\"state\": \"maximized\", \"width\": 500}]"),
632 keys::kInvalidWindowStateError
));
634 base::MatchPattern(RunCreateWindowExpectError(
635 "[{\"state\": \"fullscreen\", \"width\": 500}]"),
636 keys::kInvalidWindowStateError
));
639 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, DuplicateTab
) {
640 content::OpenURLParams
params(GURL(url::kAboutBlankURL
),
643 ui::PAGE_TRANSITION_LINK
,
645 content::WebContents
* web_contents
= browser()->OpenURL(params
);
646 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
647 int window_id
= ExtensionTabUtil::GetWindowIdOfTab(web_contents
);
649 TabStripModel
* tab_strip
;
650 ExtensionTabUtil::GetTabStripModel(web_contents
, &tab_strip
, &tab_index
);
652 scoped_refptr
<TabsDuplicateFunction
> duplicate_tab_function(
653 new TabsDuplicateFunction());
654 scoped_ptr
<base::DictionaryValue
> test_extension_value(
655 api_test_utils::ParseDictionary(
656 "{\"name\": \"Test\", \"version\": \"1.0\", \"permissions\": "
658 scoped_refptr
<Extension
> empty_tab_extension(
659 api_test_utils::CreateExtension(test_extension_value
.get()));
660 duplicate_tab_function
->set_extension(empty_tab_extension
.get());
661 duplicate_tab_function
->set_has_callback(true);
663 scoped_ptr
<base::DictionaryValue
> duplicate_result(utils::ToDictionary(
664 utils::RunFunctionAndReturnSingleResult(
665 duplicate_tab_function
.get(), base::StringPrintf("[%u]", tab_id
),
668 int duplicate_tab_id
=
669 api_test_utils::GetInteger(duplicate_result
.get(), "id");
670 int duplicate_tab_window_id
=
671 api_test_utils::GetInteger(duplicate_result
.get(), "windowId");
672 int duplicate_tab_index
=
673 api_test_utils::GetInteger(duplicate_result
.get(), "index");
674 EXPECT_EQ(base::Value::TYPE_DICTIONARY
, duplicate_result
->GetType());
675 // Duplicate tab id should be different from the original tab id.
676 EXPECT_NE(tab_id
, duplicate_tab_id
);
677 EXPECT_EQ(window_id
, duplicate_tab_window_id
);
678 EXPECT_EQ(tab_index
+ 1, duplicate_tab_index
);
679 // The test empty tab extension has tabs permissions, therefore
680 // |duplicate_result| should contain url, title, and faviconUrl
681 // in the function result.
682 EXPECT_TRUE(utils::HasPrivacySensitiveFields(duplicate_result
.get()));
685 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, DuplicateTabNoPermission
) {
686 content::OpenURLParams
params(GURL(url::kAboutBlankURL
),
689 ui::PAGE_TRANSITION_LINK
,
691 content::WebContents
* web_contents
= browser()->OpenURL(params
);
692 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
693 int window_id
= ExtensionTabUtil::GetWindowIdOfTab(web_contents
);
695 TabStripModel
* tab_strip
;
696 ExtensionTabUtil::GetTabStripModel(web_contents
, &tab_strip
, &tab_index
);
698 scoped_refptr
<TabsDuplicateFunction
> duplicate_tab_function(
699 new TabsDuplicateFunction());
700 scoped_refptr
<Extension
> empty_extension(test_util::CreateEmptyExtension());
701 duplicate_tab_function
->set_extension(empty_extension
.get());
702 duplicate_tab_function
->set_has_callback(true);
704 scoped_ptr
<base::DictionaryValue
> duplicate_result(utils::ToDictionary(
705 utils::RunFunctionAndReturnSingleResult(
706 duplicate_tab_function
.get(), base::StringPrintf("[%u]", tab_id
),
709 int duplicate_tab_id
=
710 api_test_utils::GetInteger(duplicate_result
.get(), "id");
711 int duplicate_tab_window_id
=
712 api_test_utils::GetInteger(duplicate_result
.get(), "windowId");
713 int duplicate_tab_index
=
714 api_test_utils::GetInteger(duplicate_result
.get(), "index");
715 EXPECT_EQ(base::Value::TYPE_DICTIONARY
, duplicate_result
->GetType());
716 // Duplicate tab id should be different from the original tab id.
717 EXPECT_NE(tab_id
, duplicate_tab_id
);
718 EXPECT_EQ(window_id
, duplicate_tab_window_id
);
719 EXPECT_EQ(tab_index
+ 1, duplicate_tab_index
);
720 // The test empty extension has no permissions, therefore |duplicate_result|
721 // should not contain url, title, and faviconUrl in the function result.
722 EXPECT_FALSE(utils::HasPrivacySensitiveFields(duplicate_result
.get()));
725 // Tester class for the tabs.zoom* api functions.
726 class ExtensionTabsZoomTest
: public ExtensionTabsTest
{
728 void SetUpOnMainThread() override
;
730 // Runs chrome.tabs.setZoom().
731 bool RunSetZoom(int tab_id
, double zoom_factor
);
733 // Runs chrome.tabs.getZoom().
734 testing::AssertionResult
RunGetZoom(int tab_id
, double* zoom_factor
);
736 // Runs chrome.tabs.setZoomSettings().
737 bool RunSetZoomSettings(int tab_id
, const char* mode
, const char* scope
);
739 // Runs chrome.tabs.getZoomSettings().
740 testing::AssertionResult
RunGetZoomSettings(int tab_id
,
744 // Runs chrome.tabs.getZoomSettings() and returns default zoom.
745 testing::AssertionResult
RunGetDefaultZoom(int tab_id
,
746 double* default_zoom_factor
);
748 // Runs chrome.tabs.setZoom(), expecting an error.
749 std::string
RunSetZoomExpectError(int tab_id
,
752 // Runs chrome.tabs.setZoomSettings(), expecting an error.
753 std::string
RunSetZoomSettingsExpectError(int tab_id
,
757 content::WebContents
* OpenUrlAndWaitForLoad(const GURL
& url
);
760 scoped_refptr
<Extension
> extension_
;
763 void ExtensionTabsZoomTest::SetUpOnMainThread() {
764 ExtensionTabsTest::SetUpOnMainThread();
765 extension_
= test_util::CreateEmptyExtension();
768 bool ExtensionTabsZoomTest::RunSetZoom(int tab_id
, double zoom_factor
) {
769 scoped_refptr
<TabsSetZoomFunction
> set_zoom_function(
770 new TabsSetZoomFunction());
771 set_zoom_function
->set_extension(extension_
.get());
772 set_zoom_function
->set_has_callback(true);
774 return utils::RunFunction(
775 set_zoom_function
.get(),
776 base::StringPrintf("[%u, %lf]", tab_id
, zoom_factor
), browser(),
777 extension_function_test_utils::NONE
);
780 testing::AssertionResult
ExtensionTabsZoomTest::RunGetZoom(
782 double* zoom_factor
) {
783 scoped_refptr
<TabsGetZoomFunction
> get_zoom_function(
784 new TabsGetZoomFunction());
785 get_zoom_function
->set_extension(extension_
.get());
786 get_zoom_function
->set_has_callback(true);
788 scoped_ptr
<base::Value
> get_zoom_result(
789 utils::RunFunctionAndReturnSingleResult(
790 get_zoom_function
.get(),
791 base::StringPrintf("[%u]", tab_id
),
794 if (!get_zoom_result
)
795 return testing::AssertionFailure() << "no result";
796 if (!get_zoom_result
->GetAsDouble(zoom_factor
))
797 return testing::AssertionFailure() << "result was not a double";
799 return testing::AssertionSuccess();
802 bool ExtensionTabsZoomTest::RunSetZoomSettings(int tab_id
,
805 scoped_refptr
<TabsSetZoomSettingsFunction
> set_zoom_settings_function(
806 new TabsSetZoomSettingsFunction());
807 set_zoom_settings_function
->set_extension(extension_
.get());
811 args
= base::StringPrintf("[%u, {\"mode\": \"%s\", \"scope\": \"%s\"}]",
812 tab_id
, mode
, scope
);
814 args
= base::StringPrintf("[%u, {\"mode\": \"%s\"}]", tab_id
, mode
);
817 return utils::RunFunction(set_zoom_settings_function
.get(),
820 extension_function_test_utils::NONE
);
823 testing::AssertionResult
ExtensionTabsZoomTest::RunGetZoomSettings(
826 std::string
* scope
) {
829 scoped_refptr
<TabsGetZoomSettingsFunction
> get_zoom_settings_function(
830 new TabsGetZoomSettingsFunction());
831 get_zoom_settings_function
->set_extension(extension_
.get());
832 get_zoom_settings_function
->set_has_callback(true);
834 scoped_ptr
<base::DictionaryValue
> get_zoom_settings_result(
835 utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
836 get_zoom_settings_function
.get(),
837 base::StringPrintf("[%u]", tab_id
),
840 if (!get_zoom_settings_result
)
841 return testing::AssertionFailure() << "no result";
843 *mode
= api_test_utils::GetString(get_zoom_settings_result
.get(), "mode");
844 *scope
= api_test_utils::GetString(get_zoom_settings_result
.get(), "scope");
846 return testing::AssertionSuccess();
849 testing::AssertionResult
ExtensionTabsZoomTest::RunGetDefaultZoom(
851 double* default_zoom_factor
) {
852 DCHECK(default_zoom_factor
);
853 scoped_refptr
<TabsGetZoomSettingsFunction
> get_zoom_settings_function(
854 new TabsGetZoomSettingsFunction());
855 get_zoom_settings_function
->set_extension(extension_
.get());
856 get_zoom_settings_function
->set_has_callback(true);
858 scoped_ptr
<base::DictionaryValue
> get_zoom_settings_result(
859 utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
860 get_zoom_settings_function
.get(),
861 base::StringPrintf("[%u]", tab_id
),
864 if (!get_zoom_settings_result
)
865 return testing::AssertionFailure() << "no result";
867 if (!get_zoom_settings_result
->GetDouble("defaultZoomFactor",
868 default_zoom_factor
)) {
869 return testing::AssertionFailure()
870 << "default zoom factor not found in result";
873 return testing::AssertionSuccess();
876 std::string
ExtensionTabsZoomTest::RunSetZoomExpectError(int tab_id
,
877 double zoom_factor
) {
878 scoped_refptr
<TabsSetZoomFunction
> set_zoom_function(
879 new TabsSetZoomFunction());
880 set_zoom_function
->set_extension(extension_
.get());
881 set_zoom_function
->set_has_callback(true);
883 return utils::RunFunctionAndReturnError(
884 set_zoom_function
.get(),
885 base::StringPrintf("[%u, %lf]", tab_id
, zoom_factor
),
889 std::string
ExtensionTabsZoomTest::RunSetZoomSettingsExpectError(
893 scoped_refptr
<TabsSetZoomSettingsFunction
> set_zoom_settings_function(
894 new TabsSetZoomSettingsFunction());
895 set_zoom_settings_function
->set_extension(extension_
.get());
897 return utils::RunFunctionAndReturnError(set_zoom_settings_function
.get(),
899 "[%u, {\"mode\": \"%s\", "
900 "\"scope\": \"%s\"}]",
907 content::WebContents
* ExtensionTabsZoomTest::OpenUrlAndWaitForLoad(
909 ui_test_utils::NavigateToURLWithDisposition(
913 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
914 return browser()->tab_strip_model()->GetActiveWebContents();
919 double GetZoomLevel(const content::WebContents
* web_contents
) {
920 return ui_zoom::ZoomController::FromWebContents(web_contents
)->GetZoomLevel();
923 content::OpenURLParams
GetOpenParams(const char* url
) {
924 return content::OpenURLParams(GURL(url
),
927 ui::PAGE_TRANSITION_LINK
,
933 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, SetAndGetZoom
) {
934 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
935 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
936 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
938 // Test default values before we set anything.
939 double zoom_factor
= -1;
940 EXPECT_TRUE(RunGetZoom(tab_id
, &zoom_factor
));
941 EXPECT_EQ(1.0, zoom_factor
);
943 // Test chrome.tabs.setZoom().
944 const double kZoomLevel
= 0.8;
945 EXPECT_TRUE(RunSetZoom(tab_id
, kZoomLevel
));
946 EXPECT_EQ(kZoomLevel
,
947 content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents
)));
949 // Test chrome.tabs.getZoom().
951 EXPECT_TRUE(RunGetZoom(tab_id
, &zoom_factor
));
952 EXPECT_EQ(kZoomLevel
, zoom_factor
);
955 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, GetDefaultZoom
) {
956 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
957 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
958 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
960 ui_zoom::ZoomController
* zoom_controller
=
961 ui_zoom::ZoomController::FromWebContents(web_contents
);
962 double default_zoom_factor
= -1.0;
963 EXPECT_TRUE(RunGetDefaultZoom(tab_id
, &default_zoom_factor
));
964 EXPECT_TRUE(content::ZoomValuesEqual(
965 zoom_controller
->GetDefaultZoomLevel(),
966 content::ZoomFactorToZoomLevel(default_zoom_factor
)));
968 // Change the default zoom level and verify GetDefaultZoom returns the
970 content::StoragePartition
* partition
=
971 content::BrowserContext::GetStoragePartition(
972 web_contents
->GetBrowserContext(), web_contents
->GetSiteInstance());
973 chrome::ChromeZoomLevelPrefs
* zoom_prefs
=
974 static_cast<chrome::ChromeZoomLevelPrefs
*>(
975 partition
->GetZoomLevelDelegate());
977 double default_zoom_level
= zoom_controller
->GetDefaultZoomLevel();
978 zoom_prefs
->SetDefaultZoomLevelPref(default_zoom_level
+ 0.5);
979 default_zoom_factor
= -1.0;
980 EXPECT_TRUE(RunGetDefaultZoom(tab_id
, &default_zoom_factor
));
981 EXPECT_TRUE(content::ZoomValuesEqual(
982 default_zoom_level
+ 0.5,
983 content::ZoomFactorToZoomLevel(default_zoom_factor
)));
986 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, SetToDefaultZoom
) {
987 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
988 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
989 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
991 ui_zoom::ZoomController
* zoom_controller
=
992 ui_zoom::ZoomController::FromWebContents(web_contents
);
993 double default_zoom_level
= zoom_controller
->GetDefaultZoomLevel();
994 double new_default_zoom_level
= default_zoom_level
+ 0.42;
996 content::StoragePartition
* partition
=
997 content::BrowserContext::GetStoragePartition(
998 web_contents
->GetBrowserContext(), web_contents
->GetSiteInstance());
999 chrome::ChromeZoomLevelPrefs
* zoom_prefs
=
1000 static_cast<chrome::ChromeZoomLevelPrefs
*>(
1001 partition
->GetZoomLevelDelegate());
1003 zoom_prefs
->SetDefaultZoomLevelPref(new_default_zoom_level
);
1005 double observed_zoom_factor
= -1.0;
1006 EXPECT_TRUE(RunSetZoom(tab_id
, 0.0));
1007 EXPECT_TRUE(RunGetZoom(tab_id
, &observed_zoom_factor
));
1008 EXPECT_TRUE(content::ZoomValuesEqual(
1009 new_default_zoom_level
,
1010 content::ZoomFactorToZoomLevel(observed_zoom_factor
)));
1013 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, ZoomSettings
) {
1014 // In this test we need two URLs that (1) represent real pages (i.e. they
1015 // load without causing an error page load), (2) have different domains, and
1016 // (3) are zoomable by the extension API (this last condition rules out
1017 // chrome:// urls). We achieve this by noting that about:blank meets these
1018 // requirements, allowing us to spin up a spawned http server on localhost to
1019 // get the other domain.
1020 net::SpawnedTestServer
http_server(
1021 net::SpawnedTestServer::TYPE_HTTP
,
1022 net::SpawnedTestServer::kLocalhost
,
1023 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1024 ASSERT_TRUE(http_server
.Start());
1026 GURL url_A
= http_server
.GetURL("files/simple.html");
1027 GURL
url_B("about:blank");
1029 // Tabs A1 and A2 are navigated to the same origin, while B is navigated
1030 // to a different one.
1031 content::WebContents
* web_contents_A1
= OpenUrlAndWaitForLoad(url_A
);
1032 content::WebContents
* web_contents_A2
= OpenUrlAndWaitForLoad(url_A
);
1033 content::WebContents
* web_contents_B
= OpenUrlAndWaitForLoad(url_B
);
1035 int tab_id_A1
= ExtensionTabUtil::GetTabId(web_contents_A1
);
1036 int tab_id_A2
= ExtensionTabUtil::GetTabId(web_contents_A2
);
1037 int tab_id_B
= ExtensionTabUtil::GetTabId(web_contents_B
);
1040 1.f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
1042 1.f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
1044 1.f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_B
)));
1046 // Test per-origin automatic zoom settings.
1047 EXPECT_TRUE(RunSetZoom(tab_id_B
, 1.f
));
1048 EXPECT_TRUE(RunSetZoom(tab_id_A2
, 1.1f
));
1050 1.1f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
1052 1.1f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
1053 EXPECT_FLOAT_EQ(1.f
,
1054 content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_B
)));
1056 // Test per-tab automatic zoom settings.
1057 EXPECT_TRUE(RunSetZoomSettings(tab_id_A1
, "automatic", "per-tab"));
1058 EXPECT_TRUE(RunSetZoom(tab_id_A1
, 1.2f
));
1060 1.2f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
1062 1.1f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
1064 // Test 'manual' mode.
1065 EXPECT_TRUE(RunSetZoomSettings(tab_id_A1
, "manual", NULL
));
1066 EXPECT_TRUE(RunSetZoom(tab_id_A1
, 1.3f
));
1068 1.3f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
1070 1.1f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
1072 // Test 'disabled' mode, which will reset A1's zoom to 1.f.
1073 EXPECT_TRUE(RunSetZoomSettings(tab_id_A1
, "disabled", NULL
));
1074 std::string error
= RunSetZoomExpectError(tab_id_A1
, 1.4f
);
1075 EXPECT_TRUE(base::MatchPattern(error
, keys::kCannotZoomDisabledTabError
));
1077 1.f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
1078 // We should still be able to zoom A2 though.
1079 EXPECT_TRUE(RunSetZoom(tab_id_A2
, 1.4f
));
1081 1.4f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
1084 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, PerTabResetsOnNavigation
) {
1085 net::SpawnedTestServer
http_server(
1086 net::SpawnedTestServer::TYPE_HTTP
,
1087 net::SpawnedTestServer::kLocalhost
,
1088 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1089 ASSERT_TRUE(http_server
.Start());
1091 GURL url_A
= http_server
.GetURL("files/simple.html");
1092 GURL
url_B("about:blank");
1094 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(url_A
);
1095 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
1096 EXPECT_TRUE(RunSetZoomSettings(tab_id
, "automatic", "per-tab"));
1100 EXPECT_TRUE(RunGetZoomSettings(tab_id
, &mode
, &scope
));
1101 EXPECT_EQ("automatic", mode
);
1102 EXPECT_EQ("per-tab", scope
);
1104 // Navigation of tab should reset mode to per-origin.
1105 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url_B
,
1107 EXPECT_TRUE(RunGetZoomSettings(tab_id
, &mode
, &scope
));
1108 EXPECT_EQ("automatic", mode
);
1109 EXPECT_EQ("per-origin", scope
);
1112 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, GetZoomSettings
) {
1113 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
1114 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
1115 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
1120 EXPECT_TRUE(RunGetZoomSettings(tab_id
, &mode
, &scope
));
1121 EXPECT_EQ("automatic", mode
);
1122 EXPECT_EQ("per-origin", scope
);
1124 EXPECT_TRUE(RunSetZoomSettings(tab_id
, "automatic", "per-tab"));
1125 EXPECT_TRUE(RunGetZoomSettings(tab_id
, &mode
, &scope
));
1127 EXPECT_EQ("automatic", mode
);
1128 EXPECT_EQ("per-tab", scope
);
1131 RunSetZoomSettingsExpectError(tab_id
, "manual", "per-origin");
1132 EXPECT_TRUE(base::MatchPattern(error
, keys::kPerOriginOnlyInAutomaticError
));
1134 RunSetZoomSettingsExpectError(tab_id
, "disabled", "per-origin");
1135 EXPECT_TRUE(base::MatchPattern(error
, keys::kPerOriginOnlyInAutomaticError
));
1138 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, CannotZoomInvalidTab
) {
1139 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
1140 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
1141 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
1143 int bogus_id
= tab_id
+ 100;
1144 std::string error
= RunSetZoomExpectError(bogus_id
, 3.14159);
1145 EXPECT_TRUE(base::MatchPattern(error
, keys::kTabNotFoundError
));
1147 error
= RunSetZoomSettingsExpectError(bogus_id
, "manual", "per-tab");
1148 EXPECT_TRUE(base::MatchPattern(error
, keys::kTabNotFoundError
));
1150 const char kNewTestTabArgs
[] = "chrome://version";
1151 params
= GetOpenParams(kNewTestTabArgs
);
1152 web_contents
= browser()->OpenURL(params
);
1153 tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
1155 // Test chrome.tabs.setZoom().
1156 error
= RunSetZoomExpectError(tab_id
, 3.14159);
1158 base::MatchPattern(error
, manifest_errors::kCannotAccessChromeUrl
));
1160 // chrome.tabs.setZoomSettings().
1161 error
= RunSetZoomSettingsExpectError(tab_id
, "manual", "per-tab");
1163 base::MatchPattern(error
, manifest_errors::kCannotAccessChromeUrl
));
1166 } // namespace extensions