Commit bd9fe73d authored by Michael Giuffrida's avatar Michael Giuffrida Committed by Commit Bot

Browser tests for TabActivityWatcher UKMs

Like the unit tests, but these can test more robust browser activity.

Bug: 784639
Change-Id: I65ef78d56143d65811a05e7b8a1088e2ce9c372e
Reviewed-on: https://chromium-review.googlesource.com/905688
Commit-Queue: Michael Giuffrida <michaelpg@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537830}
parent 93c5199a
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "base/macros.h"
#include "chrome/browser/resource_coordinator/tab_metrics_event.pb.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_ukm_test_helper.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/test/web_contents_tester.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/mojom/ukm_interface.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
using metrics::TabMetricsEvent;
using ukm::builders::TabManager_TabMetrics;
namespace resource_coordinator {
namespace {
const char* kEntryName = TabManager_TabMetrics::kEntryName;
const GURL kTestUrls[] = {
GURL("https://example.com/"), GURL("https://google.fake"),
GURL("https://example3.com"),
};
// The default metric values for a tab.
const UkmMetricMap kBasicMetricValues({
{TabManager_TabMetrics::kContentTypeName,
TabMetricsEvent::CONTENT_TYPE_TEXT_HTML},
{TabManager_TabMetrics::kDefaultProtocolHandlerName, base::nullopt},
{TabManager_TabMetrics::kHasBeforeUnloadHandlerName, 0},
{TabManager_TabMetrics::kHasFormEntryName, 0},
{TabManager_TabMetrics::kIsExtensionProtectedName, 0},
{TabManager_TabMetrics::kIsPinnedName, 0},
{TabManager_TabMetrics::kKeyEventCountName, 0},
{TabManager_TabMetrics::kNavigationEntryCountName, 1},
{TabManager_TabMetrics::kSiteEngagementScoreName, 0},
{TabManager_TabMetrics::kTouchEventCountName, 0},
{TabManager_TabMetrics::kWasRecentlyAudibleName, 0},
// TODO(michaelpg): Test TabManager_TabMetrics::kMouseEventCountName.
// Depending on the test environment, the browser may receive mouse events
// from the mouse cursor during tests, so we currently don't check this
// metric.
});
} // namespace
// Tests UKM entries generated by TabActivityWatcher/TabMetricsLogger as tabs
// are backgrounded.
// Modeled after the TabActivityWatcherTest unit tests, these browser tests
// focus on end-to-end testing from the first browser launch onwards, verifying
// that window and browser commands are really triggering the paths that lead
// to UKM logs.
class TabActivityWatcherTest : public InProcessBrowserTest {
protected:
TabActivityWatcherTest() = default;
// InProcessBrowserTest:
void PreRunTestOnMainThread() override {
InProcessBrowserTest::PreRunTestOnMainThread();
ukm_entry_checker_ = std::make_unique<UkmEntryChecker>();
}
void SetUpOnMainThread() override {
// Browser created in BrowserMain() shouldn't result in a background tab
// being logged.
EXPECT_EQ(0u, ukm_entry_checker_->NumEntries(kEntryName));
}
void TearDown() override {
EXPECT_EQ(0, ukm_entry_checker_->NumNewEntriesRecorded(kEntryName));
InProcessBrowserTest::TearDown();
}
protected:
std::unique_ptr<UkmEntryChecker> ukm_entry_checker_;
private:
DISALLOW_COPY_AND_ASSIGN(TabActivityWatcherTest);
};
// Tests TabMetrics UKMs logged by creating and switching between tabs.
IN_PROC_BROWSER_TEST_F(TabActivityWatcherTest, SwitchTabs) {
bool is_user_gesture = true;
const GURL kTabUrls[] = {
GURL(), // "about:blank" tab doesn't have a UKM source.
kTestUrls[0], kTestUrls[1],
};
EXPECT_EQ(0u, ukm_entry_checker_->NumEntries(kEntryName));
UkmMetricMap expected_metrics = kBasicMetricValues;
expected_metrics[TabManager_TabMetrics::kWindowIdName] =
browser()->session_id().id();
// Adding a new foreground tab logs the previously active tab.
AddTabAtIndex(1, kTabUrls[1], ui::PAGE_TRANSITION_LINK);
{
SCOPED_TRACE("");
ukm_entry_checker_->ExpectNewEntry(kEntryName, kTabUrls[0],
expected_metrics);
}
AddTabAtIndex(2, kTabUrls[2], ui::PAGE_TRANSITION_LINK);
{
SCOPED_TRACE("");
ukm_entry_checker_->ExpectNewEntry(kEntryName, kTabUrls[1],
expected_metrics);
}
// Switching to another tab logs the previously active tab.
browser()->tab_strip_model()->ActivateTabAt(0, is_user_gesture);
{
SCOPED_TRACE("");
ukm_entry_checker_->ExpectNewEntry(kEntryName, kTabUrls[2],
expected_metrics);
}
browser()->tab_strip_model()->ActivateTabAt(1, is_user_gesture);
{
SCOPED_TRACE("");
ukm_entry_checker_->ExpectNewEntry(kEntryName, kTabUrls[0],
expected_metrics);
}
// Closing the window doesn't log more TabMetrics UKMs (tested in TearDown()).
CloseBrowserSynchronously(browser());
}
// Tests that switching between multiple windows doesn't affect TabMetrics UKMs.
// This is a sanity check; window activation shouldn't make any difference to
// what we log. If we needed to actually test different behavior based on window
// focus, we would run these tests in interactive_ui_tests.
IN_PROC_BROWSER_TEST_F(TabActivityWatcherTest, SwitchWindows) {
const bool check_navigation_success = false;
Browser* browser_2 = CreateBrowser(browser()->profile());
EXPECT_EQ(0, ukm_entry_checker_->NumNewEntriesRecorded(kEntryName));
AddTabAtIndexToBrowser(browser(), 1, kTestUrls[0], ui::PAGE_TRANSITION_LINK,
check_navigation_success);
{
SCOPED_TRACE("");
UkmMetricMap expected_metrics = kBasicMetricValues;
expected_metrics[TabManager_TabMetrics::kWindowIdName] =
browser()->session_id().id();
ukm_entry_checker_->ExpectNewEntry(kEntryName, GURL(), kBasicMetricValues);
}
AddTabAtIndexToBrowser(browser_2, 1, kTestUrls[1], ui::PAGE_TRANSITION_LINK,
check_navigation_success);
{
SCOPED_TRACE("");
UkmMetricMap expected_metrics = kBasicMetricValues;
expected_metrics[TabManager_TabMetrics::kWindowIdName] =
browser_2->session_id().id();
ukm_entry_checker_->ExpectNewEntry(kEntryName, GURL(), kBasicMetricValues);
}
browser()->window()->Activate();
browser_2->window()->Activate();
EXPECT_EQ(0, ukm_entry_checker_->NumNewEntriesRecorded(kEntryName));
// Closing each window doesn't log more TabMetrics UKMs.
CloseBrowserSynchronously(browser_2);
CloseBrowserSynchronously(browser());
}
// Tests page with a beforeunload handler.
IN_PROC_BROWSER_TEST_F(TabActivityWatcherTest, BeforeUnloadHandler) {
bool is_user_gesture = false;
ASSERT_TRUE(embedded_test_server()->Start());
// Navigate to a page with a beforeunload handler.
GURL url(embedded_test_server()->GetURL("/beforeunload.html"));
ui_test_utils::NavigateToURL(browser(), url);
// Log metrics for the first tab by switching to a new tab.
AddTabAtIndex(1, kTestUrls[0], ui::PAGE_TRANSITION_LINK);
UkmMetricMap expected_metrics = kBasicMetricValues;
expected_metrics[TabManager_TabMetrics::kHasBeforeUnloadHandlerName] = 1;
expected_metrics[TabManager_TabMetrics::kNavigationEntryCountName] = 2;
{
SCOPED_TRACE("");
ukm_entry_checker_->ExpectNewEntry(kEntryName, url, expected_metrics);
}
// Sanity check: the new tab doesn't have a beforeunload handler.
browser()->tab_strip_model()->ActivateTabAt(0, is_user_gesture);
{
SCOPED_TRACE("");
ukm_entry_checker_->ExpectNewEntry(kEntryName, kTestUrls[0],
kBasicMetricValues);
}
}
} // namespace resource_coordinator
...@@ -49,7 +49,6 @@ const GURL kTestUrls[] = { ...@@ -49,7 +49,6 @@ const GURL kTestUrls[] = {
const UkmMetricMap kBasicMetricValues({ const UkmMetricMap kBasicMetricValues({
{TabManager_TabMetrics::kContentTypeName, {TabManager_TabMetrics::kContentTypeName,
TabMetricsEvent::CONTENT_TYPE_TEXT_HTML}, TabMetricsEvent::CONTENT_TYPE_TEXT_HTML},
// TODO(michaelpg): Test HasBeforeUnloadHandler in a browser_test.
{TabManager_TabMetrics::kHasBeforeUnloadHandlerName, 0}, {TabManager_TabMetrics::kHasBeforeUnloadHandlerName, 0},
{TabManager_TabMetrics::kHasFormEntryName, 0}, {TabManager_TabMetrics::kHasFormEntryName, 0},
{TabManager_TabMetrics::kIsExtensionProtectedName, 0}, {TabManager_TabMetrics::kIsExtensionProtectedName, 0},
......
...@@ -142,7 +142,7 @@ void UkmEntryChecker::ExpectNewEntriesBySource( ...@@ -142,7 +142,7 @@ void UkmEntryChecker::ExpectNewEntriesBySource(
const size_t num_entries = entries.size(); const size_t num_entries = entries.size();
num_entries_[entry_name] += num_new_entries; num_entries_[entry_name] += num_new_entries;
ASSERT_LE(NumEntries(entry_name), entries.size()); ASSERT_LE(num_entries_[entry_name], entries.size());
std::set<ukm::SourceId> found_source_ids; std::set<ukm::SourceId> found_source_ids;
for (size_t i = 0; i < num_new_entries; ++i) { for (size_t i = 0; i < num_new_entries; ++i) {
...@@ -169,16 +169,20 @@ void UkmEntryChecker::ExpectNewEntriesBySource( ...@@ -169,16 +169,20 @@ void UkmEntryChecker::ExpectNewEntriesBySource(
int UkmEntryChecker::NumNewEntriesRecorded( int UkmEntryChecker::NumNewEntriesRecorded(
const std::string& entry_name) const { const std::string& entry_name) const {
const size_t current_ukm_entries = const size_t current_ukm_entries = NumEntries(entry_name);
ukm_recorder_.GetEntriesByName(entry_name).size();
const size_t previous_num_entries = NumEntries(entry_name); // If a value hasn't been inserted for |entry_name|, the test hasn't checked
// for these entries before, so they all count as new.
if (!num_entries_.count(entry_name))
return current_ukm_entries;
size_t previous_num_entries = num_entries_.at(entry_name);
EXPECT_GE(current_ukm_entries, previous_num_entries); EXPECT_GE(current_ukm_entries, previous_num_entries);
return current_ukm_entries - previous_num_entries; return current_ukm_entries - previous_num_entries;
} }
size_t UkmEntryChecker::NumEntries(const std::string& entry_name) const { size_t UkmEntryChecker::NumEntries(const std::string& entry_name) const {
const auto it = num_entries_.find(entry_name); return ukm_recorder_.GetEntriesByName(entry_name).size();
return it != num_entries_.end() ? it->second : 0;
} }
const ukm::mojom::UkmEntry* UkmEntryChecker::LastUkmEntry( const ukm::mojom::UkmEntry* UkmEntryChecker::LastUkmEntry(
......
...@@ -669,6 +669,7 @@ test("browser_tests") { ...@@ -669,6 +669,7 @@ test("browser_tests") {
"../browser/renderer_host/render_process_host_chrome_browsertest.cc", "../browser/renderer_host/render_process_host_chrome_browsertest.cc",
"../browser/repost_form_warning_browsertest.cc", "../browser/repost_form_warning_browsertest.cc",
"../browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc", "../browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc",
"../browser/resource_coordinator/tab_activity_watcher_browsertest.cc",
"../browser/resource_coordinator/tab_lifecycle_observer_browsertest.cc", "../browser/resource_coordinator/tab_lifecycle_observer_browsertest.cc",
"../browser/resource_coordinator/tab_manager_browsertest.cc", "../browser/resource_coordinator/tab_manager_browsertest.cc",
"../browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc", "../browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment