| // Copyright 2012 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/functional/bind.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/run_loop.h" |
| #include "base/scoped_observation.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/test/bind.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/metrics/user_action_tester.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "base/timer/timer.h" |
| #include "build/build_config.h" |
| #include "chrome/app/chrome_command_ids.h" |
| #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h" |
| #include "chrome/browser/platform_util.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/tab_group_sync/tab_group_sync_service_factory.h" |
| #include "chrome/browser/ui/bookmarks/bookmark_bar_controller.h" |
| #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" |
| #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" |
| #include "chrome/browser/ui/bookmarks/bookmark_utils_desktop.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_commands.h" |
| #include "chrome/browser/ui/browser_element_identifiers.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/browser/ui/browser_window/public/browser_window_features.h" |
| #include "chrome/browser/ui/browser_window/public/browser_window_interface.h" |
| #include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" |
| #include "chrome/browser/ui/tabs/tab_group_model.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/ui/ui_features.h" |
| #include "chrome/common/webui_url_constants.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/bookmarks/browser/bookmark_model.h" |
| #include "components/bookmarks/browser/bookmark_utils.h" |
| #include "components/bookmarks/browser/url_and_title.h" |
| #include "components/bookmarks/test/bookmark_test_helpers.h" |
| #include "components/saved_tab_groups/public/tab_group_sync_service.h" |
| #include "components/security_interstitials/content/security_interstitial_tab_helper.h" |
| #include "components/signin/public/base/signin_switches.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "content/public/test/prerender_test_util.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "net/test/embedded_test_server/embedded_test_server.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h" |
| #include "ui/base/dragdrop/os_exchange_data.h" |
| #include "ui/base/interaction/element_tracker.h" |
| #include "ui/base/ui_base_features.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/views/controls/button/checkbox.h" |
| #include "ui/views/interaction/element_tracker_views.h" |
| #include "ui/views/test/button_test_api.h" |
| #include "ui/views/widget/any_widget_observer.h" |
| #include "ui/views/widget/widget.h" |
| #include "ui/views/widget/widget_delegate.h" |
| #include "ui/views/window/dialog_delegate.h" |
| |
| using bookmarks::BookmarkModel; |
| using bookmarks::BookmarkNode; |
| using bookmarks::UrlAndTitle; |
| |
| namespace { |
| |
| const char kPersistBookmarkURL[] = "http://www.cnn.com/"; |
| const char16_t kPersistBookmarkTitle[] = u"CNN"; |
| const base::Time kPersistLastUsedTime = |
| base::Time() + base::Days(7) + base::Hours(2) + base::Minutes(55) + |
| base::Seconds(24) + base::Milliseconds(133); |
| |
| } // namespace |
| |
| class TestBookmarkTabHelperObserver : public BookmarkTabHelperObserver { |
| public: |
| explicit TestBookmarkTabHelperObserver(BookmarkTabHelper* helper) { |
| observation_.Observe(helper); |
| } |
| |
| TestBookmarkTabHelperObserver(const TestBookmarkTabHelperObserver&) = delete; |
| TestBookmarkTabHelperObserver& operator=( |
| const TestBookmarkTabHelperObserver&) = delete; |
| |
| ~TestBookmarkTabHelperObserver() override = default; |
| |
| void URLStarredChanged(content::WebContents*, bool starred) override { |
| starred_ = starred; |
| } |
| bool is_starred() const { return starred_; } |
| |
| private: |
| base::ScopedObservation<BookmarkTabHelper, BookmarkTabHelperObserver> |
| observation_{this}; |
| |
| bool starred_ = false; |
| }; |
| |
| class BookmarkBrowsertest : public InProcessBrowserTest { |
| public: |
| BookmarkBrowsertest() { |
| feature_list_.InitWithFeatures( |
| /*enabled_features=*/{switches::kSyncEnableBookmarksInTransportMode, |
| features::kBookmarkTabGroupConversion}, |
| /*disabled_features=*/{ |
| #if BUILDFLAG(IS_WIN) |
| // This needs to be disabled so that animations are guaranteed to |
| // work. |
| features::kApplyNativeOcclusionToCompositor |
| #endif |
| }); |
| } |
| |
| BookmarkBrowsertest(const BookmarkBrowsertest&) = delete; |
| BookmarkBrowsertest& operator=(const BookmarkBrowsertest&) = delete; |
| |
| bool IsVisible() { |
| return BookmarkBarController::From(browser())->bookmark_bar_state() == |
| BookmarkBar::SHOW; |
| } |
| |
| static void CheckAnimation(Browser* browser, base::RunLoop* loop) { |
| if (!browser->window()->IsBookmarkBarAnimating()) { |
| loop->Quit(); |
| } |
| } |
| |
| base::TimeDelta WaitForBookmarkBarAnimationToFinish() { |
| base::Time start(base::Time::Now()); |
| { |
| base::RunLoop loop; |
| base::RepeatingTimer timer; |
| timer.Start(FROM_HERE, base::Milliseconds(15), |
| base::BindRepeating(&CheckAnimation, browser(), &loop)); |
| loop.Run(); |
| } |
| return base::Time::Now() - start; |
| } |
| |
| BookmarkModel* WaitForBookmarkModel(Profile* profile) { |
| BookmarkModel* bookmark_model = |
| BookmarkModelFactory::GetForBrowserContext(profile); |
| bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model); |
| return bookmark_model; |
| } |
| |
| base::HistogramTester* histogram_tester() { return &histogram_tester_; } |
| |
| private: |
| base::test::ScopedFeatureList feature_list_; |
| |
| // We make the histogram tester a member field to make sure it starts |
| // recording as early as possible. |
| base::HistogramTester histogram_tester_; |
| }; |
| |
| // Test of bookmark bar toggling, visibility, and animation. |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, BookmarkBarVisibleWait) { |
| ASSERT_FALSE(IsVisible()); |
| chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR); |
| base::TimeDelta delay = WaitForBookmarkBarAnimationToFinish(); |
| LOG(INFO) << "Took " << delay.InMilliseconds() << " ms to show bookmark bar"; |
| ASSERT_TRUE(IsVisible()); |
| chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR); |
| delay = WaitForBookmarkBarAnimationToFinish(); |
| LOG(INFO) << "Took " << delay.InMilliseconds() << " ms to hide bookmark bar"; |
| ASSERT_FALSE(IsVisible()); |
| } |
| |
| // Verify that bookmarks persist browser restart. |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, PRE_Persist) { |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| |
| const BookmarkNode* node = bookmarks::AddIfNotBookmarked( |
| bookmark_model, GURL(kPersistBookmarkURL), kPersistBookmarkTitle); |
| bookmark_model->UpdateLastUsedTime(node, kPersistLastUsedTime, |
| /*just_opened=*/true); |
| } |
| |
| #if BUILDFLAG(IS_WIN) |
| // TODO(crbug.com/41443454): The test fails on Windows. |
| #define MAYBE_Persist DISABLED_Persist |
| #else |
| #define MAYBE_Persist Persist |
| #endif |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, MAYBE_Persist) { |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| |
| GURL url(kPersistBookmarkURL); |
| std::vector<raw_ptr<const BookmarkNode, VectorExperimental>> nodes = |
| bookmark_model->GetNodesByURL(url); |
| |
| ASSERT_EQ(1u, nodes.size()); |
| ASSERT_EQ(url, nodes[0]->url()); |
| ASSERT_EQ(kPersistBookmarkTitle, nodes[0]->GetTitledUrlNodeTitle()); |
| EXPECT_EQ(kPersistLastUsedTime, nodes[0]->date_last_used()); |
| } |
| |
| #if !BUILDFLAG(IS_CHROMEOS) // No multi-profile on ChromeOS. |
| |
| // Sanity check that bookmarks from different profiles are separate. |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, MultiProfile) { |
| BookmarkModel* bookmark_model1 = WaitForBookmarkModel(browser()->profile()); |
| |
| base::RunLoop run_loop; |
| Profile* profile2 = nullptr; |
| g_browser_process->profile_manager()->CreateMultiProfileAsync( |
| u"New Profile", 0, false, |
| base::BindLambdaForTesting([&](Profile* profile) { |
| if (profile) { |
| profile2 = profile; |
| run_loop.Quit(); |
| } |
| })); |
| run_loop.Run(); |
| BookmarkModel* bookmark_model2 = WaitForBookmarkModel(profile2); |
| |
| bookmarks::AddIfNotBookmarked(bookmark_model1, GURL(kPersistBookmarkURL), |
| kPersistBookmarkTitle); |
| |
| ASSERT_EQ(1u, bookmark_model1->GetUniqueUrls().size()); |
| ASSERT_TRUE(bookmark_model2->GetUniqueUrls().empty()); |
| } |
| |
| #endif |
| |
| // Sanity check that bookmarks from Incognito mode persist Incognito restart. |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, IncognitoPersistence) { |
| Browser* incognito_browser = CreateIncognitoBrowser(); |
| BookmarkModel* bookmark_model = |
| WaitForBookmarkModel(incognito_browser->profile()); |
| |
| // Add bookmark for Incognito and ensure it is added. |
| bookmarks::AddIfNotBookmarked(bookmark_model, GURL(kPersistBookmarkURL), |
| kPersistBookmarkTitle); |
| |
| ASSERT_EQ(1u, bookmark_model->GetUniqueUrls().size()); |
| |
| // Restart Incognito, and check again. |
| CloseBrowserSynchronously(incognito_browser); |
| incognito_browser = CreateIncognitoBrowser(); |
| bookmark_model = WaitForBookmarkModel(incognito_browser->profile()); |
| ASSERT_EQ(1u, bookmark_model->GetUniqueUrls().size()); |
| |
| // Ensure it is also available in regular mode. |
| bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| ASSERT_EQ(1u, bookmark_model->GetUniqueUrls().size()); |
| } |
| |
| // Regression for crash caused by opening folder as a group in an incognito |
| // window when the folder contains URLs that cannot be displayed in incognito. |
| // See discussion starting at crbug.com/1242351#c15 |
| IN_PROC_BROWSER_TEST_F( |
| BookmarkBrowsertest, |
| OpenFolderAsGroupInIncognitoWhenBookmarksCantOpenInIncognito) { |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| const BookmarkNode* const folder = bookmark_model->AddFolder( |
| bookmark_model->bookmark_bar_node(), 0, u"Folder"); |
| const BookmarkNode* const page1 = bookmark_model->AddURL( |
| folder, 0, u"Extensions", GURL(chrome::kChromeUIExtensionsURL)); |
| const BookmarkNode* const page2 = bookmark_model->AddURL( |
| folder, 1, u"Settings", GURL(chrome::kChromeUISettingsURL)); |
| |
| Browser* incognito_browser = CreateIncognitoBrowser(); |
| BookmarkModel* incognito_model = |
| WaitForBookmarkModel(incognito_browser->profile()); |
| ASSERT_FALSE(incognito_model->root_node()->children().empty()); |
| ASSERT_TRUE(incognito_model->root_node()->children()[0]->is_folder()); |
| BookmarkNode* const incognito_folder = |
| incognito_model->bookmark_bar_node()->children()[0].get(); |
| ASSERT_EQ(2U, incognito_folder->children().size()); |
| EXPECT_EQ(page1->url(), incognito_folder->children()[0]->url()); |
| EXPECT_EQ(page2->url(), incognito_folder->children()[1]->url()); |
| |
| const int browser_tabs = browser()->tab_strip_model()->GetTabCount(); |
| const int incognito_tabs = |
| incognito_browser->tab_strip_model()->GetTabCount(); |
| |
| bookmarks::OpenAllIfAllowed(incognito_browser, {incognito_folder}, |
| WindowOpenDisposition::NEW_BACKGROUND_TAB, |
| bookmarks::OpenAllBookmarksContext::kInGroup); |
| |
| EXPECT_EQ(incognito_tabs, |
| incognito_browser->tab_strip_model()->GetTabCount()); |
| EXPECT_EQ(browser_tabs + 2, browser()->tab_strip_model()->GetTabCount()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, |
| ConvertBookmarkFolderToGroupCreateNewGroup) { |
| base::UserActionTester user_action_tester; |
| // Create a bookmark folder with 2 urls. |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| const BookmarkNode* const folder = bookmark_model->AddFolder( |
| bookmark_model->bookmark_bar_node(), 0, u"Folder"); |
| bookmark_model->AddURL(folder, 0, u"Extensions", |
| GURL(chrome::kChromeUIExtensionsURL)); |
| const BookmarkNode* bookmark_node = bookmark_model->AddURL( |
| folder, 1, u"Settings", GURL(chrome::kChromeUISettingsURL)); |
| |
| tab_groups::TabGroupSyncService* tab_group_service = |
| tab_groups::TabGroupSyncServiceFactory::GetForProfile( |
| browser()->profile()); |
| CHECK(tab_group_service); |
| |
| // Convert to saved tab group for the first time. |
| { |
| EXPECT_EQ( |
| 0u, |
| browser()->tab_strip_model()->group_model()->ListTabGroups().size()); |
| |
| bookmarks::OpenAllIfAllowed(browser(), {folder}, |
| WindowOpenDisposition::NEW_BACKGROUND_TAB, |
| bookmarks::OpenAllBookmarksContext::kInGroup); |
| |
| ASSERT_EQ( |
| 1u, |
| browser()->tab_strip_model()->group_model()->ListTabGroups().size()); |
| |
| auto saved_tab_group1 = tab_group_service->GetGroup( |
| browser()->tab_strip_model()->group_model()->ListTabGroups()[0]); |
| ASSERT_TRUE(saved_tab_group1.has_value()); |
| ASSERT_EQ(2u, saved_tab_group1->saved_tabs().size()); |
| ASSERT_EQ(GURL(chrome::kChromeUIExtensionsURL), |
| saved_tab_group1->saved_tabs()[0].url()); |
| ASSERT_EQ(GURL(chrome::kChromeUISettingsURL), |
| saved_tab_group1->saved_tabs()[1].url()); |
| } |
| |
| // Remove a bookmark node and add a new one. |
| bookmark_model->Remove( |
| bookmark_node, bookmarks::metrics::BookmarkEditSource::kOther, FROM_HERE); |
| bookmark_model->AddURL(folder, 1, u"Version", |
| GURL(chrome::kChromeUIVersionURL)); |
| |
| // Convert to saved tab group for the second time. |
| // User chooses to create new group. |
| { |
| views::NamedWidgetShownWaiter waiter( |
| views::test::AnyWidgetTestPasskey{}, |
| bookmarks::kReplaceOrCreateGroupDialogName); |
| |
| bookmarks::OpenAllIfAllowed(browser(), {folder}, |
| WindowOpenDisposition::NEW_BACKGROUND_TAB, |
| bookmarks::OpenAllBookmarksContext::kInGroup); |
| |
| views::Widget* dialog_widget = waiter.WaitIfNeededAndGet(); |
| ASSERT_NE(nullptr, dialog_widget); |
| dialog_widget->widget_delegate()->AsDialogDelegate()->Accept(); |
| } |
| |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "BookmarkTabGroupConversion_UserSelectCreateNewGroup")); |
| |
| EXPECT_EQ( |
| 2u, browser()->tab_strip_model()->group_model()->ListTabGroups().size()); |
| |
| // Verify group1 has the original URLS and group2 has the updated URLs. |
| { |
| auto saved_tab_group1 = tab_group_service->GetGroup( |
| browser()->tab_strip_model()->group_model()->ListTabGroups()[0]); |
| ASSERT_TRUE(saved_tab_group1.has_value()); |
| ASSERT_EQ(2u, saved_tab_group1->saved_tabs().size()); |
| ASSERT_EQ(GURL(chrome::kChromeUIExtensionsURL), |
| saved_tab_group1->saved_tabs()[0].url()); |
| ASSERT_EQ(GURL(chrome::kChromeUISettingsURL), |
| saved_tab_group1->saved_tabs()[1].url()); |
| |
| auto saved_tab_group2 = tab_group_service->GetGroup( |
| browser()->tab_strip_model()->group_model()->ListTabGroups()[1]); |
| ASSERT_TRUE(saved_tab_group2.has_value()); |
| ASSERT_EQ(2u, saved_tab_group2->saved_tabs().size()); |
| ASSERT_EQ(GURL(chrome::kChromeUIExtensionsURL), |
| saved_tab_group2->saved_tabs()[0].url()); |
| ASSERT_EQ(GURL(chrome::kChromeUIVersionURL), |
| saved_tab_group2->saved_tabs()[1].url()); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, |
| ConvertBookmarkFolderToGroupOverrideOldGroup) { |
| base::UserActionTester user_action_tester; |
| // Create a bookmark folder with 2 urls. |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| const BookmarkNode* const folder = bookmark_model->AddFolder( |
| bookmark_model->bookmark_bar_node(), 0, u"Folder"); |
| bookmark_model->AddURL(folder, 0, u"Extensions", |
| GURL(chrome::kChromeUIExtensionsURL)); |
| const BookmarkNode* bookmark_node = bookmark_model->AddURL( |
| folder, 1, u"Settings", GURL(chrome::kChromeUISettingsURL)); |
| |
| tab_groups::TabGroupSyncService* tab_group_service = |
| tab_groups::TabGroupSyncServiceFactory::GetForProfile( |
| browser()->profile()); |
| CHECK(tab_group_service); |
| |
| // Convert to saved tab group for the first time. |
| { |
| EXPECT_EQ( |
| 0u, |
| browser()->tab_strip_model()->group_model()->ListTabGroups().size()); |
| |
| bookmarks::OpenAllIfAllowed(browser(), {folder}, |
| WindowOpenDisposition::NEW_BACKGROUND_TAB, |
| bookmarks::OpenAllBookmarksContext::kInGroup); |
| |
| ASSERT_EQ( |
| 1u, |
| browser()->tab_strip_model()->group_model()->ListTabGroups().size()); |
| |
| auto saved_tab_group1 = tab_group_service->GetGroup( |
| browser()->tab_strip_model()->group_model()->ListTabGroups()[0]); |
| ASSERT_TRUE(saved_tab_group1.has_value()); |
| ASSERT_EQ(2u, saved_tab_group1->saved_tabs().size()); |
| ASSERT_EQ(GURL(chrome::kChromeUIExtensionsURL), |
| saved_tab_group1->saved_tabs()[0].url()); |
| ASSERT_EQ(GURL(chrome::kChromeUISettingsURL), |
| saved_tab_group1->saved_tabs()[1].url()); |
| } |
| |
| // Remove a bookmark node and add a new one. |
| bookmark_model->Remove( |
| bookmark_node, bookmarks::metrics::BookmarkEditSource::kOther, FROM_HERE); |
| bookmark_model->AddURL(folder, 1, u"Version", |
| GURL(chrome::kChromeUIVersionURL)); |
| |
| // Convert to saved tab group for the second time. |
| // User chooses to override the existing group. |
| { |
| views::NamedWidgetShownWaiter waiter( |
| views::test::AnyWidgetTestPasskey{}, |
| bookmarks::kReplaceOrCreateGroupDialogName); |
| |
| bookmarks::OpenAllIfAllowed(browser(), {folder}, |
| WindowOpenDisposition::NEW_BACKGROUND_TAB, |
| bookmarks::OpenAllBookmarksContext::kInGroup); |
| |
| views::Widget* dialog_widget = waiter.WaitIfNeededAndGet(); |
| ASSERT_NE(nullptr, dialog_widget); |
| |
| // Find and check the checkbox. |
| const ui::ElementContext context = |
| views::ElementTrackerViews::GetContextForView( |
| dialog_widget->GetContentsView()); |
| views::Checkbox* checkbox = |
| views::ElementTrackerViews::GetInstance() |
| ->GetUniqueViewAs<views::Checkbox>( |
| kBookmarkReplaceOldGroupCheckboxId, context); |
| CHECK(checkbox); |
| ui::MouseEvent released_event(ui::EventType::kMouseReleased, gfx::PointF(), |
| gfx::PointF(), base::TimeTicks(), 0, 0); |
| views::test::ButtonTestApi(checkbox).NotifyClick(released_event); |
| |
| dialog_widget->widget_delegate()->AsDialogDelegate()->Accept(); |
| } |
| |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "BookmarkTabGroupConversion_UserSelectReplaceOldGroup")); |
| |
| // Verify group1 has the updated URLs. |
| auto saved_tab_group1 = tab_group_service->GetGroup( |
| browser()->tab_strip_model()->group_model()->ListTabGroups()[0]); |
| ASSERT_TRUE(saved_tab_group1.has_value()); |
| ASSERT_EQ(2u, saved_tab_group1->saved_tabs().size()); |
| ASSERT_EQ(GURL(chrome::kChromeUIExtensionsURL), |
| saved_tab_group1->saved_tabs()[0].url()); |
| ASSERT_EQ(GURL(chrome::kChromeUIVersionURL), |
| saved_tab_group1->saved_tabs()[1].url()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, OpenAllBookmarks) { |
| Browser* regular_browser = browser(); |
| BookmarkModel* bookmark_model = |
| WaitForBookmarkModel(regular_browser->profile()); |
| const BookmarkNode* const bbar = bookmark_model->bookmark_bar_node(); |
| ASSERT_TRUE(bbar->children().empty()); |
| |
| Browser* incognito_browser = CreateIncognitoBrowser(); |
| BookmarkModel* incognito_model = |
| WaitForBookmarkModel(incognito_browser->profile()); |
| const BookmarkNode* const incognito_bbar = |
| incognito_model->bookmark_bar_node(); |
| |
| auto close_all_tabs_except_first = [](Browser* browser) { |
| int num_tabs = browser->tab_strip_model()->GetTabCount(); |
| for (int i = 0; i < num_tabs - 1; ++i) { |
| browser->tab_strip_model()->CloseWebContentsAt(num_tabs - 1 - i, 0); |
| } |
| EXPECT_EQ(1, browser->tab_strip_model()->count()); |
| }; |
| |
| auto open_urls_and_test = [®ular_browser, &incognito_browser, &bbar, |
| &close_all_tabs_except_first, this]() { |
| // open all in new tab from regular browser |
| { |
| close_all_tabs_except_first(regular_browser); |
| close_all_tabs_except_first(incognito_browser); |
| bookmarks::OpenAllIfAllowed(regular_browser, {bbar}, |
| WindowOpenDisposition::NEW_BACKGROUND_TAB); |
| int num_tabs_regular = regular_browser->tab_strip_model()->GetTabCount(); |
| int num_tabs_incognito = |
| incognito_browser->tab_strip_model()->GetTabCount(); |
| EXPECT_EQ(num_tabs_regular, 5); |
| EXPECT_EQ(num_tabs_incognito, 1); |
| } |
| |
| // open all in a new window from regular browser |
| { |
| close_all_tabs_except_first(regular_browser); |
| close_all_tabs_except_first(incognito_browser); |
| bookmarks::OpenAllIfAllowed(regular_browser, {bbar}, |
| WindowOpenDisposition::NEW_WINDOW); |
| BrowserWindowInterface* regular_browser2 = nullptr; |
| ForEachCurrentBrowserWindowInterfaceOrderedByActivation( |
| [&](BrowserWindowInterface* browser) { |
| if (browser != incognito_browser && browser != regular_browser) { |
| regular_browser2 = browser; |
| } |
| return !regular_browser2; |
| }); |
| // new browser needs to be opened |
| EXPECT_NE(regular_browser2, nullptr); |
| int num_tabs_regular = regular_browser->tab_strip_model()->GetTabCount(); |
| int num_tabs_regular2 = |
| regular_browser2->GetTabStripModel()->GetTabCount(); |
| EXPECT_EQ(num_tabs_regular, 1); |
| EXPECT_EQ(num_tabs_regular2, 4); |
| CloseBrowserSynchronously(regular_browser2); |
| } |
| |
| // open all in a new incognito window from regular browser |
| { |
| close_all_tabs_except_first(regular_browser); |
| close_all_tabs_except_first(incognito_browser); |
| bookmarks::OpenAllIfAllowed(regular_browser, {bbar}, |
| WindowOpenDisposition::OFF_THE_RECORD); |
| int num_tabs_incognito = |
| incognito_browser->tab_strip_model()->GetTabCount(); |
| EXPECT_EQ(num_tabs_incognito, 3); |
| } |
| }; |
| |
| auto open_urls_from_incognito_and_test = [®ular_browser, |
| &incognito_browser, &incognito_bbar, |
| &close_all_tabs_except_first, |
| this]() { |
| // open all in new tab from incognito |
| { |
| close_all_tabs_except_first(regular_browser); |
| close_all_tabs_except_first(incognito_browser); |
| bookmarks::OpenAllIfAllowed(incognito_browser, {incognito_bbar}, |
| WindowOpenDisposition::NEW_BACKGROUND_TAB); |
| int num_tabs_regular = regular_browser->tab_strip_model()->GetTabCount(); |
| int num_tabs_incognito = |
| incognito_browser->tab_strip_model()->GetTabCount(); |
| EXPECT_EQ(num_tabs_regular, 3); |
| EXPECT_EQ(num_tabs_incognito, 3); |
| } |
| |
| // open all in new window from incognito |
| { |
| close_all_tabs_except_first(regular_browser); |
| close_all_tabs_except_first(incognito_browser); |
| bookmarks::OpenAllIfAllowed(incognito_browser, {incognito_bbar}, |
| WindowOpenDisposition::NEW_WINDOW); |
| BrowserWindowInterface* incognito_browser2 = nullptr; |
| ForEachCurrentBrowserWindowInterfaceOrderedByActivation( |
| [&](BrowserWindowInterface* browser) { |
| if (browser != incognito_browser && browser != regular_browser) { |
| incognito_browser2 = browser; |
| } |
| return !incognito_browser2; |
| }); |
| // new browser needs to be opened |
| EXPECT_NE(incognito_browser2, nullptr); |
| int num_tabs_regular = regular_browser->tab_strip_model()->GetTabCount(); |
| int num_tabs_incognito = |
| incognito_browser->tab_strip_model()->GetTabCount(); |
| int num_tabs_incognito2 = |
| incognito_browser2->GetTabStripModel()->GetTabCount(); |
| EXPECT_EQ(num_tabs_regular, 3); |
| EXPECT_EQ(num_tabs_incognito, 1); |
| EXPECT_EQ(num_tabs_incognito2, 2); |
| CloseBrowserSynchronously(incognito_browser2); |
| } |
| }; |
| |
| { |
| // Bookmark 4 pages, with the first and third one not being able to be |
| // opened in incognito mode |
| bookmark_model->AddURL(bbar, 0, u"Settings", |
| GURL(chrome::kChromeUISettingsURL)); |
| bookmark_model->AddURL(bbar, 1, u"Google", GURL("http://www.google.com")); |
| bookmark_model->AddURL(bbar, 2, u"Extensions", |
| GURL(chrome::kChromeUIExtensionsURL)); |
| bookmark_model->AddURL(bbar, 3, u"Gmail", GURL("http://mail.google.com")); |
| open_urls_and_test(); |
| open_urls_from_incognito_and_test(); |
| bookmark_model->RemoveAllUserBookmarks(FROM_HERE); |
| } |
| { |
| // Bookmark 4 pages, with the second and fourth one not being able to be |
| // opened in incognito mode |
| bookmark_model->AddURL(bbar, 0, u"Google", GURL("http://www.google.com")); |
| bookmark_model->AddURL(bbar, 1, u"Settings", |
| GURL(chrome::kChromeUISettingsURL)); |
| bookmark_model->AddURL(bbar, 2, u"Gmail", GURL("http://mail.google.com")); |
| bookmark_model->AddURL(bbar, 3, u"Extensions", |
| GURL(chrome::kChromeUIExtensionsURL)); |
| open_urls_and_test(); |
| open_urls_from_incognito_and_test(); |
| bookmark_model->RemoveAllUserBookmarks(FROM_HERE); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, |
| HideStarOnNonbookmarkedInterstitial) { |
| // Start an HTTPS server with a certificate error. |
| net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); |
| https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); |
| https_server.ServeFilesFromSourceDirectory(GetChromeTestDataDir()); |
| ASSERT_TRUE(https_server.Start()); |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| GURL bookmark_url = embedded_test_server()->GetURL("example.test", "/"); |
| bookmarks::AddIfNotBookmarked(bookmark_model, bookmark_url, u"Bookmark"); |
| |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| BookmarkTabHelper* tab_helper = |
| BookmarkTabHelper::FromWebContents(web_contents); |
| TestBookmarkTabHelperObserver bookmark_observer(tab_helper); |
| |
| // Go to a bookmarked url. Bookmark star should show. |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), bookmark_url)); |
| EXPECT_FALSE( |
| chrome_browser_interstitials::IsShowingInterstitial(web_contents)); |
| EXPECT_TRUE(bookmark_observer.is_starred()); |
| // Now go to a non-bookmarked url which triggers an SSL warning. Bookmark |
| // star should disappear. |
| GURL error_url = https_server.GetURL("/"); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), error_url)); |
| web_contents = browser()->tab_strip_model()->GetActiveWebContents(); |
| EXPECT_TRUE( |
| chrome_browser_interstitials::IsShowingInterstitial(web_contents)); |
| EXPECT_FALSE(bookmark_observer.is_starred()); |
| } |
| |
| // Provides coverage for the Bookmark Manager bookmark drag and drag image |
| // generation for dragging a single bookmark. |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, DragSingleBookmark) { |
| BookmarkModel* model = WaitForBookmarkModel(browser()->profile()); |
| const std::u16string page_title(u"foo"); |
| const GURL page_url("http://www.google.com"); |
| const BookmarkNode* root = model->bookmark_bar_node(); |
| const BookmarkNode* node = model->AddURL(root, 0, page_title, page_url); |
| const gfx::Point expected_point(100, 100); |
| |
| auto run_loop = std::make_unique<base::RunLoop>(); |
| |
| chrome::DoBookmarkDragCallback cb = base::BindLambdaForTesting( |
| [&run_loop, page_title, page_url, expected_point]( |
| std::unique_ptr<ui::OSExchangeData> drag_data, |
| gfx::NativeView native_view, ui::mojom::DragEventSource source, |
| gfx::Point point, int operation) { |
| std::vector<ui::ClipboardUrlInfo> url_infos = |
| drag_data->GetURLsAndTitles( |
| ui::FilenameToURLPolicy::DO_NOT_CONVERT_FILENAMES); |
| ASSERT_FALSE(url_infos.empty()); |
| EXPECT_EQ(page_url, url_infos.front().url); |
| EXPECT_EQ(page_title, url_infos.front().title); |
| #if !BUILDFLAG(IS_WIN) |
| // On Windows, GetDragImage() is a NOTREACHED() as the Windows |
| // implementation of OSExchangeData just sets the drag image on the OS |
| // API. https://crbug.com/893388 |
| EXPECT_FALSE(drag_data->provider().GetDragImage().isNull()); |
| #endif |
| EXPECT_EQ(expected_point, point); |
| run_loop->Quit(); |
| }); |
| |
| constexpr int kDragNodeIndex = 0; |
| chrome::DragBookmarksForTest( |
| browser()->profile(), |
| {{node}, |
| kDragNodeIndex, |
| browser()->tab_strip_model()->GetActiveWebContents(), |
| ui::mojom::DragEventSource::kMouse, |
| expected_point}, |
| std::move(cb)); |
| |
| run_loop->Run(); |
| } |
| |
| // A favicon update during drag shouldn't trigger the drag flow again. The test |
| // passes if the favicon update does not cause a crash. (see |
| // https://crbug.com/1364056) |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, FaviconChangeDuringBookmarkDrag) { |
| BookmarkModel* model = WaitForBookmarkModel(browser()->profile()); |
| const std::u16string kPageTitle(u"foo"); |
| const GURL kPageUrl("http://www.google.com"); |
| const GURL kFaviconUrl("http://www.google.com/favicon.ico"); |
| const BookmarkNode* root = model->bookmark_bar_node(); |
| const BookmarkNode* node = model->AddURL(root, 0, kPageTitle, kPageUrl); |
| constexpr gfx::Point kExpectedPoint(100, 100); |
| |
| auto run_loop = std::make_unique<base::RunLoop>(); |
| |
| chrome::DoBookmarkDragCallback cb = base::BindLambdaForTesting( |
| [&run_loop, model, kPageUrl, kFaviconUrl]( |
| std::unique_ptr<ui::OSExchangeData> drag_data, |
| gfx::NativeView native_view, ui::mojom::DragEventSource source, |
| gfx::Point point, int operation) { |
| // Simulate a favicon change during the drag operation. |
| model->OnFaviconsChanged({kPageUrl}, kFaviconUrl); |
| run_loop->Quit(); |
| }); |
| |
| constexpr int kDragNodeIndex = 0; |
| chrome::DragBookmarksForTest( |
| browser()->profile(), |
| {{node}, |
| kDragNodeIndex, |
| browser()->tab_strip_model()->GetActiveWebContents(), |
| ui::mojom::DragEventSource::kMouse, |
| kExpectedPoint}, |
| std::move(cb)); |
| |
| run_loop->Run(); |
| } |
| |
| // Provides coverage for the Bookmark Manager bookmark drag and drag image |
| // generation for dragging multiple bookmarks. |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, DragMultipleBookmarks) { |
| BookmarkModel* model = WaitForBookmarkModel(browser()->profile()); |
| const std::u16string page_title = u"foo"; |
| const GURL page_url("http://www.google.com"); |
| const BookmarkNode* root = model->bookmark_bar_node(); |
| const BookmarkNode* node1 = model->AddURL(root, 0, page_title, page_url); |
| const BookmarkNode* node2 = model->AddFolder(root, 0, page_title); |
| const gfx::Point expected_point(100, 100); |
| |
| auto run_loop = std::make_unique<base::RunLoop>(); |
| |
| chrome::DoBookmarkDragCallback cb = base::BindLambdaForTesting( |
| [&run_loop, expected_point, page_title, page_url]( |
| std::unique_ptr<ui::OSExchangeData> drag_data, |
| gfx::NativeView native_view, ui::mojom::DragEventSource source, |
| gfx::Point point, int operation) { |
| const std::vector<ui::ClipboardUrlInfo> url_infos = |
| drag_data->GetURLsAndTitles( |
| ui::FilenameToURLPolicy::DO_NOT_CONVERT_FILENAMES); |
| ASSERT_FALSE(url_infos.empty()); |
| |
| // The bookmarks are added in order, and the first is retrieved, so |
| // expect the values from the first bookmark. |
| // TODO(http://crbug.com/41011768): test the bookmark folder. |
| EXPECT_EQ(page_title, url_infos.front().title); |
| EXPECT_EQ(page_url, url_infos.front().url); |
| #if !BUILDFLAG(IS_WIN) |
| // On Windows, GetDragImage() is a NOTREACHED() as the Windows |
| // implementation of OSExchangeData just sets the drag image on the OS |
| // API. https://crbug.com/893388 |
| EXPECT_FALSE(drag_data->provider().GetDragImage().isNull()); |
| #endif |
| EXPECT_EQ(expected_point, point); |
| run_loop->Quit(); |
| }); |
| |
| constexpr int kDragNodeIndex = 1; |
| chrome::DragBookmarksForTest( |
| browser()->profile(), |
| { |
| {node1, node2}, |
| kDragNodeIndex, |
| browser()->tab_strip_model()->GetActiveWebContents(), |
| ui::mojom::DragEventSource::kMouse, |
| expected_point, |
| }, |
| std::move(cb)); |
| |
| run_loop->Run(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, PRE_EmitUmaForTimeMetrics) { |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| const BookmarkNode* parent = bookmarks::GetParentForNewNodes(bookmark_model); |
| const BookmarkNode* other_parent = |
| bookmark_model->AddFolder(parent, 0, u"Folder"); |
| |
| // Add one bookmark with a unique URL, two other bookmarks with a shared URL, |
| // and three more with another shared URL. |
| bookmark_model->AddURL(parent, parent->children().size(), u"title1", |
| GURL("http://a.com")); |
| bookmark_model->AddURL(parent, parent->children().size(), u"title2", |
| GURL("http://b.com")); |
| bookmark_model->AddURL(parent, parent->children().size(), u"title3", |
| GURL("http://b.com")); |
| bookmark_model->AddURL(parent, parent->children().size(), u"title4", |
| GURL("http://c.com")); |
| bookmark_model->AddURL(parent, parent->children().size(), u"title5", |
| GURL("http://c.com")); |
| bookmark_model->AddURL(parent, parent->children().size(), u"title5", |
| GURL("http://c.com")); |
| bookmark_model->AddURL(other_parent, other_parent->children().size(), |
| u"title5", GURL("http://c.com")); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, EmitUmaForTimeMetrics) { |
| WaitForBookmarkModel(browser()->profile()); |
| |
| // The total number of bookmarks is 7, but it gets rounded down due to |
| // bucketing. |
| ASSERT_THAT( |
| histogram_tester()->GetAllSamples("Bookmarks.Count.OnProfileLoad3"), |
| testing::ElementsAre(base::Bucket(/*min=*/6, /*count=*/1))); |
| |
| EXPECT_THAT(histogram_tester()->GetAllSamples( |
| "Bookmarks.Times.OnProfileLoad.TimeSinceAdded3"), |
| testing::ElementsAre(base::Bucket(/*min=*/0, /*count=*/1))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, PRE_EmitUmaForMostRecentlyUsed) { |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| BookmarkNode* parent = const_cast<BookmarkNode*>(bookmark_model->AddFolder( |
| bookmarks::GetParentForNewNodes(bookmark_model), 0, u"Test Folder")); |
| parent->set_date_added(base::Time::Now() - base::Days(3)); |
| |
| BookmarkNode* node = const_cast<BookmarkNode*>(bookmark_model->AddURL( |
| parent, parent->children().size(), u"title1", GURL("http://a.com"))); |
| node->set_date_added(base::Time::Now() - base::Days(2)); |
| node->set_date_last_used(base::Time::Now() - base::Days(1)); |
| |
| // This shouldn't count towards metrics because there's another node which |
| // is more recently saved/used. |
| node = const_cast<BookmarkNode*>(bookmark_model->AddURL( |
| parent, parent->children().size(), u"title1", GURL("http://a.com"))); |
| node->set_date_added(base::Time::Now() - base::Days(3)); |
| node->set_date_last_used(base::Time::Now() - base::Days(3)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, EmitUmaForMostRecentlyUsed) { |
| WaitForBookmarkModel(browser()->profile()); |
| |
| EXPECT_THAT( |
| histogram_tester()->GetAllSamples( |
| "Bookmarks.Times.OnProfileLoad.MostRecentlyUsedBookmarkInDays"), |
| testing::ElementsAre(base::Bucket(/*min=*/1, /*count=*/1))); |
| |
| EXPECT_THAT( |
| histogram_tester()->GetAllSamples( |
| "Bookmarks.Times.OnProfileLoad.MostRecentlySavedBookmarkInDays"), |
| testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1))); |
| EXPECT_THAT( |
| histogram_tester()->GetAllSamples( |
| "Bookmarks.Times.OnProfileLoad.MostRecentlyAddedFolderInDays"), |
| testing::ElementsAre(base::Bucket(/*min=*/3, /*count=*/1))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, |
| EmitUmaForMostRecentlyUsed_NoBookmarks) { |
| WaitForBookmarkModel(browser()->profile()); |
| |
| EXPECT_THAT( |
| histogram_tester()->GetAllSamples( |
| "Bookmarks.Times.OnProfileLoad.MostRecentlyUsedBookmarkInDays"), |
| testing::ElementsAre()); |
| |
| EXPECT_THAT( |
| histogram_tester()->GetAllSamples( |
| "Bookmarks.Times.OnProfileLoad.MostRecentlySavedBookmarkInDays"), |
| testing::ElementsAre()); |
| EXPECT_THAT( |
| histogram_tester()->GetAllSamples( |
| "Bookmarks.Times.OnProfileLoad.MostRecentlyAddedFolderInDays"), |
| testing::ElementsAre()); |
| } |
| |
| // Test that the bookmark star state updates in response to same document |
| // navigations that change the URL |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, SameDocumentNavigation) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| GURL bookmark_url = embedded_test_server()->GetURL("/title1.html"); |
| bookmarks::AddIfNotBookmarked(bookmark_model, bookmark_url, u"Bookmark"); |
| |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| BookmarkTabHelper* tab_helper = |
| BookmarkTabHelper::FromWebContents(web_contents); |
| TestBookmarkTabHelperObserver bookmark_observer(tab_helper); |
| |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), bookmark_url)); |
| EXPECT_TRUE(bookmark_observer.is_starred()); |
| |
| GURL same_document_url = embedded_test_server()->GetURL("/title1.html#test"); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), same_document_url)); |
| EXPECT_FALSE(bookmark_observer.is_starred()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, |
| DifferentDocumentNavigationWithoutFinishing) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| GURL bookmark_url = embedded_test_server()->GetURL("/title1.html"); |
| bookmarks::AddIfNotBookmarked(bookmark_model, bookmark_url, u"Bookmark"); |
| |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| BookmarkTabHelper* tab_helper = |
| BookmarkTabHelper::FromWebContents(web_contents); |
| TestBookmarkTabHelperObserver bookmark_observer(tab_helper); |
| |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), bookmark_url)); |
| EXPECT_TRUE(bookmark_observer.is_starred()); |
| |
| // Navigate to the second page and check that the bookmark is not starred even |
| // when the navigation is not finished. |
| GURL different_document_url = embedded_test_server()->GetURL("/title2.html"); |
| content::TestNavigationManager manager(web_contents, different_document_url); |
| web_contents->GetController().LoadURL( |
| different_document_url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, |
| std::string()); |
| EXPECT_TRUE(manager.WaitForRequestStart()); |
| EXPECT_FALSE(manager.was_committed()); |
| EXPECT_EQ(web_contents->GetVisibleURL(), different_document_url); |
| EXPECT_EQ(web_contents->GetLastCommittedURL(), bookmark_url); |
| EXPECT_FALSE(bookmark_observer.is_starred()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, NonCommitURLNavigation) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| GURL bookmark_url = embedded_test_server()->GetURL("/title1.html"); |
| bookmarks::AddIfNotBookmarked(bookmark_model, bookmark_url, u"Bookmark"); |
| |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| BookmarkTabHelper* tab_helper = |
| BookmarkTabHelper::FromWebContents(web_contents); |
| TestBookmarkTabHelperObserver bookmark_observer(tab_helper); |
| |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), bookmark_url)); |
| EXPECT_TRUE(bookmark_observer.is_starred()); |
| |
| const GURL non_commit_url = embedded_test_server()->GetURL("/page204.html"); |
| content::TestNavigationManager manager(web_contents, non_commit_url); |
| web_contents->GetController().LoadURL(non_commit_url, content::Referrer(), |
| ui::PAGE_TRANSITION_TYPED, |
| std::string()); |
| EXPECT_TRUE(manager.WaitForRequestStart()); |
| EXPECT_FALSE(manager.was_committed()); |
| EXPECT_EQ(web_contents->GetVisibleURL(), non_commit_url); |
| EXPECT_EQ(web_contents->GetLastCommittedURL(), bookmark_url); |
| EXPECT_FALSE(bookmark_observer.is_starred()); |
| |
| // Since the navigation did not commit, the last committed URL becomes the |
| // visible URL again, so the starred state should be restored. |
| ASSERT_TRUE(manager.WaitForNavigationFinished()); |
| EXPECT_FALSE(manager.was_committed()); |
| EXPECT_TRUE(bookmark_observer.is_starred()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, |
| BookmarkCurrentTab_WithoutAccountNodes) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| |
| // If no folders have been modified, bookmarks are saved to other bookmarks by |
| // default. |
| ASSERT_EQ(bookmark_model->other_node(), |
| bookmarks::GetParentForNewNodes(bookmark_model)); |
| |
| ASSERT_TRUE(chrome::ExecuteCommand(browser(), IDC_BOOKMARK_THIS_TAB)); |
| EXPECT_THAT(1u, bookmark_model->other_node()->children().size()); |
| |
| // Add a bookmark to the local bookmark bar node, so that it becomes the most |
| // recently modified one. |
| bookmark_model->AddURL(bookmark_model->bookmark_bar_node(), 0, u"Title", |
| GURL("http://google.com")); |
| ASSERT_EQ(bookmark_model->bookmark_bar_node(), |
| bookmarks::GetParentForNewNodes(bookmark_model)); |
| |
| // After the bookmarks bar was modified, it should be the new default save |
| // location. |
| ASSERT_TRUE(chrome::ExecuteCommand(browser(), IDC_BOOKMARK_THIS_TAB)); |
| EXPECT_THAT(1u, bookmark_model->bookmark_bar_node()->children().size()); |
| } |
| |
| // Account nodes don't exist on ChromeOS, so this test does not apply. |
| #if !BUILDFLAG(IS_CHROMEOS) |
| IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, |
| BookmarkCurrentTab_WithAccountNodes) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| bookmark_model->CreateAccountPermanentFolders(); |
| |
| // If no folders have been modified, bookmarks are saved to account other |
| // bookmarks by default. |
| ASSERT_EQ(bookmark_model->account_other_node(), |
| bookmarks::GetParentForNewNodes(bookmark_model)); |
| |
| ASSERT_TRUE(chrome::ExecuteCommand(browser(), IDC_BOOKMARK_THIS_TAB)); |
| EXPECT_THAT(1u, bookmark_model->account_other_node()->children().size()); |
| |
| // Add a bookmark to the local bookmark bar node, so that it becomes the most |
| // recently modified one. |
| bookmark_model->AddURL(bookmark_model->bookmark_bar_node(), 0, u"Title", |
| GURL("http://google.com")); |
| ASSERT_EQ(bookmark_model->bookmark_bar_node(), |
| bookmarks::GetParentForNewNodes(bookmark_model)); |
| |
| // After the bookmarks bar was modified, it should be the new default save |
| // location. |
| ASSERT_TRUE(chrome::ExecuteCommand(browser(), IDC_BOOKMARK_THIS_TAB)); |
| EXPECT_THAT(1u, bookmark_model->bookmark_bar_node()->children().size()); |
| } |
| #endif // !BUILDFLAG(IS_CHROMEOS) |
| |
| class BookmarkPrerenderBrowsertest : public BookmarkBrowsertest { |
| public: |
| BookmarkPrerenderBrowsertest() |
| : prerender_helper_( |
| base::BindRepeating(&BookmarkPrerenderBrowsertest::GetWebContents, |
| base::Unretained(this))) {} |
| ~BookmarkPrerenderBrowsertest() override = default; |
| BookmarkPrerenderBrowsertest(const BookmarkPrerenderBrowsertest&) = delete; |
| |
| BookmarkPrerenderBrowsertest& operator=(const BookmarkPrerenderBrowsertest&) = |
| delete; |
| |
| void SetUp() override { |
| prerender_helper_.RegisterServerRequestMonitor(embedded_test_server()); |
| BookmarkBrowsertest::SetUp(); |
| } |
| |
| void SetUpOnMainThread() override { |
| host_resolver()->AddRule("*", "127.0.0.1"); |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| BookmarkBrowsertest::SetUpOnMainThread(); |
| } |
| |
| content::test::PrerenderTestHelper& prerender_test_helper() { |
| return prerender_helper_; |
| } |
| |
| content::WebContents* GetWebContents() { |
| return browser()->tab_strip_model()->GetActiveWebContents(); |
| } |
| |
| private: |
| content::test::PrerenderTestHelper prerender_helper_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(BookmarkPrerenderBrowsertest, |
| PrerenderingShouldNotUpdateStarredState) { |
| GURL initial_url = embedded_test_server()->GetURL("/empty.html"); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url)); |
| |
| BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile()); |
| GURL bookmark_url = embedded_test_server()->GetURL("/title1.html"); |
| bookmarks::AddIfNotBookmarked(bookmark_model, bookmark_url, u"Bookmark"); |
| |
| BookmarkTabHelper* tab_helper = |
| BookmarkTabHelper::FromWebContents(GetWebContents()); |
| TestBookmarkTabHelperObserver bookmark_observer(tab_helper); |
| |
| // Load a prerender page and prerendering should not notify to |
| // URLStarredChanged listener. |
| const content::FrameTreeNodeId host_id = |
| prerender_test_helper().AddPrerender(bookmark_url); |
| content::test::PrerenderHostObserver host_observer(*GetWebContents(), |
| host_id); |
| EXPECT_FALSE(host_observer.was_activated()); |
| EXPECT_FALSE(bookmark_observer.is_starred()); |
| |
| // Activate the prerender page. |
| prerender_test_helper().NavigatePrimaryPage(bookmark_url); |
| EXPECT_TRUE(host_observer.was_activated()); |
| EXPECT_TRUE(bookmark_observer.is_starred()); |
| } |