| // Copyright 2022 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/feature_list.h" |
| #include "base/strings/escape.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/page_info/about_this_site_side_panel.h" |
| #include "chrome/browser/ui/ui_features.h" |
| #include "chrome/browser/ui/views/frame/browser_view.h" |
| #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h" |
| #include "chrome/browser/ui/views/side_panel/side_panel_entry.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/page_info/core/about_this_site_service.h" |
| #include "components/page_info/core/features.h" |
| #include "components/page_info/core/proto/about_this_site_metadata.pb.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/browser_test_utils.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 "testing/gtest/include/gtest/gtest.h" |
| |
| using ::testing::_; |
| |
| namespace { |
| const char kRegularUrl1[] = "a.test"; |
| const char kRegularUrl2[] = "b.test"; |
| const char kInvalidUrl[] = "127.0.0.1"; |
| const char kAboutThisSiteUrl[] = "c.test"; |
| } // namespace |
| |
| class AboutThisSiteSidePanelCoordinatorBrowserTest |
| : public InProcessBrowserTest { |
| protected: |
| void SetUp() override { |
| https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES); |
| https_server_.ServeFilesFromSourceDirectory(GetChromeTestDataDir()); |
| ASSERT_TRUE(https_server_.Start()); |
| SetUpFeatureList(); |
| InProcessBrowserTest::SetUp(); |
| } |
| |
| void SetUpOnMainThread() override { |
| host_resolver()->AddRule("*", "127.0.0.1"); |
| } |
| |
| GURL CreateUrl(const std::string& host) { |
| return https_server_.GetURL(host, "/title1.html"); |
| } |
| |
| std::string CreateAboutThisSiteUrl(const GURL& url) { |
| return base::StringPrintf( |
| "https://www.google.com/search?" |
| "q=About+%s" |
| "&tbm=ilp&ctx=chrome_nav", |
| base::EscapeQueryParamValue(url.spec(), true).c_str()); |
| } |
| |
| page_info::proto::SiteInfo CreateSiteInfo() { |
| page_info::proto::SiteInfo info; |
| info.mutable_more_about()->set_url(CreateUrl(kAboutThisSiteUrl).spec()); |
| return info; |
| } |
| |
| content::WebContents* web_contents() { |
| return browser()->tab_strip_model()->GetActiveWebContents(); |
| } |
| |
| SidePanelCoordinator* side_panel_coordinator() { |
| return BrowserView::GetBrowserViewForBrowser(browser()) |
| ->side_panel_coordinator(); |
| } |
| |
| base::test::ScopedFeatureList feature_list_; |
| |
| private: |
| virtual void SetUpFeatureList() { |
| feature_list_.InitWithFeatures( |
| {}, {page_info::kPageInfoAboutThisSiteKeepSidePanelOnSameTabNavs}); |
| } |
| |
| net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS}; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteSidePanelCoordinatorBrowserTest, |
| ShowAndClose) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl1))); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Test showing a sidepanel. |
| ShowAboutThisSiteSidePanel(web_contents(), CreateUrl(kAboutThisSiteUrl)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that it closes on navigation. |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl2))); |
| EXPECT_FALSE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Check that navigating to reloading that URL is works fine |
| // (See https://crbug.com/1393000). |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl2))); |
| } |
| |
| // Tests that the ATS Side Panel remains open and updated on same tab |
| // navigations including refreshes. |
| class AboutThisSiteKeepSidePanelOpenBrowserTest |
| : public AboutThisSiteSidePanelCoordinatorBrowserTest { |
| private: |
| void SetUpFeatureList() override { |
| feature_list_.InitAndEnableFeature( |
| page_info::kPageInfoAboutThisSiteKeepSidePanelOnSameTabNavs); |
| } |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteKeepSidePanelOpenBrowserTest, |
| ShowOnRefresh) { |
| GURL kRegularGURL1 = CreateUrl(kRegularUrl1); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kRegularGURL1)); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Test showing a side panel. |
| ShowAboutThisSiteSidePanel(web_contents(), CreateUrl(kAboutThisSiteUrl)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that the side panel remains open on refresh. |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kRegularGURL1)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteKeepSidePanelOpenBrowserTest, |
| ShowSameTabNav) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl1))); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Test showing a side panel. |
| ShowAboutThisSiteSidePanel(web_contents(), CreateUrl(kAboutThisSiteUrl)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that side panel remains open on navigation. |
| GURL kRegularGURL2 = CreateUrl(kRegularUrl2); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kRegularGURL2)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that the AboutThisSite url was updated. |
| std::string kAboutThisSiteRegularUrl2 = CreateAboutThisSiteUrl(kRegularGURL2); |
| |
| EXPECT_TRUE(side_panel_coordinator()->GetCurrentSidePanelEntryForTesting()); |
| EXPECT_EQ(side_panel_coordinator() |
| ->GetCurrentSidePanelEntryForTesting() |
| ->GetOpenInNewTabURL(), |
| kAboutThisSiteRegularUrl2); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteKeepSidePanelOpenBrowserTest, |
| ShowSameTabNavRef) { |
| GURL kRegularGURL1 = CreateUrl(kRegularUrl1); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kRegularGURL1)); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Test showing a side panel. |
| GURL kAboutThisSiteGURL = CreateUrl(kAboutThisSiteUrl); |
| ShowAboutThisSiteSidePanel(web_contents(), kAboutThisSiteGURL); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that side panel remains open on navigation with an anchor. |
| ASSERT_TRUE( |
| ui_test_utils::NavigateToURL(browser(), kRegularGURL1.Resolve("#ref"))); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that the AboutThisSite url remains the same. |
| EXPECT_TRUE(side_panel_coordinator()->GetCurrentSidePanelEntryForTesting()); |
| EXPECT_EQ(side_panel_coordinator() |
| ->GetCurrentSidePanelEntryForTesting() |
| ->GetOpenInNewTabURL(), |
| kAboutThisSiteGURL); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteKeepSidePanelOpenBrowserTest, |
| ShowSameTabNavSameDocumentPushState) { |
| GURL kRegularGURL1 = CreateUrl(kRegularUrl1); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kRegularGURL1)); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Test showing a side panel. |
| ShowAboutThisSiteSidePanel(web_contents(), CreateUrl(kAboutThisSiteUrl)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Push state with new path. |
| GURL kRegularGURL1WithPath2 = kRegularGURL1.Resolve("/title2.html"); |
| ASSERT_TRUE(content::ExecJs(web_contents(), |
| "history.pushState({},'','title2.html')")); |
| EXPECT_TRUE(content::WaitForLoadStop(web_contents())); |
| |
| // Check that side panel remains open on push state. |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that the AboutThisSite url was updated. |
| std::string kAboutThisSiteRegularUrl1WithPath2 = |
| CreateAboutThisSiteUrl(kRegularGURL1WithPath2); |
| |
| EXPECT_TRUE(side_panel_coordinator()->GetCurrentSidePanelEntryForTesting()); |
| EXPECT_EQ(side_panel_coordinator() |
| ->GetCurrentSidePanelEntryForTesting() |
| ->GetOpenInNewTabURL(), |
| kAboutThisSiteRegularUrl1WithPath2); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteKeepSidePanelOpenBrowserTest, |
| ShowSameTabNavSameDocumentReplaceState) { |
| GURL kRegularGURL1 = CreateUrl(kRegularUrl1); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kRegularGURL1)); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Test showing a side panel. |
| ShowAboutThisSiteSidePanel(web_contents(), CreateUrl(kAboutThisSiteUrl)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Replace state with new path. |
| GURL kRegularGURL1WithPath2 = kRegularGURL1.Resolve("/title2.html"); |
| ASSERT_TRUE(content::ExecJs(web_contents(), |
| "history.replaceState({},'','title2.html')")); |
| EXPECT_TRUE(content::WaitForLoadStop(web_contents())); |
| |
| // Check that side panel remains open on replace state. |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that the AboutThisSite url was updated. |
| std::string kAboutThisSiteRegularUrl1WithPath2 = |
| CreateAboutThisSiteUrl(kRegularGURL1WithPath2); |
| |
| EXPECT_TRUE(side_panel_coordinator()->GetCurrentSidePanelEntryForTesting()); |
| EXPECT_EQ(side_panel_coordinator() |
| ->GetCurrentSidePanelEntryForTesting() |
| ->GetOpenInNewTabURL(), |
| kAboutThisSiteRegularUrl1WithPath2); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteKeepSidePanelOpenBrowserTest, |
| ShowSameTabNavSameDocumentReplaceStateRef) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl1))); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Test showing a side panel. |
| GURL kAboutThisSiteGURL = CreateUrl(kAboutThisSiteUrl); |
| ShowAboutThisSiteSidePanel(web_contents(), kAboutThisSiteGURL); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Replace state with anchor. |
| ASSERT_TRUE( |
| content::ExecJs(web_contents(), "history.replaceState({},'','#ref')")); |
| EXPECT_TRUE(content::WaitForLoadStop(web_contents())); |
| |
| // Check that side panel remains open on replace state. |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that the AboutThisSite url remains the same. |
| EXPECT_TRUE(side_panel_coordinator()->GetCurrentSidePanelEntryForTesting()); |
| EXPECT_EQ(side_panel_coordinator() |
| ->GetCurrentSidePanelEntryForTesting() |
| ->GetOpenInNewTabURL(), |
| kAboutThisSiteGURL); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteKeepSidePanelOpenBrowserTest, |
| ShowSameTabNavWithInvalidOrigin) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl1))); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Test showing the side panel. |
| ShowAboutThisSiteSidePanel(web_contents(), CreateUrl(kAboutThisSiteUrl)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that side panel remains open on navigation to an invalid url with a |
| // path |
| GURL kInvalidGURL = CreateUrl(kInvalidUrl); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), GURL(kInvalidGURL.spec() + "/index.html"))); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that the AboutThisSite url was updated with the invalid origin but |
| // with an empty path. |
| std::string kAboutThisSiteInvalidUrl = |
| CreateAboutThisSiteUrl(kInvalidGURL.GetWithEmptyPath()); |
| |
| EXPECT_TRUE(side_panel_coordinator()->GetCurrentSidePanelEntryForTesting()); |
| EXPECT_EQ(side_panel_coordinator() |
| ->GetCurrentSidePanelEntryForTesting() |
| ->GetOpenInNewTabURL(), |
| kAboutThisSiteInvalidUrl); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteKeepSidePanelOpenBrowserTest, |
| RemainsClosedOnSameTabNav) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl1))); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Test showing a side panel. |
| ShowAboutThisSiteSidePanel(web_contents(), CreateUrl(kAboutThisSiteUrl)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Close side panel. |
| side_panel_coordinator()->Close(); |
| EXPECT_FALSE(side_panel_coordinator()->IsSidePanelShowing()); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Check that side panel remains closed on navigation. |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl2))); |
| EXPECT_FALSE(side_panel_coordinator()->IsSidePanelShowing()); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AboutThisSiteKeepSidePanelOpenBrowserTest, |
| HistogramEmissionOnSameTabNav) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl1))); |
| ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), absl::nullopt); |
| |
| // Show side panel. |
| ShowAboutThisSiteSidePanel(web_contents(), CreateUrl(kAboutThisSiteUrl)); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| base::HistogramTester t; |
| |
| // Navigate on the same tab. |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), CreateUrl(kRegularUrl2))); |
| EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); |
| EXPECT_EQ(side_panel_coordinator()->GetCurrentEntryId(), |
| SidePanelEntry::Id::kAboutThisSite); |
| |
| // Check that the histogram was emitted. |
| t.ExpectUniqueSample("Security.PageInfo.AboutThisSiteInteraction", |
| page_info::AboutThisSiteService:: |
| AboutThisSiteInteraction::kSameTabNavigation, |
| 1); |
| } |
| |
| // TODO(crbug.com/1318000): Cover additional AboutThisSite side panel behavior. |