blob: 2200afd63983d5248da24eb4b4c682a29a9b69b5 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "base/base64.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/history/history_test_utils.h"
#include "chrome/browser/history_clusters/history_clusters_metrics_logger.h"
#include "chrome/browser/history_clusters/history_clusters_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/webui/history/history_ui.h"
#include "chrome/browser/ui/webui/history_clusters/history_clusters_handler.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/history_clusters/core/features.h"
#include "components/history_clusters/core/url_constants.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/variations/active_field_trials.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "ui/webui/resources/cr_components/history_clusters/history_clusters.mojom.h"
namespace history_clusters {
namespace {
enum class UiTab {
kBasicHistory = 0,
kClustersUi = 1,
};
void ValidateHistoryClustersUKMEntry(const ukm::mojom::UkmEntry* entry,
HistoryClustersInitialState init_state,
int num_queries,
int num_toggles_to_basic_history) {
ukm::TestAutoSetUkmRecorder ukm_recorder;
EXPECT_TRUE(ukm_recorder.EntryHasMetric(
entry, ukm::builders::HistoryClusters::kInitialStateName));
ukm_recorder.ExpectEntryMetric(
entry, ukm::builders::HistoryClusters::kInitialStateName,
static_cast<int>(init_state));
EXPECT_TRUE(ukm_recorder.EntryHasMetric(
entry, ukm::builders::HistoryClusters::kNumQueriesName));
ukm_recorder.ExpectEntryMetric(
entry, ukm::builders::HistoryClusters::kNumQueriesName, num_queries);
EXPECT_TRUE(ukm_recorder.EntryHasMetric(
entry, ukm::builders::HistoryClusters::kNumTogglesToBasicHistoryName));
ukm_recorder.ExpectEntryMetric(
entry, ukm::builders::HistoryClusters::kNumTogglesToBasicHistoryName,
num_toggles_to_basic_history);
}
} // namespace
class HistoryClustersMetricsBrowserTest : public InProcessBrowserTest {
public:
HistoryClustersMetricsBrowserTest() {
feature_list_.InitWithFeatures({history_clusters::internal::kJourneys}, {});
}
// Toggle to the specified `tab`, either the basic history (0) or clusters UI
// (1).
void ToggleToUi(UiTab tab) {
std::string tab_string = tab == UiTab::kClustersUi ? "1" : "0";
std::string execute_string = "";
execute_string += R"(
import('chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js')
.then((polymerModule)=> {
polymerModule.flush();
const historyApp = document.querySelector('#history-app');
const tab = )" +
tab_string + R"(;
historyApp.shadowRoot.querySelector('cr-tabs').selected = tab;
window.domAutomationController.send(true);
});)";
bool result = false;
EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
browser()->tab_strip_model()->GetActiveWebContents(), execute_string,
&result));
EXPECT_TRUE(result);
}
// Creates and follows an anchor link. Since we can't differentiate between
// that and actual visit links, it'll log the final state as `kLinkClick`,
// which is useful since the browser tests won't populate journeys, and we
// have no other way to trigger `kLinkClick`.
void FollowBrowserManagedLink() {
std::string execute_string = "";
execute_string += R"(
import('chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js')
.then((polymerModule)=> {
polymerModule.flush();
let link = document.createElement('a');
link.href = 'https://google.com';
link.click();
window.domAutomationController.send(true);
});)";
bool result = false;
EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
browser()->tab_strip_model()->GetActiveWebContents(), execute_string,
&result));
EXPECT_TRUE(result);
}
// Navigates to the history clusters UI with `PAGE_TRANSITION_RELOAD`. Assumes
// the current URL is also the history clusters UI.
void RefreshHistoryClusters() {
NavigateParams params(browser(), GURL(kChromeUIHistoryClustersURL),
ui::PAGE_TRANSITION_RELOAD);
ui_test_utils::NavigateToURL(&params);
}
private:
base::test::ScopedFeatureList feature_list_;
};
IN_PROC_BROWSER_TEST_F(HistoryClustersMetricsBrowserTest,
NoUKMEventOnOtherPages) {
base::HistogramTester histogram_tester;
ukm::TestAutoSetUkmRecorder ukm_recorder;
// Navigate to and away from a site. The UKM events are recorded when leaving
// a page.
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("https://foo.com")));
EXPECT_TRUE(
ui_test_utils::NavigateToURL(browser(), GURL("https://foo2.com")));
auto entries =
ukm_recorder.GetEntriesByName(ukm::builders::HistoryClusters::kEntryName);
EXPECT_EQ(0u, entries.size());
histogram_tester.ExpectTotalCount("History.Clusters.Actions.DidMakeQuery", 0);
histogram_tester.ExpectTotalCount("History.Clusters.Actions.NumQueries", 0);
}
// Flaky on Win, Linux and Mac. http://crbug.com/1282122
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || \
BUILDFLAG(IS_MAC)
#define MAYBE_DirectNavigationNoInteraction \
DISABLED_DirectNavigationNoInteraction
#else
#define MAYBE_DirectNavigationNoInteraction DirectNavigationNoInteraction
#endif
IN_PROC_BROWSER_TEST_F(HistoryClustersMetricsBrowserTest,
MAYBE_DirectNavigationNoInteraction) {
base::HistogramTester histogram_tester;
ukm::TestAutoSetUkmRecorder ukm_recorder;
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(),
GURL(kChromeUIHistoryClustersURL)));
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("https://foo.com")));
auto entries =
ukm_recorder.GetEntriesByName(ukm::builders::HistoryClusters::kEntryName);
EXPECT_EQ(1u, entries.size());
auto* entry = entries[0];
ValidateHistoryClustersUKMEntry(
entry, HistoryClustersInitialState::kDirectNavigation, 0, 0);
histogram_tester.ExpectUniqueSample(
"History.Clusters.Actions.InitialState",
HistoryClustersInitialState::kDirectNavigation, 1);
histogram_tester.ExpectUniqueSample("History.Clusters.Actions.DidMakeQuery",
false, 1);
histogram_tester.ExpectTotalCount("History.Clusters.Actions.NumQueries", 0);
}
// TODO(crbug.com/1282087): Flaky on Linux, Windows and Mac.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || \
BUILDFLAG(IS_MAC)
#define MAYBE_DirectNavigationWithQuery DISABLED_DirectNavigationWithQuery
#else
#define MAYBE_DirectNavigationWithQuery DirectNavigationWithQuery
#endif
IN_PROC_BROWSER_TEST_F(HistoryClustersMetricsBrowserTest,
MAYBE_DirectNavigationWithQuery) {
base::HistogramTester histogram_tester;
ukm::TestAutoSetUkmRecorder ukm_recorder;
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(),
GURL(kChromeUIHistoryClustersURL)));
EXPECT_TRUE(content::WaitForLoadStop(
browser()->tab_strip_model()->GetActiveWebContents()));
history_clusters::HistoryClustersHandler* page_handler =
browser()
->tab_strip_model()
->GetActiveWebContents()
->GetWebUI()
->GetController()
->template GetAs<HistoryUI>()
->GetHistoryClustersHandlerForTesting();
page_handler->StartQueryClusters("cat", false);
page_handler->StartQueryClusters("dog", false);
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("https://foo.com")));
auto entries =
ukm_recorder.GetEntriesByName(ukm::builders::HistoryClusters::kEntryName);
EXPECT_EQ(1u, entries.size());
auto* entry = entries[0];
ValidateHistoryClustersUKMEntry(
entry, HistoryClustersInitialState::kDirectNavigation, 2, 0);
histogram_tester.ExpectUniqueSample(
"History.Clusters.Actions.InitialState",
HistoryClustersInitialState::kDirectNavigation, 1);
histogram_tester.ExpectUniqueSample("History.Clusters.Actions.DidMakeQuery",
true, 1);
histogram_tester.ExpectUniqueSample("History.Clusters.Actions.NumQueries", 2,
1);
}
// Disabled on Windows, ChromeOS, and Linux due to flakes: crbug.com/1263465.
// Disabled on Mac due to flakes: crbug.com/1288805.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || \
BUILDFLAG(IS_MAC)
#define MAYBE_DirectNavigationWithToggleToBasic \
DISABLED_DirectNavigationWithToggleToBasic
#else
#define MAYBE_DirectNavigationWithToggleToBasic \
DirectNavigationWithToggleToBasic
#endif
IN_PROC_BROWSER_TEST_F(HistoryClustersMetricsBrowserTest,
MAYBE_DirectNavigationWithToggleToBasic) {
base::HistogramTester histogram_tester;
ukm::TestAutoSetUkmRecorder ukm_recorder;
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(),
GURL(kChromeUIHistoryClustersURL)));
ToggleToUi(UiTab::kBasicHistory);
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("https://foo.com")));
auto entries =
ukm_recorder.GetEntriesByName(ukm::builders::HistoryClusters::kEntryName);
EXPECT_EQ(1u, entries.size());
auto* ukm_entry = entries[0];
ValidateHistoryClustersUKMEntry(
ukm_entry, HistoryClustersInitialState::kDirectNavigation, 0, 1);
histogram_tester.ExpectUniqueSample(
"History.Clusters.Actions.InitialState",
HistoryClustersInitialState::kDirectNavigation, 1);
histogram_tester.ExpectUniqueSample("History.Clusters.Actions.DidMakeQuery",
false, 1);
histogram_tester.ExpectTotalCount("History.Clusters.Actions.NumQueries", 0);
}
IN_PROC_BROWSER_TEST_F(
HistoryClustersMetricsBrowserTest,
DISABLED_DirectNavigationWithToggleToBasicAndToggleBack) {
base::HistogramTester histogram_tester;
ukm::TestAutoSetUkmRecorder ukm_recorder;
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(),
GURL(kChromeUIHistoryClustersURL)));
ToggleToUi(UiTab::kBasicHistory);
ToggleToUi(UiTab::kClustersUi);
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("https://foo.com")));
auto entries =
ukm_recorder.GetEntriesByName(ukm::builders::HistoryClusters::kEntryName);
EXPECT_EQ(1u, entries.size());
auto* ukm_entry = entries[0];
ValidateHistoryClustersUKMEntry(
ukm_entry, HistoryClustersInitialState::kIndirectNavigation, 0, 1);
histogram_tester.ExpectUniqueSample(
"History.Clusters.Actions.InitialState",
HistoryClustersInitialState::kIndirectNavigation, 1);
histogram_tester.ExpectUniqueSample("History.Clusters.Actions.DidMakeQuery",
false, 1);
histogram_tester.ExpectTotalCount("History.Clusters.Actions.NumQueries", 0);
}
// Assumed to be flaky since the above tests are flaky.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || \
BUILDFLAG(IS_MAC)
#define MAYBE_IndirectNavigation DISABLED_IndirectNavigation
#else
#define MAYBE_IndirectNavigation IndirectNavigation
#endif
IN_PROC_BROWSER_TEST_F(HistoryClustersMetricsBrowserTest,
MAYBE_IndirectNavigation) {
base::HistogramTester histogram_tester;
ukm::TestAutoSetUkmRecorder ukm_recorder;
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(),
GURL(chrome::kChromeUIHistoryURL)));
ToggleToUi(UiTab::kClustersUi);
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("https://foo.com")));
auto entries =
ukm_recorder.GetEntriesByName(ukm::builders::HistoryClusters::kEntryName);
EXPECT_EQ(1u, entries.size());
auto* ukm_entry = entries[0];
ValidateHistoryClustersUKMEntry(
ukm_entry, HistoryClustersInitialState::kIndirectNavigation, 0, 0);
histogram_tester.ExpectUniqueSample(
"History.Clusters.Actions.InitialState",
HistoryClustersInitialState::kIndirectNavigation, 1);
histogram_tester.ExpectUniqueSample("History.Clusters.Actions.DidMakeQuery",
false, 1);
histogram_tester.ExpectTotalCount("History.Clusters.Actions.NumQueries", 0);
}
} // namespace history_clusters