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/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/values.h"
14 #include "chrome/browser/devtools/devtools_window_testing.h"
15 #include "chrome/browser/extensions/api/tabs/tabs_api.h"
16 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
17 #include "chrome/browser/extensions/extension_function_test_utils.h"
18 #include "chrome/browser/extensions/extension_tab_util.h"
19 #include "chrome/browser/prefs/incognito_mode_prefs.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_commands.h"
23 #include "chrome/browser/ui/browser_window.h"
24 #include "chrome/browser/ui/tabs/tab_strip_model.h"
25 #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
26 #include "chrome/test/base/in_process_browser_test.h"
27 #include "chrome/test/base/ui_test_utils.h"
28 #include "content/public/browser/browser_context.h"
29 #include "content/public/browser/storage_partition.h"
30 #include "content/public/common/page_zoom.h"
31 #include "content/public/common/url_constants.h"
32 #include "extensions/browser/api_test_utils.h"
33 #include "extensions/common/manifest_constants.h"
34 #include "extensions/common/test_util.h"
35 #include "net/test/spawned_test_server/spawned_test_server.h"
36 #include "ui/gfx/geometry/rect.h"
38 namespace extensions
{
40 namespace keys
= tabs_constants
;
41 namespace utils
= extension_function_test_utils
;
45 class ExtensionTabsTest
: public InProcessBrowserTest
{
50 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, GetWindow
) {
51 int window_id
= ExtensionTabUtil::GetWindowId(browser());
53 // Invalid window ID error.
54 scoped_refptr
<WindowsGetFunction
> function
= new WindowsGetFunction();
55 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
56 function
->set_extension(extension
.get());
57 EXPECT_TRUE(MatchPattern(
58 utils::RunFunctionAndReturnError(
60 base::StringPrintf("[%u]", window_id
+ 1),
62 keys::kWindowNotFoundError
));
64 // Basic window details.
66 if (browser()->window()->IsMinimized())
67 bounds
= browser()->window()->GetRestoredBounds();
69 bounds
= browser()->window()->GetBounds();
71 function
= new WindowsGetFunction();
72 function
->set_extension(extension
.get());
73 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
74 utils::RunFunctionAndReturnSingleResult(
76 base::StringPrintf("[%u]", window_id
),
78 EXPECT_EQ(window_id
, api_test_utils::GetInteger(result
.get(), "id"));
79 EXPECT_FALSE(api_test_utils::GetBoolean(result
.get(), "incognito"));
80 EXPECT_EQ("normal", api_test_utils::GetString(result
.get(), "type"));
81 EXPECT_EQ(bounds
.x(), api_test_utils::GetInteger(result
.get(), "left"));
82 EXPECT_EQ(bounds
.y(), api_test_utils::GetInteger(result
.get(), "top"));
83 EXPECT_EQ(bounds
.width(), api_test_utils::GetInteger(result
.get(), "width"));
84 EXPECT_EQ(bounds
.height(),
85 api_test_utils::GetInteger(result
.get(), "height"));
87 // With "populate" enabled.
88 function
= new WindowsGetFunction();
89 function
->set_extension(extension
.get());
90 result
.reset(utils::ToDictionary(
91 utils::RunFunctionAndReturnSingleResult(
93 base::StringPrintf("[%u, {\"populate\": true}]", window_id
),
96 EXPECT_EQ(window_id
, api_test_utils::GetInteger(result
.get(), "id"));
97 // "populate" was enabled so tabs should be populated.
98 base::ListValue
* tabs
= NULL
;
99 EXPECT_TRUE(result
.get()->GetList(keys::kTabsKey
, &tabs
));
101 // TODO(aa): Can't assume window is focused. On mac, calling Activate() from a
102 // browser test doesn't seem to do anything, so can't test the opposite
104 EXPECT_EQ(browser()->window()->IsActive(),
105 api_test_utils::GetBoolean(result
.get(), "focused"));
107 // TODO(aa): Minimized and maximized dimensions. Is there a way to set
108 // minimize/maximize programmatically?
111 Browser
* popup_browser
= new Browser(
112 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
113 browser()->host_desktop_type()));
114 function
= new WindowsGetFunction();
115 function
->set_extension(extension
.get());
116 result
.reset(utils::ToDictionary(
117 utils::RunFunctionAndReturnSingleResult(
120 "[%u]", ExtensionTabUtil::GetWindowId(popup_browser
)),
122 EXPECT_EQ("popup", api_test_utils::GetString(result
.get(), "type"));
125 Browser
* incognito_browser
= CreateIncognitoBrowser();
126 int incognito_window_id
= ExtensionTabUtil::GetWindowId(incognito_browser
);
128 // Without "include_incognito".
129 function
= new WindowsGetFunction();
130 function
->set_extension(extension
.get());
131 EXPECT_TRUE(MatchPattern(
132 utils::RunFunctionAndReturnError(
134 base::StringPrintf("[%u]", incognito_window_id
),
136 keys::kWindowNotFoundError
));
138 // With "include_incognito".
139 function
= new WindowsGetFunction();
140 function
->set_extension(extension
.get());
141 result
.reset(utils::ToDictionary(
142 utils::RunFunctionAndReturnSingleResult(
144 base::StringPrintf("[%u]", incognito_window_id
),
146 utils::INCLUDE_INCOGNITO
)));
147 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
150 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, GetCurrentWindow
) {
151 int window_id
= ExtensionTabUtil::GetWindowId(browser());
152 Browser
* new_browser
= CreateBrowser(browser()->profile());
153 int new_id
= ExtensionTabUtil::GetWindowId(new_browser
);
155 // Get the current window using new_browser.
156 scoped_refptr
<WindowsGetCurrentFunction
> function
=
157 new WindowsGetCurrentFunction();
158 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
159 function
->set_extension(extension
.get());
160 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
161 utils::RunFunctionAndReturnSingleResult(function
.get(),
165 // The id should match the window id of the browser instance that was passed
166 // to RunFunctionAndReturnSingleResult.
167 EXPECT_EQ(new_id
, api_test_utils::GetInteger(result
.get(), "id"));
168 base::ListValue
* tabs
= NULL
;
169 EXPECT_FALSE(result
.get()->GetList(keys::kTabsKey
, &tabs
));
171 // Get the current window using the old window and make the tabs populated.
172 function
= new WindowsGetCurrentFunction();
173 function
->set_extension(extension
.get());
174 result
.reset(utils::ToDictionary(
175 utils::RunFunctionAndReturnSingleResult(function
.get(),
176 "[{\"populate\": true}]",
179 // The id should match the window id of the browser instance that was passed
180 // to RunFunctionAndReturnSingleResult.
181 EXPECT_EQ(window_id
, api_test_utils::GetInteger(result
.get(), "id"));
182 // "populate" was enabled so tabs should be populated.
183 EXPECT_TRUE(result
.get()->GetList(keys::kTabsKey
, &tabs
));
186 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, GetAllWindows
) {
187 const size_t NUM_WINDOWS
= 5;
188 std::set
<int> window_ids
;
189 std::set
<int> result_ids
;
190 window_ids
.insert(ExtensionTabUtil::GetWindowId(browser()));
192 for (size_t i
= 0; i
< NUM_WINDOWS
- 1; ++i
) {
193 Browser
* new_browser
= CreateBrowser(browser()->profile());
194 window_ids
.insert(ExtensionTabUtil::GetWindowId(new_browser
));
197 // Undocked DevTools window should not be accessible.
198 DevToolsWindow
* devtools
= DevToolsWindowTesting::OpenDevToolsWindowSync(
199 browser()->tab_strip_model()->GetWebContentsAt(0), false /* is_docked */);
201 scoped_refptr
<WindowsGetAllFunction
> function
= new WindowsGetAllFunction();
202 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
203 function
->set_extension(extension
.get());
204 scoped_ptr
<base::ListValue
> result(utils::ToList(
205 utils::RunFunctionAndReturnSingleResult(function
.get(),
209 base::ListValue
* windows
= result
.get();
210 EXPECT_EQ(NUM_WINDOWS
, windows
->GetSize());
211 for (size_t i
= 0; i
< NUM_WINDOWS
; ++i
) {
212 base::DictionaryValue
* result_window
= NULL
;
213 EXPECT_TRUE(windows
->GetDictionary(i
, &result_window
));
214 result_ids
.insert(api_test_utils::GetInteger(result_window
, "id"));
216 // "populate" was not passed in so tabs are not populated.
217 base::ListValue
* tabs
= NULL
;
218 EXPECT_FALSE(result_window
->GetList(keys::kTabsKey
, &tabs
));
220 // The returned ids should contain all the current browser instance ids.
221 EXPECT_EQ(window_ids
, result_ids
);
224 function
= new WindowsGetAllFunction();
225 function
->set_extension(extension
.get());
226 result
.reset(utils::ToList(
227 utils::RunFunctionAndReturnSingleResult(function
.get(),
228 "[{\"populate\": true}]",
231 windows
= result
.get();
232 EXPECT_EQ(NUM_WINDOWS
, windows
->GetSize());
233 for (size_t i
= 0; i
< windows
->GetSize(); ++i
) {
234 base::DictionaryValue
* result_window
= NULL
;
235 EXPECT_TRUE(windows
->GetDictionary(i
, &result_window
));
236 result_ids
.insert(api_test_utils::GetInteger(result_window
, "id"));
238 // "populate" was enabled so tabs should be populated.
239 base::ListValue
* tabs
= NULL
;
240 EXPECT_TRUE(result_window
->GetList(keys::kTabsKey
, &tabs
));
242 // The returned ids should contain all the current browser instance ids.
243 EXPECT_EQ(window_ids
, result_ids
);
245 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools
);
248 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, UpdateNoPermissions
) {
249 // The test empty extension has no permissions, therefore it should not get
250 // tab data in the function result.
251 scoped_refptr
<TabsUpdateFunction
> update_tab_function(
252 new TabsUpdateFunction());
253 scoped_refptr
<Extension
> empty_extension(test_util::CreateEmptyExtension());
254 update_tab_function
->set_extension(empty_extension
.get());
255 // Without a callback the function will not generate a result.
256 update_tab_function
->set_has_callback(true);
258 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
259 utils::RunFunctionAndReturnSingleResult(
260 update_tab_function
.get(),
261 "[null, {\"url\": \"about:blank\", \"pinned\": true}]",
263 // The url is stripped since the extension does not have tab permissions.
264 EXPECT_FALSE(result
->HasKey("url"));
265 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "pinned"));
268 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
,
269 DefaultToIncognitoWhenItIsForced
) {
270 static const char kArgsWithoutExplicitIncognitoParam
[] =
271 "[{\"url\": \"about:blank\"}]";
272 // Force Incognito mode.
273 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
274 IncognitoModePrefs::FORCED
);
275 // Run without an explicit "incognito" param.
276 scoped_refptr
<WindowsCreateFunction
> function(new WindowsCreateFunction());
277 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
278 function
->set_extension(extension
.get());
279 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
280 utils::RunFunctionAndReturnSingleResult(
282 kArgsWithoutExplicitIncognitoParam
,
284 utils::INCLUDE_INCOGNITO
)));
286 // Make sure it is a new(different) window.
287 EXPECT_NE(ExtensionTabUtil::GetWindowId(browser()),
288 api_test_utils::GetInteger(result
.get(), "id"));
289 // ... and it is incognito.
290 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
292 // Now try creating a window from incognito window.
293 Browser
* incognito_browser
= CreateIncognitoBrowser();
294 // Run without an explicit "incognito" param.
295 function
= new WindowsCreateFunction();
296 function
->set_extension(extension
.get());
297 result
.reset(utils::ToDictionary(
298 utils::RunFunctionAndReturnSingleResult(
300 kArgsWithoutExplicitIncognitoParam
,
302 utils::INCLUDE_INCOGNITO
)));
303 // Make sure it is a new(different) window.
304 EXPECT_NE(ExtensionTabUtil::GetWindowId(incognito_browser
),
305 api_test_utils::GetInteger(result
.get(), "id"));
306 // ... and it is incognito.
307 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
310 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
,
311 DefaultToIncognitoWhenItIsForcedAndNoArgs
) {
312 static const char kEmptyArgs
[] = "[]";
313 // Force Incognito mode.
314 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
315 IncognitoModePrefs::FORCED
);
316 // Run without an explicit "incognito" param.
317 scoped_refptr
<WindowsCreateFunction
> function
= new WindowsCreateFunction();
318 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
319 function
->set_extension(extension
.get());
320 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
321 utils::RunFunctionAndReturnSingleResult(function
.get(),
324 utils::INCLUDE_INCOGNITO
)));
326 // Make sure it is a new(different) window.
327 EXPECT_NE(ExtensionTabUtil::GetWindowId(browser()),
328 api_test_utils::GetInteger(result
.get(), "id"));
329 // ... and it is incognito.
330 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
332 // Now try creating a window from incognito window.
333 Browser
* incognito_browser
= CreateIncognitoBrowser();
334 // Run without an explicit "incognito" param.
335 function
= new WindowsCreateFunction();
336 function
->set_extension(extension
.get());
337 result
.reset(utils::ToDictionary(
338 utils::RunFunctionAndReturnSingleResult(function
.get(),
341 utils::INCLUDE_INCOGNITO
)));
342 // Make sure it is a new(different) window.
343 EXPECT_NE(ExtensionTabUtil::GetWindowId(incognito_browser
),
344 api_test_utils::GetInteger(result
.get(), "id"));
345 // ... and it is incognito.
346 EXPECT_TRUE(api_test_utils::GetBoolean(result
.get(), "incognito"));
349 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
,
350 DontCreateNormalWindowWhenIncognitoForced
) {
351 static const char kArgsWithExplicitIncognitoParam
[] =
352 "[{\"url\": \"about:blank\", \"incognito\": false }]";
353 // Force Incognito mode.
354 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
355 IncognitoModePrefs::FORCED
);
357 // Run with an explicit "incognito" param.
358 scoped_refptr
<WindowsCreateFunction
> function
= new WindowsCreateFunction();
359 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
360 function
->set_extension(extension
.get());
361 EXPECT_TRUE(MatchPattern(
362 utils::RunFunctionAndReturnError(function
.get(),
363 kArgsWithExplicitIncognitoParam
,
365 keys::kIncognitoModeIsForced
));
367 // Now try opening a normal window from incognito window.
368 Browser
* incognito_browser
= CreateIncognitoBrowser();
369 // Run with an explicit "incognito" param.
370 function
= new WindowsCreateFunction();
371 function
->set_extension(extension
.get());
372 EXPECT_TRUE(MatchPattern(
373 utils::RunFunctionAndReturnError(function
.get(),
374 kArgsWithExplicitIncognitoParam
,
376 keys::kIncognitoModeIsForced
));
379 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
,
380 DontCreateIncognitoWindowWhenIncognitoDisabled
) {
381 static const char kArgs
[] =
382 "[{\"url\": \"about:blank\", \"incognito\": true }]";
384 Browser
* incognito_browser
= CreateIncognitoBrowser();
385 // Disable Incognito mode.
386 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
387 IncognitoModePrefs::DISABLED
);
388 // Run in normal window.
389 scoped_refptr
<WindowsCreateFunction
> function
= new WindowsCreateFunction();
390 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
391 function
->set_extension(extension
.get());
392 EXPECT_TRUE(MatchPattern(
393 utils::RunFunctionAndReturnError(function
.get(),
396 keys::kIncognitoModeIsDisabled
));
398 // Run in incognito window.
399 function
= new WindowsCreateFunction();
400 function
->set_extension(extension
.get());
401 EXPECT_TRUE(MatchPattern(
402 utils::RunFunctionAndReturnError(function
.get(),
405 keys::kIncognitoModeIsDisabled
));
408 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, QueryCurrentWindowTabs
) {
409 const size_t kExtraWindows
= 3;
410 for (size_t i
= 0; i
< kExtraWindows
; ++i
)
411 CreateBrowser(browser()->profile());
413 GURL
url(url::kAboutBlankURL
);
414 AddTabAtIndex(0, url
, ui::PAGE_TRANSITION_LINK
);
415 int window_id
= ExtensionTabUtil::GetWindowId(browser());
417 // Get tabs in the 'current' window called from non-focused browser.
418 scoped_refptr
<TabsQueryFunction
> function
= new TabsQueryFunction();
419 function
->set_extension(test_util::CreateEmptyExtension().get());
420 scoped_ptr
<base::ListValue
> result(utils::ToList(
421 utils::RunFunctionAndReturnSingleResult(function
.get(),
422 "[{\"currentWindow\":true}]",
425 base::ListValue
* result_tabs
= result
.get();
426 // We should have one initial tab and one added tab.
427 EXPECT_EQ(2u, result_tabs
->GetSize());
428 for (size_t i
= 0; i
< result_tabs
->GetSize(); ++i
) {
429 base::DictionaryValue
* result_tab
= NULL
;
430 EXPECT_TRUE(result_tabs
->GetDictionary(i
, &result_tab
));
432 api_test_utils::GetInteger(result_tab
, keys::kWindowIdKey
));
435 // Get tabs NOT in the 'current' window called from non-focused browser.
436 function
= new TabsQueryFunction();
437 function
->set_extension(test_util::CreateEmptyExtension().get());
438 result
.reset(utils::ToList(
439 utils::RunFunctionAndReturnSingleResult(function
.get(),
440 "[{\"currentWindow\":false}]",
443 result_tabs
= result
.get();
444 // We should have one tab for each extra window.
445 EXPECT_EQ(kExtraWindows
, result_tabs
->GetSize());
446 for (size_t i
= 0; i
< kExtraWindows
; ++i
) {
447 base::DictionaryValue
* result_tab
= NULL
;
448 EXPECT_TRUE(result_tabs
->GetDictionary(i
, &result_tab
));
450 api_test_utils::GetInteger(result_tab
, keys::kWindowIdKey
));
454 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, QueryAllTabsWithDevTools
) {
455 const size_t kNumWindows
= 3;
456 std::set
<int> window_ids
;
457 window_ids
.insert(ExtensionTabUtil::GetWindowId(browser()));
458 for (size_t i
= 0; i
< kNumWindows
- 1; ++i
) {
459 Browser
* new_browser
= CreateBrowser(browser()->profile());
460 window_ids
.insert(ExtensionTabUtil::GetWindowId(new_browser
));
463 // Undocked DevTools window should not be accessible.
464 DevToolsWindow
* devtools
= DevToolsWindowTesting::OpenDevToolsWindowSync(
465 browser()->tab_strip_model()->GetWebContentsAt(0), false /* is_docked */);
467 // Get tabs in the 'current' window called from non-focused browser.
468 scoped_refptr
<TabsQueryFunction
> function
= new TabsQueryFunction();
469 function
->set_extension(test_util::CreateEmptyExtension().get());
470 scoped_ptr
<base::ListValue
> result(utils::ToList(
471 utils::RunFunctionAndReturnSingleResult(function
.get(),
475 std::set
<int> result_ids
;
476 base::ListValue
* result_tabs
= result
.get();
477 // We should have one tab per browser except for DevTools.
478 EXPECT_EQ(kNumWindows
, result_tabs
->GetSize());
479 for (size_t i
= 0; i
< result_tabs
->GetSize(); ++i
) {
480 base::DictionaryValue
* result_tab
= NULL
;
481 EXPECT_TRUE(result_tabs
->GetDictionary(i
, &result_tab
));
483 api_test_utils::GetInteger(result_tab
, keys::kWindowIdKey
));
485 EXPECT_EQ(window_ids
, result_ids
);
487 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools
);
490 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, DontCreateTabInClosingPopupWindow
) {
491 // Test creates new popup window, closes it right away and then tries to open
492 // a new tab in it. Tab should not be opened in the popup window, but in a
493 // tabbed browser window.
494 Browser
* popup_browser
= new Browser(
495 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
496 browser()->host_desktop_type()));
497 int window_id
= ExtensionTabUtil::GetWindowId(popup_browser
);
498 chrome::CloseWindow(popup_browser
);
500 scoped_refptr
<TabsCreateFunction
> create_tab_function(
501 new TabsCreateFunction());
502 create_tab_function
->set_extension(test_util::CreateEmptyExtension().get());
503 // Without a callback the function will not generate a result.
504 create_tab_function
->set_has_callback(true);
506 static const char kNewBlankTabArgs
[] =
507 "[{\"url\": \"about:blank\", \"windowId\": %u}]";
509 scoped_ptr
<base::DictionaryValue
> result(utils::ToDictionary(
510 utils::RunFunctionAndReturnSingleResult(
511 create_tab_function
.get(),
512 base::StringPrintf(kNewBlankTabArgs
, window_id
),
515 EXPECT_NE(window_id
, api_test_utils::GetInteger(result
.get(), "windowId"));
518 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, InvalidUpdateWindowState
) {
519 int window_id
= ExtensionTabUtil::GetWindowId(browser());
521 static const char kArgsMinimizedWithFocus
[] =
522 "[%u, {\"state\": \"minimized\", \"focused\": true}]";
523 scoped_refptr
<WindowsUpdateFunction
> function
= new WindowsUpdateFunction();
524 scoped_refptr
<Extension
> extension(test_util::CreateEmptyExtension());
525 function
->set_extension(extension
.get());
526 EXPECT_TRUE(MatchPattern(
527 utils::RunFunctionAndReturnError(
529 base::StringPrintf(kArgsMinimizedWithFocus
, window_id
),
531 keys::kInvalidWindowStateError
));
533 static const char kArgsMaximizedWithoutFocus
[] =
534 "[%u, {\"state\": \"maximized\", \"focused\": false}]";
535 function
= new WindowsUpdateFunction();
536 function
->set_extension(extension
.get());
537 EXPECT_TRUE(MatchPattern(
538 utils::RunFunctionAndReturnError(
540 base::StringPrintf(kArgsMaximizedWithoutFocus
, window_id
),
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(MatchPattern(
549 utils::RunFunctionAndReturnError(
551 base::StringPrintf(kArgsMinimizedWithBounds
, window_id
),
553 keys::kInvalidWindowStateError
));
555 static const char kArgsMaximizedWithBounds
[] =
556 "[%u, {\"state\": \"maximized\", \"width\": 500}]";
557 function
= new WindowsUpdateFunction();
558 function
->set_extension(extension
.get());
559 EXPECT_TRUE(MatchPattern(
560 utils::RunFunctionAndReturnError(
562 base::StringPrintf(kArgsMaximizedWithBounds
, window_id
),
564 keys::kInvalidWindowStateError
));
567 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, DuplicateTab
) {
568 content::OpenURLParams
params(GURL(url::kAboutBlankURL
),
571 ui::PAGE_TRANSITION_LINK
,
573 content::WebContents
* web_contents
= browser()->OpenURL(params
);
574 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
575 int window_id
= ExtensionTabUtil::GetWindowIdOfTab(web_contents
);
577 TabStripModel
* tab_strip
;
578 ExtensionTabUtil::GetTabStripModel(web_contents
, &tab_strip
, &tab_index
);
580 scoped_refptr
<TabsDuplicateFunction
> duplicate_tab_function(
581 new TabsDuplicateFunction());
582 scoped_ptr
<base::DictionaryValue
> test_extension_value(
583 api_test_utils::ParseDictionary(
584 "{\"name\": \"Test\", \"version\": \"1.0\", \"permissions\": "
586 scoped_refptr
<Extension
> empty_tab_extension(
587 api_test_utils::CreateExtension(test_extension_value
.get()));
588 duplicate_tab_function
->set_extension(empty_tab_extension
.get());
589 duplicate_tab_function
->set_has_callback(true);
591 scoped_ptr
<base::DictionaryValue
> duplicate_result(utils::ToDictionary(
592 utils::RunFunctionAndReturnSingleResult(
593 duplicate_tab_function
.get(), base::StringPrintf("[%u]", tab_id
),
596 int duplicate_tab_id
=
597 api_test_utils::GetInteger(duplicate_result
.get(), "id");
598 int duplicate_tab_window_id
=
599 api_test_utils::GetInteger(duplicate_result
.get(), "windowId");
600 int duplicate_tab_index
=
601 api_test_utils::GetInteger(duplicate_result
.get(), "index");
602 EXPECT_EQ(base::Value::TYPE_DICTIONARY
, duplicate_result
->GetType());
603 // Duplicate tab id should be different from the original tab id.
604 EXPECT_NE(tab_id
, duplicate_tab_id
);
605 EXPECT_EQ(window_id
, duplicate_tab_window_id
);
606 EXPECT_EQ(tab_index
+ 1, duplicate_tab_index
);
607 // The test empty tab extension has tabs permissions, therefore
608 // |duplicate_result| should contain url, title, and faviconUrl
609 // in the function result.
610 EXPECT_TRUE(utils::HasPrivacySensitiveFields(duplicate_result
.get()));
613 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest
, DuplicateTabNoPermission
) {
614 content::OpenURLParams
params(GURL(url::kAboutBlankURL
),
617 ui::PAGE_TRANSITION_LINK
,
619 content::WebContents
* web_contents
= browser()->OpenURL(params
);
620 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
621 int window_id
= ExtensionTabUtil::GetWindowIdOfTab(web_contents
);
623 TabStripModel
* tab_strip
;
624 ExtensionTabUtil::GetTabStripModel(web_contents
, &tab_strip
, &tab_index
);
626 scoped_refptr
<TabsDuplicateFunction
> duplicate_tab_function(
627 new TabsDuplicateFunction());
628 scoped_refptr
<Extension
> empty_extension(test_util::CreateEmptyExtension());
629 duplicate_tab_function
->set_extension(empty_extension
.get());
630 duplicate_tab_function
->set_has_callback(true);
632 scoped_ptr
<base::DictionaryValue
> duplicate_result(utils::ToDictionary(
633 utils::RunFunctionAndReturnSingleResult(
634 duplicate_tab_function
.get(), base::StringPrintf("[%u]", tab_id
),
637 int duplicate_tab_id
=
638 api_test_utils::GetInteger(duplicate_result
.get(), "id");
639 int duplicate_tab_window_id
=
640 api_test_utils::GetInteger(duplicate_result
.get(), "windowId");
641 int duplicate_tab_index
=
642 api_test_utils::GetInteger(duplicate_result
.get(), "index");
643 EXPECT_EQ(base::Value::TYPE_DICTIONARY
, duplicate_result
->GetType());
644 // Duplicate tab id should be different from the original tab id.
645 EXPECT_NE(tab_id
, duplicate_tab_id
);
646 EXPECT_EQ(window_id
, duplicate_tab_window_id
);
647 EXPECT_EQ(tab_index
+ 1, duplicate_tab_index
);
648 // The test empty extension has no permissions, therefore |duplicate_result|
649 // should not contain url, title, and faviconUrl in the function result.
650 EXPECT_FALSE(utils::HasPrivacySensitiveFields(duplicate_result
.get()));
653 // Tester class for the tabs.zoom* api functions.
654 class ExtensionTabsZoomTest
: public ExtensionTabsTest
{
656 void SetUpOnMainThread() override
;
658 // Runs chrome.tabs.setZoom().
659 bool RunSetZoom(int tab_id
, double zoom_factor
);
661 // Runs chrome.tabs.getZoom().
662 testing::AssertionResult
RunGetZoom(int tab_id
, double* zoom_factor
);
664 // Runs chrome.tabs.setZoomSettings().
665 bool RunSetZoomSettings(int tab_id
, const char* mode
, const char* scope
);
667 // Runs chrome.tabs.getZoomSettings().
668 testing::AssertionResult
RunGetZoomSettings(int tab_id
,
672 // Runs chrome.tabs.getZoomSettings() and returns default zoom.
673 testing::AssertionResult
RunGetDefaultZoom(int tab_id
,
674 double* default_zoom_factor
);
676 // Runs chrome.tabs.setZoom(), expecting an error.
677 std::string
RunSetZoomExpectError(int tab_id
,
680 // Runs chrome.tabs.setZoomSettings(), expecting an error.
681 std::string
RunSetZoomSettingsExpectError(int tab_id
,
685 content::WebContents
* OpenUrlAndWaitForLoad(const GURL
& url
);
688 scoped_refptr
<Extension
> extension_
;
691 void ExtensionTabsZoomTest::SetUpOnMainThread() {
692 ExtensionTabsTest::SetUpOnMainThread();
693 extension_
= test_util::CreateEmptyExtension();
696 bool ExtensionTabsZoomTest::RunSetZoom(int tab_id
, double zoom_factor
) {
697 scoped_refptr
<TabsSetZoomFunction
> set_zoom_function(
698 new TabsSetZoomFunction());
699 set_zoom_function
->set_extension(extension_
.get());
700 set_zoom_function
->set_has_callback(true);
702 return utils::RunFunction(
703 set_zoom_function
.get(),
704 base::StringPrintf("[%u, %lf]", tab_id
, zoom_factor
), browser(),
705 extension_function_test_utils::NONE
);
708 testing::AssertionResult
ExtensionTabsZoomTest::RunGetZoom(
710 double* zoom_factor
) {
711 scoped_refptr
<TabsGetZoomFunction
> get_zoom_function(
712 new TabsGetZoomFunction());
713 get_zoom_function
->set_extension(extension_
.get());
714 get_zoom_function
->set_has_callback(true);
716 scoped_ptr
<base::Value
> get_zoom_result(
717 utils::RunFunctionAndReturnSingleResult(
718 get_zoom_function
.get(),
719 base::StringPrintf("[%u]", tab_id
),
722 if (!get_zoom_result
)
723 return testing::AssertionFailure() << "no result";
724 if (!get_zoom_result
->GetAsDouble(zoom_factor
))
725 return testing::AssertionFailure() << "result was not a double";
727 return testing::AssertionSuccess();
730 bool ExtensionTabsZoomTest::RunSetZoomSettings(int tab_id
,
733 scoped_refptr
<TabsSetZoomSettingsFunction
> set_zoom_settings_function(
734 new TabsSetZoomSettingsFunction());
735 set_zoom_settings_function
->set_extension(extension_
.get());
739 args
= base::StringPrintf("[%u, {\"mode\": \"%s\", \"scope\": \"%s\"}]",
740 tab_id
, mode
, scope
);
742 args
= base::StringPrintf("[%u, {\"mode\": \"%s\"}]", tab_id
, mode
);
745 return utils::RunFunction(set_zoom_settings_function
.get(),
748 extension_function_test_utils::NONE
);
751 testing::AssertionResult
ExtensionTabsZoomTest::RunGetZoomSettings(
754 std::string
* scope
) {
757 scoped_refptr
<TabsGetZoomSettingsFunction
> get_zoom_settings_function(
758 new TabsGetZoomSettingsFunction());
759 get_zoom_settings_function
->set_extension(extension_
.get());
760 get_zoom_settings_function
->set_has_callback(true);
762 scoped_ptr
<base::DictionaryValue
> get_zoom_settings_result(
763 utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
764 get_zoom_settings_function
.get(),
765 base::StringPrintf("[%u]", tab_id
),
768 if (!get_zoom_settings_result
)
769 return testing::AssertionFailure() << "no result";
771 *mode
= api_test_utils::GetString(get_zoom_settings_result
.get(), "mode");
772 *scope
= api_test_utils::GetString(get_zoom_settings_result
.get(), "scope");
774 return testing::AssertionSuccess();
777 testing::AssertionResult
ExtensionTabsZoomTest::RunGetDefaultZoom(
779 double* default_zoom_factor
) {
780 DCHECK(default_zoom_factor
);
781 scoped_refptr
<TabsGetZoomSettingsFunction
> get_zoom_settings_function(
782 new TabsGetZoomSettingsFunction());
783 get_zoom_settings_function
->set_extension(extension_
.get());
784 get_zoom_settings_function
->set_has_callback(true);
786 scoped_ptr
<base::DictionaryValue
> get_zoom_settings_result(
787 utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
788 get_zoom_settings_function
.get(),
789 base::StringPrintf("[%u]", tab_id
),
792 if (!get_zoom_settings_result
)
793 return testing::AssertionFailure() << "no result";
795 if (!get_zoom_settings_result
->GetDouble("default_zoom_factor",
796 default_zoom_factor
)) {
797 return testing::AssertionFailure()
798 << "default zoom factor not found in result";
801 return testing::AssertionSuccess();
804 std::string
ExtensionTabsZoomTest::RunSetZoomExpectError(int tab_id
,
805 double zoom_factor
) {
806 scoped_refptr
<TabsSetZoomFunction
> set_zoom_function(
807 new TabsSetZoomFunction());
808 set_zoom_function
->set_extension(extension_
.get());
809 set_zoom_function
->set_has_callback(true);
811 return utils::RunFunctionAndReturnError(
812 set_zoom_function
.get(),
813 base::StringPrintf("[%u, %lf]", tab_id
, zoom_factor
),
817 std::string
ExtensionTabsZoomTest::RunSetZoomSettingsExpectError(
821 scoped_refptr
<TabsSetZoomSettingsFunction
> set_zoom_settings_function(
822 new TabsSetZoomSettingsFunction());
823 set_zoom_settings_function
->set_extension(extension_
.get());
825 return utils::RunFunctionAndReturnError(set_zoom_settings_function
.get(),
827 "[%u, {\"mode\": \"%s\", "
828 "\"scope\": \"%s\"}]",
835 content::WebContents
* ExtensionTabsZoomTest::OpenUrlAndWaitForLoad(
837 ui_test_utils::NavigateToURLWithDisposition(
841 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
842 return browser()->tab_strip_model()->GetActiveWebContents();
847 double GetZoomLevel(const content::WebContents
* web_contents
) {
848 return ui_zoom::ZoomController::FromWebContents(web_contents
)->GetZoomLevel();
851 content::OpenURLParams
GetOpenParams(const char* url
) {
852 return content::OpenURLParams(GURL(url
),
855 ui::PAGE_TRANSITION_LINK
,
861 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, SetAndGetZoom
) {
862 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
863 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
864 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
866 // Test default values before we set anything.
867 double zoom_factor
= -1;
868 EXPECT_TRUE(RunGetZoom(tab_id
, &zoom_factor
));
869 EXPECT_EQ(1.0, zoom_factor
);
871 // Test chrome.tabs.setZoom().
872 const double kZoomLevel
= 0.8;
873 EXPECT_TRUE(RunSetZoom(tab_id
, kZoomLevel
));
874 EXPECT_EQ(kZoomLevel
,
875 content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents
)));
877 // Test chrome.tabs.getZoom().
879 EXPECT_TRUE(RunGetZoom(tab_id
, &zoom_factor
));
880 EXPECT_EQ(kZoomLevel
, zoom_factor
);
883 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, GetDefaultZoom
) {
884 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
885 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
886 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
888 ui_zoom::ZoomController
* zoom_controller
=
889 ui_zoom::ZoomController::FromWebContents(web_contents
);
890 double default_zoom_factor
= -1.0;
891 EXPECT_TRUE(RunGetDefaultZoom(tab_id
, &default_zoom_factor
));
892 EXPECT_TRUE(content::ZoomValuesEqual(
893 zoom_controller
->GetDefaultZoomLevel(),
894 content::ZoomFactorToZoomLevel(default_zoom_factor
)));
896 // Change the default zoom level and verify GetDefaultZoom returns the
898 content::StoragePartition
* partition
=
899 content::BrowserContext::GetStoragePartition(
900 web_contents
->GetBrowserContext(), web_contents
->GetSiteInstance());
901 chrome::ChromeZoomLevelPrefs
* zoom_prefs
=
902 static_cast<chrome::ChromeZoomLevelPrefs
*>(
903 partition
->GetZoomLevelDelegate());
905 double default_zoom_level
= zoom_controller
->GetDefaultZoomLevel();
906 zoom_prefs
->SetDefaultZoomLevelPref(default_zoom_level
+ 0.5);
907 default_zoom_factor
= -1.0;
908 EXPECT_TRUE(RunGetDefaultZoom(tab_id
, &default_zoom_factor
));
909 EXPECT_TRUE(content::ZoomValuesEqual(
910 default_zoom_level
+ 0.5,
911 content::ZoomFactorToZoomLevel(default_zoom_factor
)));
914 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, SetToDefaultZoom
) {
915 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
916 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
917 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
919 ui_zoom::ZoomController
* zoom_controller
=
920 ui_zoom::ZoomController::FromWebContents(web_contents
);
921 double default_zoom_level
= zoom_controller
->GetDefaultZoomLevel();
922 double new_default_zoom_level
= default_zoom_level
+ 0.42;
924 content::StoragePartition
* partition
=
925 content::BrowserContext::GetStoragePartition(
926 web_contents
->GetBrowserContext(), web_contents
->GetSiteInstance());
927 chrome::ChromeZoomLevelPrefs
* zoom_prefs
=
928 static_cast<chrome::ChromeZoomLevelPrefs
*>(
929 partition
->GetZoomLevelDelegate());
931 zoom_prefs
->SetDefaultZoomLevelPref(new_default_zoom_level
);
933 double observed_zoom_factor
= -1.0;
934 EXPECT_TRUE(RunSetZoom(tab_id
, 0.0));
935 EXPECT_TRUE(RunGetZoom(tab_id
, &observed_zoom_factor
));
936 EXPECT_TRUE(content::ZoomValuesEqual(
937 new_default_zoom_level
,
938 content::ZoomFactorToZoomLevel(observed_zoom_factor
)));
941 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, ZoomSettings
) {
942 // In this test we need two URLs that (1) represent real pages (i.e. they
943 // load without causing an error page load), (2) have different domains, and
944 // (3) are zoomable by the extension API (this last condition rules out
945 // chrome:// urls). We achieve this by noting that about:blank meets these
946 // requirements, allowing us to spin up a spawned http server on localhost to
947 // get the other domain.
948 net::SpawnedTestServer
http_server(
949 net::SpawnedTestServer::TYPE_HTTP
,
950 net::SpawnedTestServer::kLocalhost
,
951 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
952 ASSERT_TRUE(http_server
.Start());
954 GURL url_A
= http_server
.GetURL("files/simple.html");
955 GURL
url_B("about:blank");
957 // Tabs A1 and A2 are navigated to the same origin, while B is navigated
958 // to a different one.
959 content::WebContents
* web_contents_A1
= OpenUrlAndWaitForLoad(url_A
);
960 content::WebContents
* web_contents_A2
= OpenUrlAndWaitForLoad(url_A
);
961 content::WebContents
* web_contents_B
= OpenUrlAndWaitForLoad(url_B
);
963 int tab_id_A1
= ExtensionTabUtil::GetTabId(web_contents_A1
);
964 int tab_id_A2
= ExtensionTabUtil::GetTabId(web_contents_A2
);
965 int tab_id_B
= ExtensionTabUtil::GetTabId(web_contents_B
);
968 1.f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
970 1.f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
972 1.f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_B
)));
974 // Test per-origin automatic zoom settings.
975 EXPECT_TRUE(RunSetZoom(tab_id_B
, 1.f
));
976 EXPECT_TRUE(RunSetZoom(tab_id_A2
, 1.1f
));
978 1.1f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
980 1.1f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
982 content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_B
)));
984 // Test per-tab automatic zoom settings.
985 EXPECT_TRUE(RunSetZoomSettings(tab_id_A1
, "automatic", "per-tab"));
986 EXPECT_TRUE(RunSetZoom(tab_id_A1
, 1.2f
));
988 1.2f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
990 1.1f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
992 // Test 'manual' mode.
993 EXPECT_TRUE(RunSetZoomSettings(tab_id_A1
, "manual", NULL
));
994 EXPECT_TRUE(RunSetZoom(tab_id_A1
, 1.3f
));
996 1.3f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
998 1.1f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
1000 // Test 'disabled' mode, which will reset A1's zoom to 1.f.
1001 EXPECT_TRUE(RunSetZoomSettings(tab_id_A1
, "disabled", NULL
));
1002 std::string error
= RunSetZoomExpectError(tab_id_A1
, 1.4f
);
1003 EXPECT_TRUE(MatchPattern(error
, keys::kCannotZoomDisabledTabError
));
1005 1.f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A1
)));
1006 // We should still be able to zoom A2 though.
1007 EXPECT_TRUE(RunSetZoom(tab_id_A2
, 1.4f
));
1009 1.4f
, content::ZoomLevelToZoomFactor(GetZoomLevel(web_contents_A2
)));
1012 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, PerTabResetsOnNavigation
) {
1013 net::SpawnedTestServer
http_server(
1014 net::SpawnedTestServer::TYPE_HTTP
,
1015 net::SpawnedTestServer::kLocalhost
,
1016 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1017 ASSERT_TRUE(http_server
.Start());
1019 GURL url_A
= http_server
.GetURL("files/simple.html");
1020 GURL
url_B("about:blank");
1022 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(url_A
);
1023 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
1024 EXPECT_TRUE(RunSetZoomSettings(tab_id
, "automatic", "per-tab"));
1028 EXPECT_TRUE(RunGetZoomSettings(tab_id
, &mode
, &scope
));
1029 EXPECT_EQ("automatic", mode
);
1030 EXPECT_EQ("per-tab", scope
);
1032 // Navigation of tab should reset mode to per-origin.
1033 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url_B
,
1035 EXPECT_TRUE(RunGetZoomSettings(tab_id
, &mode
, &scope
));
1036 EXPECT_EQ("automatic", mode
);
1037 EXPECT_EQ("per-origin", scope
);
1040 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, GetZoomSettings
) {
1041 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
1042 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
1043 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
1048 EXPECT_TRUE(RunGetZoomSettings(tab_id
, &mode
, &scope
));
1049 EXPECT_EQ("automatic", mode
);
1050 EXPECT_EQ("per-origin", scope
);
1052 EXPECT_TRUE(RunSetZoomSettings(tab_id
, "automatic", "per-tab"));
1053 EXPECT_TRUE(RunGetZoomSettings(tab_id
, &mode
, &scope
));
1055 EXPECT_EQ("automatic", mode
);
1056 EXPECT_EQ("per-tab", scope
);
1059 RunSetZoomSettingsExpectError(tab_id
, "manual", "per-origin");
1060 EXPECT_TRUE(MatchPattern(error
,
1061 keys::kPerOriginOnlyInAutomaticError
));
1063 RunSetZoomSettingsExpectError(tab_id
, "disabled", "per-origin");
1064 EXPECT_TRUE(MatchPattern(error
,
1065 keys::kPerOriginOnlyInAutomaticError
));
1068 IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest
, CannotZoomInvalidTab
) {
1069 content::OpenURLParams
params(GetOpenParams(url::kAboutBlankURL
));
1070 content::WebContents
* web_contents
= OpenUrlAndWaitForLoad(params
.url
);
1071 int tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
1073 int bogus_id
= tab_id
+ 100;
1074 std::string error
= RunSetZoomExpectError(bogus_id
, 3.14159);
1075 EXPECT_TRUE(MatchPattern(error
, keys::kTabNotFoundError
));
1077 error
= RunSetZoomSettingsExpectError(bogus_id
, "manual", "per-tab");
1078 EXPECT_TRUE(MatchPattern(error
, keys::kTabNotFoundError
));
1080 const char kNewTestTabArgs
[] = "chrome://version";
1081 params
= GetOpenParams(kNewTestTabArgs
);
1082 web_contents
= browser()->OpenURL(params
);
1083 tab_id
= ExtensionTabUtil::GetTabId(web_contents
);
1085 // Test chrome.tabs.setZoom().
1086 error
= RunSetZoomExpectError(tab_id
, 3.14159);
1087 EXPECT_TRUE(MatchPattern(error
, manifest_errors::kCannotAccessChromeUrl
));
1089 // chrome.tabs.setZoomSettings().
1090 error
= RunSetZoomSettingsExpectError(tab_id
, "manual", "per-tab");
1091 EXPECT_TRUE(MatchPattern(error
, manifest_errors::kCannotAccessChromeUrl
));
1094 } // namespace extensions