| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/memory/raw_ptr.h" |
| |
| #import <Cocoa/Cocoa.h> |
| |
| #include "base/apple/foundation_util.h" |
| #include "base/mac/mac_util.h" |
| #include "base/strings/sys_string_conversions.h" |
| #include "chrome/app/chrome_command_ids.h" |
| #include "chrome/browser/command_updater.h" |
| #include "chrome/browser/search_engines/template_url_service_factory_test_util.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_command_controller.h" |
| #include "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" |
| #import "chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h" |
| #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" |
| #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/test/base/browser_with_test_window_test.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "content/public/test/test_renderer_host.h" |
| #include "content/public/test/web_contents_tester.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "testing/gtest_mac.h" |
| #import "ui/base/cocoa/touch_bar_util.h" |
| #include "ui/base/l10n/l10n_util_mac.h" |
| |
| class BrowserWindowDefaultTouchBarUnitTest : public BrowserWithTestWindowTest { |
| public: |
| void SetUp() override { |
| BrowserWithTestWindowTest::SetUp(); |
| |
| // The touch bar can show a search engine prompt, which requires this |
| // service. |
| template_service_util_ = |
| std::make_unique<TemplateURLServiceFactoryTestUtil>(profile()); |
| template_service_util_->VerifyLoad(); |
| |
| command_updater_ = browser()->command_controller(); |
| |
| browser()->tab_strip_model()->AppendWebContents( |
| content::WebContentsTester::CreateTestWebContents(profile(), nullptr), |
| true); |
| |
| touch_bar_ = [[BrowserWindowDefaultTouchBar alloc] init]; |
| touch_bar_.browser = browser(); |
| } |
| |
| void UpdateCommandEnabled(int id, bool enabled) { |
| command_updater_->UpdateCommandEnabled(id, enabled); |
| } |
| |
| bool ShowsHomeButton() { |
| return browser()->profile()->GetPrefs()->GetBoolean(prefs::kShowHomeButton); |
| } |
| |
| void SetShowHomeButton(bool flag) { |
| browser()->profile()->GetPrefs()->SetBoolean(prefs::kShowHomeButton, flag); |
| } |
| |
| void TearDown() override { |
| touch_bar_.browser = nullptr; |
| touch_bar_ = nil; |
| |
| BrowserWithTestWindowTest::TearDown(); |
| } |
| |
| CocoaTestHelper cocoa_test_helper_; |
| raw_ptr<CommandUpdater, DanglingUntriaged> |
| command_updater_; // Weak, owned by Browser. |
| |
| std::unique_ptr<TemplateURLServiceFactoryTestUtil> template_service_util_; |
| |
| BrowserWindowDefaultTouchBar* __strong touch_bar_; |
| }; |
| |
| // Test if any known identifiers no longer work. See the message in the test; |
| // these identifiers may be written out to disk on users' computers if they |
| // customize the Touch Bar, and the corresponding items will disappear if they |
| // can no longer be created. |
| TEST_F(BrowserWindowDefaultTouchBarUnitTest, HistoricTouchBarItems) { |
| NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; |
| for (NSString* item_identifier : { |
| @"BACK-FWD", |
| @"BACK", |
| @"FORWARD", |
| @"RELOAD-STOP", |
| @"HOME", |
| @"SEARCH", |
| @"BOOKMARK", |
| @"NEW-TAB", |
| }) { |
| auto identifier = ui::GetTouchBarItemId(@"browser-window", item_identifier); |
| EXPECT_NE(nil, [touch_bar itemForIdentifier:identifier]) |
| << "BrowserWindowDefaultTouchBar didn't return a Touch Bar item for " |
| "an identifier that was once available (" |
| << identifier.UTF8String |
| << "). If a user's customized Touch Bar includes this item, it will " |
| "disappear! Do not update or remove entries in this list just to " |
| "make the test pass; keep supporting old identifiers when " |
| "possible, even if they're no longer part of the set of " |
| "default/customizable items."; |
| } |
| } |
| |
| // Tests if BrowserWindowDefaultTouchBar can produce the items it says it can |
| // and, for each kind of bar, also verify that the advertised/customizable lists |
| // include some representative items (if not, the lists might be wrong.) |
| TEST_F(BrowserWindowDefaultTouchBarUnitTest, TouchBarItems) { |
| auto test_default_identifiers = [&](NSSet* expected_identifiers) { |
| NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; |
| NSMutableSet<NSString*>* advertised_identifiers = [NSMutableSet set]; |
| [advertised_identifiers |
| addObjectsFromArray:touch_bar.defaultItemIdentifiers]; |
| [advertised_identifiers |
| addObjectsFromArray:touch_bar.customizationAllowedItemIdentifiers]; |
| [advertised_identifiers |
| addObjectsFromArray:touch_bar.customizationRequiredItemIdentifiers]; |
| EXPECT_TRUE([expected_identifiers isSubsetOfSet:advertised_identifiers]) |
| << "Didn't find the expected identifiers " |
| << expected_identifiers.description.UTF8String |
| << " in the set of advertised identifiers " |
| << advertised_identifiers.description.UTF8String << "."; |
| for (NSString* identifier in advertised_identifiers) { |
| EXPECT_NE(nil, [touch_bar itemForIdentifier:identifier]) |
| << "Didn't get a touch bar item for " << identifier.UTF8String; |
| } |
| }; |
| |
| // Set to tab fullscreen. |
| FullscreenController* fullscreen_controller = |
| browser()->exclusive_access_manager()->fullscreen_controller(); |
| fullscreen_controller->set_is_tab_fullscreen_for_testing(true); |
| EXPECT_TRUE(fullscreen_controller->IsTabFullscreen()); |
| |
| // The fullscreen Touch Bar should include *at least* these items. |
| test_default_identifiers([NSSet setWithArray:@[ |
| BrowserWindowDefaultTouchBar.fullscreenOriginItemIdentifier, |
| ]]); |
| |
| // Exit fullscreen. |
| fullscreen_controller->set_is_tab_fullscreen_for_testing(false); |
| EXPECT_FALSE(fullscreen_controller->IsTabFullscreen()); |
| |
| // The default Touch Bar should include *at least* these items. |
| test_default_identifiers([NSSet setWithArray:@[ |
| BrowserWindowDefaultTouchBar.backItemIdentifier, |
| BrowserWindowDefaultTouchBar.forwardItemIdentifier, |
| BrowserWindowDefaultTouchBar.reloadOrStopItemIdentifier, |
| ]]); |
| } |
| |
| // Tests the reload or stop touch bar item. |
| TEST_F(BrowserWindowDefaultTouchBarUnitTest, ReloadOrStopTouchBarItem) { |
| NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; |
| [touch_bar_ setIsPageLoading:NO]; |
| |
| NSTouchBarItem* item = |
| [touch_bar itemForIdentifier:BrowserWindowDefaultTouchBar |
| .reloadOrStopItemIdentifier]; |
| NSButton* button = base::apple::ObjCCast<NSButton>([item view]); |
| EXPECT_EQ(IDC_RELOAD, [button tag]); |
| EXPECT_EQ([BrowserWindowDefaultTouchBar reloadIcon], [button image]); |
| |
| [touch_bar_ setIsPageLoading:YES]; |
| item = [touch_bar itemForIdentifier:BrowserWindowDefaultTouchBar |
| .reloadOrStopItemIdentifier]; |
| button = base::apple::ObjCCast<NSButton>([item view]); |
| EXPECT_EQ(IDC_STOP, [button tag]); |
| EXPECT_EQ([BrowserWindowDefaultTouchBar navigateStopIcon], [button image]); |
| } |
| |
| // Tests the bookmark star touch bar item. |
| TEST_F(BrowserWindowDefaultTouchBarUnitTest, BookmkarStarTouchBarItem) { |
| NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; |
| |
| [touch_bar_ setIsStarred:NO]; |
| NSTouchBarItem* item = |
| [touch_bar itemForIdentifier:BrowserWindowDefaultTouchBar |
| .bookmarkStarItemIdentifier]; |
| NSButton* button = base::apple::ObjCCast<NSButton>([item view]); |
| EXPECT_EQ([BrowserWindowDefaultTouchBar starDefaultIcon], [button image]); |
| |
| [touch_bar_ setIsStarred:YES]; |
| item = [touch_bar itemForIdentifier:BrowserWindowDefaultTouchBar |
| .bookmarkStarItemIdentifier]; |
| button = base::apple::ObjCCast<NSButton>([item view]); |
| EXPECT_EQ([BrowserWindowDefaultTouchBar starActiveIcon], [button image]); |
| } |
| |
| // Tests if the back button on the touch bar is in sync with the back command. |
| TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackCommandUpdate) { |
| NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; |
| NSTouchBarItem* item = [touch_bar |
| itemForIdentifier:BrowserWindowDefaultTouchBar.backItemIdentifier]; |
| NSButton* button = base::apple::ObjCCast<NSButton>(item.view); |
| |
| UpdateCommandEnabled(IDC_BACK, true); |
| EXPECT_TRUE(button.enabled); |
| UpdateCommandEnabled(IDC_BACK, false); |
| EXPECT_FALSE(button.enabled); |
| } |
| |
| // Tests if the forward button on the touch bar is in sync with the forward |
| // command. |
| TEST_F(BrowserWindowDefaultTouchBarUnitTest, ForwardCommandUpdate) { |
| NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; |
| NSTouchBarItem* item = [touch_bar |
| itemForIdentifier:BrowserWindowDefaultTouchBar.forwardItemIdentifier]; |
| NSButton* button = base::apple::ObjCCast<NSButton>(item.view); |
| |
| UpdateCommandEnabled(IDC_FORWARD, true); |
| EXPECT_TRUE(button.enabled); |
| UpdateCommandEnabled(IDC_FORWARD, false); |
| EXPECT_FALSE(button.enabled); |
| } |
| |
| TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackAccessibilityLabel) { |
| NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; |
| NSTouchBarItem* item = [touch_bar |
| itemForIdentifier:BrowserWindowDefaultTouchBar.backItemIdentifier]; |
| id<NSAccessibility> view = item.view; |
| ASSERT_TRUE([view conformsToProtocol:@protocol(NSAccessibility)]); |
| EXPECT_NSEQ(view.accessibilityTitle, |
| l10n_util::GetNSString(IDS_ACCNAME_BACK)); |
| } |
| |
| TEST_F(BrowserWindowDefaultTouchBarUnitTest, ForwardAccessibilityLabel) { |
| NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; |
| NSTouchBarItem* item = [touch_bar |
| itemForIdentifier:BrowserWindowDefaultTouchBar.forwardItemIdentifier]; |
| id<NSAccessibility> view = item.view; |
| ASSERT_TRUE([view conformsToProtocol:@protocol(NSAccessibility)]); |
| EXPECT_NSEQ(view.accessibilityTitle, |
| l10n_util::GetNSString(IDS_ACCNAME_FORWARD)); |
| } |
| |
| // Tests that the home button in the Touch Bar is in sync with the setting. |
| TEST_F(BrowserWindowDefaultTouchBarUnitTest, HomeUpdate) { |
| NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; |
| |
| // Save the current state before we start mucking with preferences. |
| bool home_button_showing = ShowsHomeButton(); |
| |
| SetShowHomeButton(false); |
| touch_bar = [touch_bar_ makeTouchBar]; |
| |
| NSString* home_identifier = [BrowserWindowDefaultTouchBar homeItemIdentifier]; |
| |
| EXPECT_FALSE( |
| [[touch_bar defaultItemIdentifiers] containsObject:home_identifier]); |
| |
| SetShowHomeButton(true); |
| touch_bar = [touch_bar_ makeTouchBar]; |
| |
| EXPECT_TRUE( |
| [[touch_bar defaultItemIdentifiers] containsObject:home_identifier]); |
| |
| // Restore the original state. |
| SetShowHomeButton(home_button_showing); |
| } |