Enable Enterprise enrollment on desktop builds.
[chromium-blink-merge.git] / chrome / browser / extensions / api / extension_action / browser_action_apitest.cc
blob1aacf4982c8d1bbbdb4d7261baff454ce1356af5
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.
5 #include "build/build_config.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/extensions/browser_action_test_util.h"
9 #include "chrome/browser/extensions/extension_action.h"
10 #include "chrome/browser/extensions/extension_action_icon_factory.h"
11 #include "chrome/browser/extensions/extension_action_manager.h"
12 #include "chrome/browser/extensions/extension_apitest.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_tab_util.h"
15 #include "chrome/browser/extensions/extension_toolbar_model.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/browser_commands.h"
19 #include "chrome/browser/ui/browser_window.h"
20 #include "chrome/browser/ui/tabs/tab_strip_model.h"
21 #include "chrome/common/url_constants.h"
22 #include "chrome/test/base/ui_test_utils.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/test/browser_test_utils.h"
26 #include "extensions/browser/extension_system.h"
27 #include "extensions/common/feature_switch.h"
28 #include "grit/theme_resources.h"
29 #include "ui/base/resource/resource_bundle.h"
30 #include "ui/gfx/image/image_skia.h"
31 #include "ui/gfx/image/image_skia_operations.h"
32 #include "ui/gfx/rect.h"
33 #include "ui/gfx/size.h"
34 #include "ui/gfx/skia_util.h"
36 using content::WebContents;
38 namespace extensions {
39 namespace {
41 const char kEmptyImageDataError[] =
42 "The imageData property must contain an ImageData object or dictionary "
43 "of ImageData objects.";
44 const char kEmptyPathError[] = "The path property must not be empty.";
46 // Views implementation of browser action button will return icon whose
47 // background will be set.
48 gfx::ImageSkia AddBackgroundForViews(const gfx::ImageSkia& icon) {
49 #if defined(TOOLKIT_VIEWS)
50 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
51 gfx::ImageSkia bg = *rb.GetImageSkiaNamed(IDR_BROWSER_ACTION);
52 return gfx::ImageSkiaOperations::CreateSuperimposedImage(bg, icon);
53 #else
54 return icon;
55 #endif
58 bool ImagesAreEqualAtScale(const gfx::ImageSkia& i1,
59 const gfx::ImageSkia& i2,
60 float scale) {
61 SkBitmap bitmap1 = i1.GetRepresentation(scale).sk_bitmap();
62 SkBitmap bitmap2 = i2.GetRepresentation(scale).sk_bitmap();
63 return gfx::BitmapsAreEqual(bitmap1, bitmap2);
66 class BrowserActionApiTest : public ExtensionApiTest {
67 public:
68 BrowserActionApiTest() {}
69 virtual ~BrowserActionApiTest() {}
71 protected:
72 BrowserActionTestUtil GetBrowserActionsBar() {
73 return BrowserActionTestUtil(browser());
76 bool OpenPopup(int index) {
77 ResultCatcher catcher;
78 content::WindowedNotificationObserver popup_observer(
79 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
80 content::NotificationService::AllSources());
81 GetBrowserActionsBar().Press(index);
82 popup_observer.Wait();
83 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
84 return GetBrowserActionsBar().HasPopup();
87 ExtensionAction* GetBrowserAction(const Extension& extension) {
88 return ExtensionActionManager::Get(browser()->profile())->
89 GetBrowserAction(extension);
93 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, Basic) {
94 ASSERT_TRUE(test_server()->Start());
95 ASSERT_TRUE(RunExtensionTest("browser_action/basics")) << message_;
96 const Extension* extension = GetSingleLoadedExtension();
97 ASSERT_TRUE(extension) << message_;
99 // Test that there is a browser action in the toolbar.
100 ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
102 // Tell the extension to update the browser action state.
103 ResultCatcher catcher;
104 ui_test_utils::NavigateToURL(browser(),
105 GURL(extension->GetResourceURL("update.html")));
106 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
108 // Test that we received the changes.
109 ExtensionAction* action = GetBrowserAction(*extension);
110 ASSERT_EQ("Modified", action->GetTitle(ExtensionAction::kDefaultTabId));
111 ASSERT_EQ("badge", action->GetBadgeText(ExtensionAction::kDefaultTabId));
112 ASSERT_EQ(SkColorSetARGB(255, 255, 255, 255),
113 action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId));
115 // Simulate the browser action being clicked.
116 ui_test_utils::NavigateToURL(browser(),
117 test_server()->GetURL("files/extensions/test_file.txt"));
119 ExtensionToolbarModel* toolbar_model = ExtensionToolbarModel::Get(
120 browser()->profile());
121 toolbar_model->ExecuteBrowserAction(extension, browser(), NULL, true);
123 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
126 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, DynamicBrowserAction) {
127 ASSERT_TRUE(RunExtensionTest("browser_action/no_icon")) << message_;
128 const Extension* extension = GetSingleLoadedExtension();
129 ASSERT_TRUE(extension) << message_;
131 #if defined (OS_MACOSX)
132 // We need this on mac so we don't loose 2x representations from browser icon
133 // in transformations gfx::ImageSkia -> NSImage -> gfx::ImageSkia.
134 std::vector<ui::ScaleFactor> supported_scale_factors;
135 supported_scale_factors.push_back(ui::SCALE_FACTOR_100P);
136 supported_scale_factors.push_back(ui::SCALE_FACTOR_200P);
137 ui::SetSupportedScaleFactors(supported_scale_factors);
138 #endif
140 // We should not be creating icons asynchronously, so we don't need an
141 // observer.
142 ExtensionActionIconFactory icon_factory(
143 profile(),
144 extension,
145 GetBrowserAction(*extension),
146 NULL);
147 // Test that there is a browser action in the toolbar.
148 ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
149 EXPECT_TRUE(GetBrowserActionsBar().HasIcon(0));
151 gfx::Image action_icon = icon_factory.GetIcon(0);
152 uint32_t action_icon_last_id = action_icon.ToSkBitmap()->getGenerationID();
154 // Let's check that |GetIcon| doesn't always return bitmap with new id.
155 ASSERT_EQ(action_icon_last_id,
156 icon_factory.GetIcon(0).ToSkBitmap()->getGenerationID());
158 uint32_t action_icon_current_id = 0;
160 ResultCatcher catcher;
162 // Tell the extension to update the icon using ImageData object.
163 GetBrowserActionsBar().Press(0);
164 ASSERT_TRUE(catcher.GetNextResult());
166 action_icon = icon_factory.GetIcon(0);
168 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
169 EXPECT_GT(action_icon_current_id, action_icon_last_id);
170 action_icon_last_id = action_icon_current_id;
172 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f));
174 EXPECT_TRUE(
175 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()),
176 *GetBrowserActionsBar().GetIcon(0).ToImageSkia(),
177 1.0f));
179 // Tell the extension to update the icon using path.
180 GetBrowserActionsBar().Press(0);
181 ASSERT_TRUE(catcher.GetNextResult());
183 action_icon = icon_factory.GetIcon(0);
185 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
186 EXPECT_GT(action_icon_current_id, action_icon_last_id);
187 action_icon_last_id = action_icon_current_id;
189 EXPECT_FALSE(
190 action_icon.ToImageSkia()->HasRepresentation(2.0f));
192 EXPECT_TRUE(
193 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()),
194 *GetBrowserActionsBar().GetIcon(0).ToImageSkia(),
195 1.0f));
197 // Tell the extension to update the icon using dictionary of ImageData
198 // objects.
199 GetBrowserActionsBar().Press(0);
200 ASSERT_TRUE(catcher.GetNextResult());
202 action_icon = icon_factory.GetIcon(0);
204 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
205 EXPECT_GT(action_icon_current_id, action_icon_last_id);
206 action_icon_last_id = action_icon_current_id;
208 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(2.0f));
210 EXPECT_TRUE(
211 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()),
212 *GetBrowserActionsBar().GetIcon(0).ToImageSkia(),
213 1.0f));
215 // Tell the extension to update the icon using dictionary of paths.
216 GetBrowserActionsBar().Press(0);
217 ASSERT_TRUE(catcher.GetNextResult());
219 action_icon = icon_factory.GetIcon(0);
221 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
222 EXPECT_GT(action_icon_current_id, action_icon_last_id);
223 action_icon_last_id = action_icon_current_id;
225 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(2.0f));
227 EXPECT_TRUE(
228 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()),
229 *GetBrowserActionsBar().GetIcon(0).ToImageSkia(),
230 1.0f));
232 // Tell the extension to update the icon using dictionary of ImageData
233 // objects, but setting only size 19.
234 GetBrowserActionsBar().Press(0);
235 ASSERT_TRUE(catcher.GetNextResult());
237 action_icon = icon_factory.GetIcon(0);
239 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
240 EXPECT_GT(action_icon_current_id, action_icon_last_id);
241 action_icon_last_id = action_icon_current_id;
243 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f));
245 EXPECT_TRUE(
246 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()),
247 *GetBrowserActionsBar().GetIcon(0).ToImageSkia(),
248 1.0f));
250 // Tell the extension to update the icon using dictionary of paths, but
251 // setting only size 19.
252 GetBrowserActionsBar().Press(0);
253 ASSERT_TRUE(catcher.GetNextResult());
255 action_icon = icon_factory.GetIcon(0);
257 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
258 EXPECT_GT(action_icon_current_id, action_icon_last_id);
259 action_icon_last_id = action_icon_current_id;
261 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f));
263 EXPECT_TRUE(
264 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()),
265 *GetBrowserActionsBar().GetIcon(0).ToImageSkia(),
266 1.0f));
268 // Tell the extension to update the icon using dictionary of ImageData
269 // objects, but setting only size 38.
270 GetBrowserActionsBar().Press(0);
271 ASSERT_TRUE(catcher.GetNextResult());
273 action_icon = icon_factory.GetIcon(0);
275 const gfx::ImageSkia* action_icon_skia = action_icon.ToImageSkia();
277 EXPECT_FALSE(action_icon_skia->HasRepresentation(1.0f));
278 EXPECT_TRUE(action_icon_skia->HasRepresentation(2.0f));
280 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
281 EXPECT_GT(action_icon_current_id, action_icon_last_id);
282 action_icon_last_id = action_icon_current_id;
284 EXPECT_TRUE(gfx::BitmapsAreEqual(
285 *action_icon.ToSkBitmap(),
286 action_icon_skia->GetRepresentation(2.0f).sk_bitmap()));
288 EXPECT_TRUE(
289 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon_skia),
290 *GetBrowserActionsBar().GetIcon(0).ToImageSkia(),
291 2.0f));
293 // Try setting icon with empty dictionary of ImageData objects.
294 GetBrowserActionsBar().Press(0);
295 ASSERT_FALSE(catcher.GetNextResult());
296 EXPECT_EQ(kEmptyImageDataError, catcher.message());
298 // Try setting icon with empty dictionary of path objects.
299 GetBrowserActionsBar().Press(0);
300 ASSERT_FALSE(catcher.GetNextResult());
301 EXPECT_EQ(kEmptyPathError, catcher.message());
304 // This test is flaky as per http://crbug.com/74557.
305 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest,
306 DISABLED_TabSpecificBrowserActionState) {
307 ASSERT_TRUE(RunExtensionTest("browser_action/tab_specific_state")) <<
308 message_;
309 const Extension* extension = GetSingleLoadedExtension();
310 ASSERT_TRUE(extension) << message_;
312 // Test that there is a browser action in the toolbar and that it has an icon.
313 ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
314 EXPECT_TRUE(GetBrowserActionsBar().HasIcon(0));
316 // Execute the action, its title should change.
317 ResultCatcher catcher;
318 GetBrowserActionsBar().Press(0);
319 ASSERT_TRUE(catcher.GetNextResult());
320 EXPECT_EQ("Showing icon 2", GetBrowserActionsBar().GetTooltip(0));
322 // Open a new tab, the title should go back.
323 chrome::NewTab(browser());
324 EXPECT_EQ("hi!", GetBrowserActionsBar().GetTooltip(0));
326 // Go back to first tab, changed title should reappear.
327 browser()->tab_strip_model()->ActivateTabAt(0, true);
328 EXPECT_EQ("Showing icon 2", GetBrowserActionsBar().GetTooltip(0));
330 // Reload that tab, default title should come back.
331 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
332 EXPECT_EQ("hi!", GetBrowserActionsBar().GetTooltip(0));
335 // http://code.google.com/p/chromium/issues/detail?id=70829
336 // Mac used to be ok, but then mac 10.5 started failing too. =(
337 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, DISABLED_BrowserActionPopup) {
338 ASSERT_TRUE(
339 LoadExtension(test_data_dir_.AppendASCII("browser_action/popup")));
340 BrowserActionTestUtil actions_bar = GetBrowserActionsBar();
341 const Extension* extension = GetSingleLoadedExtension();
342 ASSERT_TRUE(extension) << message_;
344 // The extension's popup's size grows by |growFactor| each click.
345 const int growFactor = 500;
346 gfx::Size minSize = BrowserActionTestUtil::GetMinPopupSize();
347 gfx::Size middleSize = gfx::Size(growFactor, growFactor);
348 gfx::Size maxSize = BrowserActionTestUtil::GetMaxPopupSize();
350 // Ensure that two clicks will exceed the maximum allowed size.
351 ASSERT_GT(minSize.height() + growFactor * 2, maxSize.height());
352 ASSERT_GT(minSize.width() + growFactor * 2, maxSize.width());
354 // Simulate a click on the browser action and verify the size of the resulting
355 // popup. The first one tries to be 0x0, so it should be the min values.
356 ASSERT_TRUE(OpenPopup(0));
357 EXPECT_EQ(minSize, actions_bar.GetPopupBounds().size());
358 EXPECT_TRUE(actions_bar.HidePopup());
360 ASSERT_TRUE(OpenPopup(0));
361 EXPECT_EQ(middleSize, actions_bar.GetPopupBounds().size());
362 EXPECT_TRUE(actions_bar.HidePopup());
364 // One more time, but this time it should be constrained by the max values.
365 ASSERT_TRUE(OpenPopup(0));
366 EXPECT_EQ(maxSize, actions_bar.GetPopupBounds().size());
367 EXPECT_TRUE(actions_bar.HidePopup());
370 // Test that calling chrome.browserAction.setPopup() can enable and change
371 // a popup.
372 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, BrowserActionAddPopup) {
373 ASSERT_TRUE(RunExtensionTest("browser_action/add_popup")) << message_;
374 const Extension* extension = GetSingleLoadedExtension();
375 ASSERT_TRUE(extension) << message_;
377 int tab_id = ExtensionTabUtil::GetTabId(
378 browser()->tab_strip_model()->GetActiveWebContents());
380 ExtensionAction* browser_action = GetBrowserAction(*extension);
381 ASSERT_TRUE(browser_action)
382 << "Browser action test extension should have a browser action.";
384 ASSERT_FALSE(browser_action->HasPopup(tab_id));
385 ASSERT_FALSE(browser_action->HasPopup(ExtensionAction::kDefaultTabId));
387 // Simulate a click on the browser action icon. The onClicked handler
388 // will add a popup.
390 ResultCatcher catcher;
391 GetBrowserActionsBar().Press(0);
392 ASSERT_TRUE(catcher.GetNextResult());
395 // The call to setPopup in background.html set a tab id, so the
396 // current tab's setting should have changed, but the default setting
397 // should not have changed.
398 ASSERT_TRUE(browser_action->HasPopup(tab_id))
399 << "Clicking on the browser action should have caused a popup to "
400 << "be added.";
401 ASSERT_FALSE(browser_action->HasPopup(ExtensionAction::kDefaultTabId))
402 << "Clicking on the browser action should not have set a default "
403 << "popup.";
405 ASSERT_STREQ("/a_popup.html",
406 browser_action->GetPopupUrl(tab_id).path().c_str());
408 // Now change the popup from a_popup.html to another_popup.html by loading
409 // a page which removes the popup using chrome.browserAction.setPopup().
411 ResultCatcher catcher;
412 ui_test_utils::NavigateToURL(
413 browser(),
414 GURL(extension->GetResourceURL("change_popup.html")));
415 ASSERT_TRUE(catcher.GetNextResult());
418 // The call to setPopup in change_popup.html did not use a tab id,
419 // so the default setting should have changed as well as the current tab.
420 ASSERT_TRUE(browser_action->HasPopup(tab_id));
421 ASSERT_TRUE(browser_action->HasPopup(ExtensionAction::kDefaultTabId));
422 ASSERT_STREQ("/another_popup.html",
423 browser_action->GetPopupUrl(tab_id).path().c_str());
426 // Test that calling chrome.browserAction.setPopup() can remove a popup.
427 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, BrowserActionRemovePopup) {
428 // Load the extension, which has a browser action with a default popup.
429 ASSERT_TRUE(RunExtensionTest("browser_action/remove_popup")) << message_;
430 const Extension* extension = GetSingleLoadedExtension();
431 ASSERT_TRUE(extension) << message_;
433 int tab_id = ExtensionTabUtil::GetTabId(
434 browser()->tab_strip_model()->GetActiveWebContents());
436 ExtensionAction* browser_action = GetBrowserAction(*extension);
437 ASSERT_TRUE(browser_action)
438 << "Browser action test extension should have a browser action.";
440 ASSERT_TRUE(browser_action->HasPopup(tab_id))
441 << "Expect a browser action popup before the test removes it.";
442 ASSERT_TRUE(browser_action->HasPopup(ExtensionAction::kDefaultTabId))
443 << "Expect a browser action popup is the default for all tabs.";
445 // Load a page which removes the popup using chrome.browserAction.setPopup().
447 ResultCatcher catcher;
448 ui_test_utils::NavigateToURL(
449 browser(),
450 GURL(extension->GetResourceURL("remove_popup.html")));
451 ASSERT_TRUE(catcher.GetNextResult());
454 ASSERT_FALSE(browser_action->HasPopup(tab_id))
455 << "Browser action popup should have been removed.";
456 ASSERT_TRUE(browser_action->HasPopup(ExtensionAction::kDefaultTabId))
457 << "Browser action popup default should not be changed by setting "
458 << "a specific tab id.";
461 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, IncognitoBasic) {
462 ASSERT_TRUE(test_server()->Start());
464 ASSERT_TRUE(RunExtensionTest("browser_action/basics")) << message_;
465 const Extension* extension = GetSingleLoadedExtension();
466 ASSERT_TRUE(extension) << message_;
468 // Test that there is a browser action in the toolbar.
469 ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
471 // Open an incognito window and test that the browser action isn't there by
472 // default.
473 Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
474 Browser* incognito_browser =
475 new Browser(Browser::CreateParams(incognito_profile,
476 browser()->host_desktop_type()));
478 ASSERT_EQ(0,
479 BrowserActionTestUtil(incognito_browser).NumberOfBrowserActions());
481 // Now enable the extension in incognito mode, and test that the browser
482 // action shows up. Note that we don't update the existing window at the
483 // moment, so we just create a new one.
484 extensions::ExtensionPrefs::Get(browser()->profile())
485 ->SetIsIncognitoEnabled(extension->id(), true);
487 chrome::CloseWindow(incognito_browser);
488 incognito_browser =
489 new Browser(Browser::CreateParams(incognito_profile,
490 browser()->host_desktop_type()));
491 ASSERT_EQ(1,
492 BrowserActionTestUtil(incognito_browser).NumberOfBrowserActions());
494 // TODO(mpcomplete): simulate a click and have it do the right thing in
495 // incognito.
498 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, IncognitoDragging) {
499 ExtensionService* service = extensions::ExtensionSystem::Get(
500 browser()->profile())->extension_service();
502 // The tooltips for each respective browser action.
503 const char kTooltipA[] = "Alpha";
504 const char kTooltipB[] = "Beta";
505 const char kTooltipC[] = "Gamma";
507 const size_t size_before = service->extensions()->size();
509 base::FilePath test_dir = test_data_dir_.AppendASCII("browser_action");
510 const Extension* extension_a = InstallExtension(
511 test_dir.AppendASCII("empty_browser_action_alpha.crx"), 1);
512 const Extension* extension_b = InstallExtension(
513 test_dir.AppendASCII("empty_browser_action_beta.crx"), 1);
514 const Extension* extension_c = InstallExtension(
515 test_dir.AppendASCII("empty_browser_action_gamma.crx"), 1);
516 ASSERT_TRUE(extension_a);
517 ASSERT_TRUE(extension_b);
518 ASSERT_TRUE(extension_c);
520 // Test that there are 3 browser actions in the toolbar.
521 ASSERT_EQ(size_before + 3, service->extensions()->size());
522 ASSERT_EQ(3, GetBrowserActionsBar().NumberOfBrowserActions());
524 // Now enable 2 of the extensions in incognito mode, and test that the browser
525 // actions show up.
526 extensions::ExtensionPrefs* prefs =
527 extensions::ExtensionPrefs::Get(browser()->profile());
528 prefs->SetIsIncognitoEnabled(extension_a->id(), true);
529 prefs->SetIsIncognitoEnabled(extension_c->id(), true);
531 Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
532 Browser* incognito_browser =
533 new Browser(Browser::CreateParams(incognito_profile,
534 browser()->host_desktop_type()));
535 BrowserActionTestUtil incognito_bar(incognito_browser);
537 // Navigate just to have a tab in this window, otherwise wonky things happen.
538 ui_test_utils::OpenURLOffTheRecord(browser()->profile(), GURL("about:blank"));
540 ASSERT_EQ(2, incognito_bar.NumberOfBrowserActions());
542 // Ensure that the browser actions are in the right order (ABC).
543 EXPECT_EQ(kTooltipA, GetBrowserActionsBar().GetTooltip(0));
544 EXPECT_EQ(kTooltipB, GetBrowserActionsBar().GetTooltip(1));
545 EXPECT_EQ(kTooltipC, GetBrowserActionsBar().GetTooltip(2));
547 EXPECT_EQ(kTooltipA, incognito_bar.GetTooltip(0));
548 EXPECT_EQ(kTooltipC, incognito_bar.GetTooltip(1));
550 // Now rearrange them and ensure that they are rearranged correctly in both
551 // regular and incognito mode.
553 // ABC -> CAB
554 ExtensionToolbarModel* toolbar_model = ExtensionToolbarModel::Get(
555 browser()->profile());
556 toolbar_model->MoveBrowserAction(extension_c, 0);
558 EXPECT_EQ(kTooltipC, GetBrowserActionsBar().GetTooltip(0));
559 EXPECT_EQ(kTooltipA, GetBrowserActionsBar().GetTooltip(1));
560 EXPECT_EQ(kTooltipB, GetBrowserActionsBar().GetTooltip(2));
562 EXPECT_EQ(kTooltipC, incognito_bar.GetTooltip(0));
563 EXPECT_EQ(kTooltipA, incognito_bar.GetTooltip(1));
565 // CAB -> CBA
566 toolbar_model->MoveBrowserAction(extension_b, 1);
568 EXPECT_EQ(kTooltipC, GetBrowserActionsBar().GetTooltip(0));
569 EXPECT_EQ(kTooltipB, GetBrowserActionsBar().GetTooltip(1));
570 EXPECT_EQ(kTooltipA, GetBrowserActionsBar().GetTooltip(2));
572 EXPECT_EQ(kTooltipC, incognito_bar.GetTooltip(0));
573 EXPECT_EQ(kTooltipA, incognito_bar.GetTooltip(1));
576 // Tests that events are dispatched to the correct profile for split mode
577 // extensions.
578 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, IncognitoSplit) {
579 ResultCatcher catcher;
580 const Extension* extension = LoadExtensionWithFlags(
581 test_data_dir_.AppendASCII("browser_action/split_mode"),
582 kFlagEnableIncognito);
583 ASSERT_TRUE(extension) << message_;
585 // Open an incognito window.
586 Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
587 Browser* incognito_browser =
588 new Browser(Browser::CreateParams(incognito_profile,
589 browser()->host_desktop_type()));
590 // Navigate just to have a tab in this window, otherwise wonky things happen.
591 ui_test_utils::OpenURLOffTheRecord(browser()->profile(), GURL("about:blank"));
592 ASSERT_EQ(1,
593 BrowserActionTestUtil(incognito_browser).NumberOfBrowserActions());
595 // A click in the regular profile should open a tab in the regular profile.
596 ExtensionToolbarModel* toolbar_model = ExtensionToolbarModel::Get(
597 browser()->profile());
598 toolbar_model->ExecuteBrowserAction(extension, browser(), NULL, true);
599 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
601 // A click in the incognito profile should open a tab in the
602 // incognito profile.
603 toolbar_model->ExecuteBrowserAction(extension, incognito_browser, NULL, true);
604 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
607 // Disabled because of failures (crashes) on ASAN bot.
608 // See http://crbug.com/98861.
609 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, DISABLED_CloseBackgroundPage) {
610 ASSERT_TRUE(LoadExtension(
611 test_data_dir_.AppendASCII("browser_action/close_background")));
612 const Extension* extension = GetSingleLoadedExtension();
614 // There is a background page and a browser action with no badge text.
615 extensions::ProcessManager* manager =
616 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
617 ASSERT_TRUE(manager->GetBackgroundHostForExtension(extension->id()));
618 ExtensionAction* action = GetBrowserAction(*extension);
619 ASSERT_EQ("", action->GetBadgeText(ExtensionAction::kDefaultTabId));
621 content::WindowedNotificationObserver host_destroyed_observer(
622 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
623 content::NotificationService::AllSources());
625 // Click the browser action.
626 ExtensionToolbarModel* toolbar_model = ExtensionToolbarModel::Get(
627 browser()->profile());
628 toolbar_model->ExecuteBrowserAction(extension, browser(), NULL, true);
630 // It can take a moment for the background page to actually get destroyed
631 // so we wait for the notification before checking that it's really gone
632 // and the badge text has been set.
633 host_destroyed_observer.Wait();
634 ASSERT_FALSE(manager->GetBackgroundHostForExtension(extension->id()));
635 ASSERT_EQ("X", action->GetBadgeText(ExtensionAction::kDefaultTabId));
638 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, BadgeBackgroundColor) {
639 ASSERT_TRUE(test_server()->Start());
640 ASSERT_TRUE(RunExtensionTest("browser_action/color")) << message_;
641 const Extension* extension = GetSingleLoadedExtension();
642 ASSERT_TRUE(extension) << message_;
644 // Test that there is a browser action in the toolbar.
645 ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
647 // Test that CSS values (#FF0000) set color correctly.
648 ExtensionAction* action = GetBrowserAction(*extension);
649 ASSERT_EQ(SkColorSetARGB(255, 255, 0, 0),
650 action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId));
652 // Tell the extension to update the browser action state.
653 ResultCatcher catcher;
654 ui_test_utils::NavigateToURL(browser(),
655 GURL(extension->GetResourceURL("update.html")));
656 ASSERT_TRUE(catcher.GetNextResult());
658 // Test that CSS values (#0F0) set color correctly.
659 ASSERT_EQ(SkColorSetARGB(255, 0, 255, 0),
660 action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId));
662 ui_test_utils::NavigateToURL(browser(),
663 GURL(extension->GetResourceURL("update2.html")));
664 ASSERT_TRUE(catcher.GetNextResult());
666 // Test that array values set color correctly.
667 ASSERT_EQ(SkColorSetARGB(255, 255, 255, 255),
668 action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId));
671 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, Getters) {
672 ASSERT_TRUE(RunExtensionTest("browser_action/getters")) << message_;
673 const Extension* extension = GetSingleLoadedExtension();
674 ASSERT_TRUE(extension) << message_;
676 // Test that there is a browser action in the toolbar.
677 ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
679 // Test the getters for defaults.
680 ResultCatcher catcher;
681 ui_test_utils::NavigateToURL(browser(),
682 GURL(extension->GetResourceURL("update.html")));
683 ASSERT_TRUE(catcher.GetNextResult());
685 // Test the getters for a specific tab.
686 ui_test_utils::NavigateToURL(browser(),
687 GURL(extension->GetResourceURL("update2.html")));
688 ASSERT_TRUE(catcher.GetNextResult());
691 // Verify triggering browser action.
692 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, TestTriggerBrowserAction) {
693 ASSERT_TRUE(test_server()->Start());
695 ASSERT_TRUE(RunExtensionTest("trigger_actions/browser_action")) << message_;
696 const Extension* extension = GetSingleLoadedExtension();
697 ASSERT_TRUE(extension) << message_;
699 // Test that there is a browser action in the toolbar.
700 ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
702 ui_test_utils::NavigateToURL(
703 browser(),
704 test_server()->GetURL("files/simple.html"));
706 ExtensionAction* browser_action = GetBrowserAction(*extension);
707 EXPECT_TRUE(browser_action != NULL);
709 // Simulate a click on the browser action icon.
711 ResultCatcher catcher;
712 GetBrowserActionsBar().Press(0);
713 EXPECT_TRUE(catcher.GetNextResult());
716 WebContents* tab =
717 browser()->tab_strip_model()->GetActiveWebContents();
718 EXPECT_TRUE(tab != NULL);
720 // Verify that the browser action turned the background color red.
721 const std::string script =
722 "window.domAutomationController.send(document.body.style."
723 "backgroundColor);";
724 std::string result;
725 EXPECT_TRUE(content::ExecuteScriptAndExtractString(tab, script, &result));
726 EXPECT_EQ(result, "red");
729 } // namespace
730 } // namespace extensions