blob: 8c76ad3f7865d1bcd0aee91703985ed8e4647ee6 [file] [log] [blame]
// 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 <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <unordered_set>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
#include "base/test/values_test_util.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h"
#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/infobars/mock_infobar_service.h"
#include "chrome/browser/metrics/subprocess_metrics_provider.h"
#include "chrome/browser/previews/previews_lite_page_redirect_decider.h"
#include "chrome/browser/previews/previews_lite_page_redirect_url_loader_interceptor.h"
#include "chrome/browser/previews/previews_service.h"
#include "chrome/browser/previews/previews_service_factory.h"
#include "chrome/browser/previews/previews_ui_tab_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_test_utils.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
#include "components/data_reduction_proxy/proto/data_store.pb.h"
#include "components/history/core/browser/history_service.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "components/infobars/core/infobar.h"
#include "components/optimization_guide/bloom_filter.h"
#include "components/optimization_guide/hints_component_info.h"
#include "components/optimization_guide/hints_component_util.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/optimization_guide_service.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/optimization_guide/test_hints_component_creator.h"
#include "components/prefs/pref_service.h"
#include "components/previews/content/previews_decider_impl.h"
#include "components/previews/content/previews_ui_service.h"
#include "components/previews/content/previews_user_data.h"
#include "components/previews/core/previews_experiments.h"
#include "components/previews/core/previews_features.h"
#include "components/previews/core/previews_lite_page_redirect.h"
#include "components/previews/core/previews_switches.h"
#include "components/ukm/content/source_url_recorder.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/page_type.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/features.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_status_code.h"
#include "net/nqe/effective_connection_type.h"
#include "net/reporting/reporting_policy.h"
#include "net/test/embedded_test_server/embedded_test_server_connection_listener.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "services/network/public/cpp/features.h"
#include "services/network/test/test_network_quality_tracker.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
namespace {
const int kTimeoutMs = 250;
const int kRedirectLoopCount = 3;
const char kOriginHost[] = "origin.com";
// This should match the value in //components/google/core/common/google_util.cc
// so that the X-Client-Data header is sent for subresources.
const char kPreviewsHost[] = "litepages.googlezip.net";
// A host that is blacklisted for Lite Page Redirect previews and won't trigger
// on it.
const char kBlacklistedHost[] = "blacklisted.com";
// Retries fetching |histogram_name| until it contains at least |count| samples.
void RetryForHistogramUntilCountReached(base::HistogramTester* histogram_tester,
const std::string& histogram_name,
size_t count) {
while (true) {
base::ThreadPoolInstance::Get()->FlushForTesting();
base::RunLoop().RunUntilIdle();
content::FetchHistogramsFromChildProcesses();
SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
const std::vector<base::Bucket> buckets =
histogram_tester->GetAllSamples(histogram_name);
size_t total_count = 0;
for (const auto& bucket : buckets) {
total_count += bucket.count;
}
if (total_count >= count) {
break;
}
}
}
} // namespace
class BasePreviewsLitePageRedirectServerBrowserTest
: public InProcessBrowserTest,
public net::test_server::EmbeddedTestServerConnectionListener {
public:
BasePreviewsLitePageRedirectServerBrowserTest() {}
~BasePreviewsLitePageRedirectServerBrowserTest() override {}
virtual bool UseOptimizationGuideKeyedServiceImplementation() const = 0;
virtual bool ShouldEnableDRPHoldback() const = 0;
enum PreviewsServerAction {
// Previews server will respond with HTTP 200 OK, OFCL=60,
// Content-Length=20.
kSuccess = 0,
// Previews server will respond with a bypass signal (HTTP 307).
kBypass = 1,
// Previews server will respond with HTTP 307 to a non-preview page.
kRedirectNonPreview = 2,
// Previews server will respond with HTTP 503.
kLoadshed = 3,
// Previews server will respond with HTTP 403.
kAuthFailure = 4,
// Previews server will respond with HTTP 307 bypass to a non-preview page
// and set the host-blacklist header value.
kBypassAndBlacklistOriginHost = 5,
// Previews server will respond with HTTP 200 and a content body that loads
// a subresource. When the subresource is loaded, |subresources_requested|_
// will be incremented if the X-Client-Data header if in the request.
kSubresources = 6,
// Previews server will respond with HTTP 307 to a preview page.
kRedirectPreview = 7,
// Previews server will put Chrome into a redirect loop.
kRedirectLoop = 8,
// The URL that intervention reports should be sent to.
kInterventionReport = 9,
};
void SetUpCommandLine(base::CommandLine* cmd) override {
// Due to race conditions, it's possible that blacklist data is not loaded
// at the time of first navigation. That may prevent Preview from
// triggering, and causing the test to flake.
cmd->AppendSwitch(previews::switches::kIgnorePreviewsBlacklist);
cmd->AppendSwitch("enable-spdy-proxy-auth");
cmd->AppendSwitchASCII("data-reduction-proxy-client-config",
data_reduction_proxy::DummyBase64Config());
cmd->AppendSwitchASCII("force-effective-connection-type", "Slow-2G");
cmd->AppendSwitchASCII("force-variation-ids", "42");
cmd->AppendSwitchASCII("host-rules", "MAP * 127.0.0.1");
cmd->AppendSwitch("ignore-litepage-redirect-optimization-blacklist");
}
void SetUp() override {
SetUpLitePageTest(false /* use_timeout */, false /* is_control */);
InProcessBrowserTest::SetUp();
}
void SetUpLitePageTest(bool use_timeout, bool is_control) {
https_server_ = std::make_unique<net::EmbeddedTestServer>(
net::EmbeddedTestServer::TYPE_HTTPS);
https_server_->ServeFilesFromSourceDirectory(GetChromeTestDataDir());
https_server_->RegisterRequestHandler(base::BindRepeating(
&BasePreviewsLitePageRedirectServerBrowserTest::HandleOriginRequest,
base::Unretained(this)));
ASSERT_TRUE(https_server_->Start());
https_url_ =
https_server_->GetURL(kOriginHost, "/previews/noscript_test.html");
ASSERT_TRUE(https_url_.SchemeIs(url::kHttpsScheme));
blacklisted_https_url_ =
https_server_->GetURL(kBlacklistedHost, "/previews/noscript_test.html");
ASSERT_TRUE(blacklisted_https_url_.SchemeIs(url::kHttpsScheme));
https_to_https_redirect_url_ =
https_server_->GetURL(kOriginHost, "/previews/to_https_redirect.html");
ASSERT_TRUE(https_to_https_redirect_url_.SchemeIs(url::kHttpsScheme));
https_redirect_loop_url_ =
https_server_->GetURL(kOriginHost, "/previews/redirect_loop.html");
ASSERT_TRUE(https_redirect_loop_url_.SchemeIs(url::kHttpsScheme));
base_https_lite_page_url_ =
https_server_->GetURL(kOriginHost, "/previews/lite_page_test.html");
ASSERT_TRUE(base_https_lite_page_url_.SchemeIs(url::kHttpsScheme));
https_media_url_ =
https_server_->GetURL(kOriginHost, "/image_decoding/droids.jpg");
ASSERT_TRUE(https_media_url_.SchemeIs(url::kHttpsScheme));
// Set up http server with resource monitor and redirect handler.
http_server_ = std::make_unique<net::EmbeddedTestServer>(
net::EmbeddedTestServer::TYPE_HTTP);
http_server_->ServeFilesFromSourceDirectory(GetChromeTestDataDir());
http_server_->RegisterRequestHandler(base::BindRepeating(
&BasePreviewsLitePageRedirectServerBrowserTest::HandleOriginRequest,
base::Unretained(this)));
ASSERT_TRUE(http_server_->Start());
http_url_ =
http_server_->GetURL(kOriginHost, "/previews/noscript_test.html");
ASSERT_TRUE(http_url_.SchemeIs(url::kHttpScheme));
base_http_lite_page_url_ =
http_server_->GetURL(kOriginHost, "/previews/lite_page_test.html");
ASSERT_TRUE(base_http_lite_page_url_.SchemeIs(url::kHttpScheme));
subframe_url_ =
http_server_->GetURL(kOriginHost, "/previews/iframe_blank.html");
ASSERT_TRUE(subframe_url_.SchemeIs(url::kHttpScheme));
http_to_https_redirect_url_ =
http_server_->GetURL(kOriginHost, "/previews/to_https_redirect.html");
ASSERT_TRUE(http_to_https_redirect_url_.SchemeIs(url::kHttpScheme));
http_redirect_loop_url_ =
http_server_->GetURL(kOriginHost, "/previews/redirect_loop.html");
ASSERT_TRUE(http_redirect_loop_url_.SchemeIs(url::kHttpScheme));
client_redirect_url_ =
http_server_->GetURL(kOriginHost, "/previews/client_redirect.html");
ASSERT_TRUE(client_redirect_url_.SchemeIs(url::kHttpScheme));
// Set up previews server with resource handler.
previews_server_ = std::make_unique<net::EmbeddedTestServer>(
net::EmbeddedTestServer::TYPE_HTTPS);
previews_server_->RegisterRequestHandler(base::BindRepeating(
&BasePreviewsLitePageRedirectServerBrowserTest::HandleResourceRequest,
base::Unretained(this)));
previews_server_->SetConnectionListener(this);
ASSERT_TRUE(previews_server_->Start());
previews_server_url_ = previews_server_->GetURL(kPreviewsHost, "/");
ASSERT_TRUE(previews_server_url_.SchemeIs(url::kHttpsScheme));
// Set up the slow HTTP server with delayed resource handler.
slow_http_server_ = std::make_unique<net::EmbeddedTestServer>(
net::EmbeddedTestServer::TYPE_HTTP);
slow_http_server_->RegisterRequestHandler(
base::BindRepeating(&BasePreviewsLitePageRedirectServerBrowserTest::
HandleSlowResourceRequest,
base::Unretained(this)));
ASSERT_TRUE(slow_http_server_->Start());
slow_http_url_ = slow_http_server_->GetURL(kOriginHost, "/");
ASSERT_TRUE(slow_http_url_.SchemeIs(url::kHttpScheme));
std::map<std::string, std::string> feature_parameters = {
{"previews_host", previews_server_url().spec()},
{"full_probe_url", previews_server_url().spec()},
{"blacklisted_path_suffixes", ".mp4,.jpg"},
{"trigger_on_localhost", "true"},
{"max_navigation_restart", base::NumberToString(kRedirectLoopCount)},
{"navigation_timeout_milliseconds",
use_timeout ? base::NumberToString(kTimeoutMs) : "60000"},
{"control_group", is_control ? "true" : "false"},
{"preconnect_on_slow_connections", "true"},
{"preresolve_on_slow_connections", "false"},
{"should_probe_origin", "true"},
{"origin_probe_timeout_ms", "500"},
};
scoped_parameterized_feature_list_.InitAndEnableFeatureWithParameters(
previews::features::kLitePageServerPreviews, feature_parameters);
scoped_feature_list_.InitWithFeatures(
{previews::features::kPreviews,
optimization_guide::features::kOptimizationHints,
previews::features::kResourceLoadingHints,
data_reduction_proxy::features::
kDataReductionProxyEnabledWithNetworkService,
network::features::kReporting},
{network::features::kNetworkErrorLogging});
if (UseOptimizationGuideKeyedServiceImplementation()) {
opt_guide_keyed_service_feature_list_.InitWithFeatures(
{optimization_guide::features::kOptimizationGuideKeyedService}, {});
} else {
opt_guide_keyed_service_feature_list_.InitWithFeatures(
{}, {optimization_guide::features::kOptimizationGuideKeyedService});
}
drp_holdback_feature_list_.InitWithFeatureState(
data_reduction_proxy::features::kDataReductionProxyHoldback,
ShouldEnableDRPHoldback());
}
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
InitializeOptimizationHints();
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_2G);
// Some tests shouldn't bother with the notification InfoBar. Just set the
// state on the decider so it isn't required.
PreviewsService* previews_service =
PreviewsServiceFactory::GetForProfile(browser()->profile());
PreviewsLitePageRedirectDecider* decider =
previews_service->previews_lite_page_redirect_decider();
decider->SetUserHasSeenUINotification();
decider->BlacklistBypassedHost(kBlacklistedHost,
base::TimeDelta::FromHours(1));
net::ReportingPolicy policy;
policy.delivery_interval = base::TimeDelta::FromSeconds(0);
net::ReportingPolicy::UsePolicyForTesting(policy);
WaitForServerProbe();
}
void WaitForServerProbe() {
DataReductionProxyChromeSettings* drp_settings =
DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
browser()->profile());
PreviewsService* previews_service =
PreviewsServiceFactory::GetForProfile(browser()->profile());
PreviewsLitePageRedirectDecider* decider =
previews_service->previews_lite_page_redirect_decider();
// Wait for a completed probe to the litepages server if needed.
while (drp_settings->IsDataReductionProxyEnabled()) {
if (decider->IsServerProbeResultAvailable()) {
break;
}
base::RunLoop().RunUntilIdle();
}
}
void ProcessHintsComponent(
const optimization_guide::HintsComponentInfo& component_info) {
base::HistogramTester histogram_tester;
g_browser_process->optimization_guide_service()
->MaybeUpdateHintsComponentOnUIThread(component_info);
RetryForHistogramUntilCountReached(
&histogram_tester,
optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);
}
void InitializeOptimizationHints() {
ProcessHintsComponent(
test_hints_component_creator_.CreateHintsComponentInfoWithPageHints(
optimization_guide::proto::NOSCRIPT, {"doesntmatter.com"}, "*",
{}));
}
content::WebContents* GetWebContents() const {
return browser()->tab_strip_model()->GetActiveWebContents();
}
InfoBarService* GetInfoBarService() {
return InfoBarService::FromWebContents(GetWebContents());
}
void ExecuteScript(const std::string& script) const {
EXPECT_TRUE(content::ExecuteScript(GetWebContents(), script));
}
// Returns the loaded, non-virtual URL, of the current visible
// NavigationEntry.
GURL GetLoadedURL() const {
return GetWebContents()->GetController().GetVisibleEntry()->GetURL();
}
void VerifyPreviewLoaded() const {
// The Virtual URL is set in a WebContentsObserver::OnFinishNavigation.
// Since |ui_test_utils::NavigationToURL| uses the same signal to stop
// waiting, there is sometimes a race condition between the two, causing
// this validation to flake. Waiting for the load stop on the page will
// ensure that the Virtual URL has been set.
base::RunLoop().RunUntilIdle();
content::WaitForLoadStop(GetWebContents());
PreviewsUITabHelper* ui_tab_helper =
PreviewsUITabHelper::FromWebContents(GetWebContents());
EXPECT_TRUE(ui_tab_helper->displayed_preview_ui());
previews::PreviewsUserData* previews_data =
ui_tab_helper->previews_user_data();
EXPECT_TRUE(previews_data->HasCommittedPreviewsType());
EXPECT_EQ(previews_data->CommittedPreviewsType(),
previews::PreviewsType::LITE_PAGE_REDIRECT);
const GURL loaded_url = GetLoadedURL();
EXPECT_TRUE(loaded_url.DomainIs(previews_server_url().host()));
EXPECT_EQ(loaded_url.EffectiveIntPort(),
previews_server_url().EffectiveIntPort());
content::NavigationEntry* entry =
GetWebContents()->GetController().GetVisibleEntry();
EXPECT_EQ(content::PAGE_TYPE_NORMAL, entry->GetPageType());
const GURL virtual_url = entry->GetVirtualURL();
// The loaded url should be the previews version of the virtual url.
EXPECT_EQ(loaded_url, previews::GetLitePageRedirectURLForURL(virtual_url));
EXPECT_FALSE(virtual_url.DomainIs(previews_server_url().host()) &&
virtual_url.EffectiveIntPort() ==
previews_server_url().EffectiveIntPort());
}
void VerifyPreviewNotLoaded() const {
// The Virtual URL is set in a |WebContentsObserver::OnFinishNavigation|.
// Since |ui_test_utils::NavigationToURL| uses the same signal to stop
// waiting, there is sometimes a race condition between the two, causing
// this validation to flake. Waiting for the load stop on the page will
// ensure that the Virtual URL has been set.
base::RunLoop().RunUntilIdle();
content::WaitForLoadStop(GetWebContents());
PreviewsUITabHelper* ui_tab_helper =
PreviewsUITabHelper::FromWebContents(GetWebContents());
EXPECT_FALSE(ui_tab_helper->displayed_preview_ui());
previews::PreviewsUserData* previews_data =
ui_tab_helper->previews_user_data();
EXPECT_FALSE(previews_data->HasCommittedPreviewsType());
EXPECT_NE(previews_data->CommittedPreviewsType(),
previews::PreviewsType::LITE_PAGE_REDIRECT);
const GURL loaded_url = GetLoadedURL();
EXPECT_FALSE(loaded_url.DomainIs(previews_server_url().host()) &&
loaded_url.EffectiveIntPort() ==
previews_server_url().EffectiveIntPort());
content::NavigationEntry* entry =
GetWebContents()->GetController().GetVisibleEntry();
EXPECT_EQ(content::PAGE_TYPE_NORMAL, entry->GetPageType());
// The Virtual URL and the loaded URL should be the same.
EXPECT_EQ(loaded_url, entry->GetVirtualURL());
}
void VerifyErrorPageLoaded() const {
const GURL loaded_url = GetLoadedURL();
EXPECT_FALSE(loaded_url.DomainIs(previews_server_url().host()) &&
loaded_url.EffectiveIntPort() ==
previews_server_url().EffectiveIntPort());
content::NavigationEntry* entry =
GetWebContents()->GetController().GetVisibleEntry();
EXPECT_EQ(content::PAGE_TYPE_ERROR, entry->GetPageType());
}
void ResetDataSavings() const {
DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
browser()->profile())
->data_reduction_proxy_service()
->compression_stats()
->ResetStatistics();
}
// Gets the data usage recorded against the host the origin server runs on.
uint64_t GetDataUsage() const {
const auto& data_usage_map =
DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
browser()->profile())
->data_reduction_proxy_service()
->compression_stats()
->DataUsageMapForTesting();
const auto& it = data_usage_map.find(kOriginHost);
if (it != data_usage_map.end())
return it->second->data_used();
return 0;
}
// Gets the data usage recorded against all hosts.
uint64_t GetTotalDataUsage() const {
return DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
browser()->profile())
->data_reduction_proxy_service()
->compression_stats()
->GetHttpReceivedContentLength();
}
// Gets the original content length recorded against all hosts.
uint64_t GetTotalOriginalContentLength() const {
return DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
browser()->profile())
->data_reduction_proxy_service()
->compression_stats()
->GetHttpOriginalContentLength();
}
base::Value ParsedInterventionReport() const {
base::Value parsed_payload =
base::test::ParseJson(intervention_report_content_);
// Clear out any non-reproducible fields.
for (auto& report : parsed_payload.GetList()) {
report.RemoveKey("age");
report.RemoveKey("user_agent");
}
return parsed_payload;
}
// Returns a HTTP URL that will respond with the given action and headers when
// used by the previews server. The response can be delayed a number of
// milliseconds by passing a value > 0 for |delay_ms| or pass -1 to make the
// response hang indefinitely.
GURL HttpLitePageURL(PreviewsServerAction action,
std::string* headers = nullptr,
int delay_ms = 0) const {
std::string query = "resp=" + base::NumberToString(action);
if (delay_ms != 0)
query += "&delay_ms=" + base::NumberToString(delay_ms);
if (headers)
query += "&headers=" + *headers;
GURL::Replacements replacements;
replacements.SetQuery(query.c_str(), url::Component(0, query.length()));
return base_http_lite_page_url().ReplaceComponents(replacements);
}
// Returns a HTTPS URL that will respond with the given action and headers
// when used by the previews server. The response can be delayed a number of
// milliseconds by passing a value > 0 for |delay_ms| or pass -1 to make the
// response hang indefinitely.
GURL HttpsLitePageURL(PreviewsServerAction action,
std::string* headers = nullptr,
int delay_ms = 0) const {
std::string query = "resp=" + base::NumberToString(action);
if (delay_ms != 0)
query += "&delay_ms=" + base::NumberToString(delay_ms);
if (headers)
query += "&headers=" + *headers;
GURL::Replacements replacements;
replacements.SetQuery(query.c_str(), url::Component(0, query.length()));
return base_https_lite_page_url().ReplaceComponents(replacements);
}
void ClearDeciderState() const {
PreviewsService* previews_service =
PreviewsServiceFactory::GetForProfile(browser()->profile());
ASSERT_TRUE(previews_service);
PreviewsLitePageRedirectDecider* decider =
previews_service->previews_lite_page_redirect_decider();
ASSERT_TRUE(decider);
decider->ClearStateForTesting();
}
virtual GURL previews_server_url() const { return previews_server_url_; }
const GURL& blacklisted_https_url() const { return blacklisted_https_url_; }
const GURL& https_url() const { return https_url_; }
const GURL& base_https_lite_page_url() const {
return base_https_lite_page_url_;
}
const GURL& https_media_url() const { return https_media_url_; }
const GURL& http_url() const { return http_url_; }
const GURL& slow_http_url() const { return slow_http_url_; }
const GURL& base_http_lite_page_url() const {
return base_http_lite_page_url_;
}
const GURL& http_to_https_redirect_url() const {
return http_to_https_redirect_url_;
}
const GURL& https_to_https_redirect_url() const {
return https_to_https_redirect_url_;
}
const GURL& http_redirect_loop_url() const { return http_redirect_loop_url_; }
const GURL& https_redirect_loop_url() const {
return https_redirect_loop_url_;
}
const GURL& client_redirect_url() const { return client_redirect_url_; }
const GURL& subframe_url() const { return subframe_url_; }
int origin_probe_count() const { return origin_probe_count_; }
void set_origin_probe_success(bool success) {
origin_probe_success_ = success;
}
uint64_t got_page_id() const { return got_page_id_; }
int subresources_requested() const { return subresources_requested_; }
int previews_server_connections() const {
return previews_server_connections_.size();
}
void WaitForInterventionReport() {
if (!intervention_report_content_.empty())
return;
base::RunLoop run_loop;
waiting_for_report_closure_ = run_loop.QuitClosure();
run_loop.Run();
}
protected:
optimization_guide::testing::TestHintsComponentCreator
test_hints_component_creator_;
private:
std::unique_ptr<net::test_server::HttpResponse> HandleOriginRequest(
const net::test_server::HttpRequest& request) {
if (request.method == net::test_server::METHOD_HEAD) {
origin_probe_count_++;
if (origin_probe_success_) {
std::unique_ptr<net::test_server::BasicHttpResponse> response =
std::make_unique<net::test_server::BasicHttpResponse>();
response->set_code(net::HTTP_NO_CONTENT);
return std::move(response);
}
return std::make_unique<net::test_server::HungResponse>();
}
if (request.GetURL().spec().find("to_https_redirect") !=
std::string::npos) {
std::unique_ptr<net::test_server::BasicHttpResponse> response =
std::make_unique<net::test_server::BasicHttpResponse>();
response->set_code(net::HTTP_TEMPORARY_REDIRECT);
response->set_content_type("text/html");
response->AddCustomHeader("Location", https_url().spec());
return std::move(response);
}
if (request.GetURL().spec().find("client_redirect") != std::string::npos) {
std::unique_ptr<net::test_server::BasicHttpResponse> response =
std::make_unique<net::test_server::BasicHttpResponse>();
response->set_code(net::HTTP_OK);
response->set_content_type("text/html");
response->set_content("<html><body><script>window.location = \"" +
HttpsLitePageURL(kSuccess).spec() +
"\";</script></body></html>");
return std::move(response);
}
if (request.GetURL().spec().find("redirect_loop") != std::string::npos) {
std::unique_ptr<net::test_server::BasicHttpResponse> response =
std::make_unique<net::test_server::BasicHttpResponse>();
response->set_code(net::HTTP_TEMPORARY_REDIRECT);
response->set_content_type("text/html");
if (request.GetURL().SchemeIsCryptographic()) {
response->AddCustomHeader("Location", http_redirect_loop_url().spec());
} else {
// Provide a way out. If this request wasn't forward by the previews
// server, end the loop.
if (request.GetURL().spec().find("from_previews_server") !=
std::string::npos) {
response->AddCustomHeader("Location",
https_redirect_loop_url().spec());
} else {
response->set_code(net::HttpStatusCode::HTTP_OK);
}
}
return std::move(response);
}
return nullptr;
}
std::unique_ptr<net::test_server::HttpResponse> HandleSlowResourceRequest(
const net::test_server::HttpRequest& request) {
std::unique_ptr<net::test_server::DelayedHttpResponse> response =
std::make_unique<net::test_server::DelayedHttpResponse>(
base::TimeDelta::FromMilliseconds(500));
response->set_code(net::HttpStatusCode::HTTP_OK);
return std::move(response);
}
std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest(
const net::test_server::HttpRequest& request) {
std::unique_ptr<net::test_server::BasicHttpResponse> response =
std::make_unique<net::test_server::BasicHttpResponse>();
// If this request is for a subresource, record if the X-Client-Data header
// exists.
if (request.GetURL().spec().find("subresource.png") != std::string::npos) {
if (request.headers.find("X-Client-Data") != request.headers.end()) {
subresources_requested_++;
}
response->set_code(net::HTTP_OK);
return response;
}
// If this request is for a intervention report, record the content.
if (request.GetURL().spec().find("upload_report") != std::string::npos) {
intervention_report_content_ = request.content;
response->set_code(net::HTTP_NO_CONTENT);
if (waiting_for_report_closure_)
std::move(waiting_for_report_closure_).Run();
return response;
}
response->set_content_type("text/html");
std::string original_url_str;
// EmbeddedTestServer's request URL is 127.0.0.1 which causes
// |ExtractOriginalURLFromLitePageRedirectURL| to fail. So, if the ports
// match, fix up the url to have the preview hostname for the call to
// |ExtractOriginalURLFromLitePageRedirectURL|.
GURL url = request.GetURL();
if (url.EffectiveIntPort() == previews_server_url().EffectiveIntPort()) {
url = GURL(previews_server_url().spec() + url.path() + "?" + url.query());
}
// Ignore anything that's not a previews request with an unused status.
if (!previews::ExtractOriginalURLFromLitePageRedirectURL(
url, &original_url_str)) {
response->set_code(net::HttpStatusCode::HTTP_BAD_REQUEST);
return response;
}
GURL original_url = GURL(original_url_str);
// Reject anything that doesn't have the DataSaver headers.
const std::string want_headers[] = {"chrome-proxy-ect", "chrome-proxy"};
for (const std::string& header : want_headers) {
if (request.headers.find(header) == request.headers.end()) {
response->set_code(
net::HttpStatusCode::HTTP_PROXY_AUTHENTICATION_REQUIRED);
return response;
}
}
// The chrome-proxy header should have the pid or s option.
if (request.headers.find("chrome-proxy")->second.find("s=") ==
std::string::npos ||
request.headers.find("chrome-proxy")->second.find("pid=") ==
std::string::npos) {
response->set_code(
net::HttpStatusCode::HTTP_PROXY_AUTHENTICATION_REQUIRED);
return response;
}
net::HttpRequestHeaders headers;
headers.AddHeaderFromString("chrome-proxy: " +
request.headers.find("chrome-proxy")->second);
got_page_id_ = data_reduction_proxy::DataReductionProxyRequestOptions::
GetPageIdFromRequestHeaders(headers)
.value();
if (request.GetURL().spec().find("redirect_loop") != std::string::npos) {
response->set_code(net::HTTP_TEMPORARY_REDIRECT);
response->AddCustomHeader("Location", http_redirect_loop_url().spec() +
"?from_previews_server=true");
return std::move(response);
}
std::string delay_query_param;
int delay_ms = 0;
// Determine whether to delay the preview response using the |original_url|.
if (net::GetValueForKeyInQuery(original_url, "delay_ms",
&delay_query_param)) {
base::StringToInt(delay_query_param, &delay_ms);
}
if (delay_ms == -1) {
return std::make_unique<net::test_server::HungResponse>();
}
if (delay_ms > 0) {
response = std::make_unique<net::test_server::DelayedHttpResponse>(
base::TimeDelta::FromMilliseconds(delay_ms));
response->set_content_type("text/html");
}
std::string code_query_param;
int return_code = 0;
if (net::GetValueForKeyInQuery(original_url, "resp", &code_query_param))
base::StringToInt(code_query_param, &return_code);
GURL subresource_url("https://foo." + std::string(kPreviewsHost) + ":" +
previews_server_url().port() + "/subresource.png");
std::string subresource_body = "<html><body><img src=\"" +
subresource_url.spec() +
"\"/></body></html>";
switch (return_code) {
case kSuccess:
response->set_code(net::HTTP_OK);
response->set_content("porgporgporgporgporg" /* length = 20 */);
response->AddCustomHeader("chrome-proxy", "ofcl=60");
// Use the Host header for the report because CORS.
response->AddCustomHeader(
"Report-To",
base::StringPrintf("{\"endpoints\":[{\"url\":\"https://%s/"
"?upload_report=true\"}],\"max_age\":86400}",
request.headers.find("Host")->second.c_str()));
break;
case kRedirectNonPreview:
response->set_code(net::HTTP_TEMPORARY_REDIRECT);
response->AddCustomHeader("Location", blacklisted_https_url().spec());
break;
case kRedirectPreview:
response->set_code(net::HTTP_TEMPORARY_REDIRECT);
response->AddCustomHeader("Location",
HttpsLitePageURL(kSuccess).spec());
break;
case kRedirectLoop:
response->set_code(net::HTTP_TEMPORARY_REDIRECT);
response->AddCustomHeader("Location", https_redirect_loop_url().spec());
break;
case kBypass:
response->set_code(net::HTTP_TEMPORARY_REDIRECT);
// This will not cause a redirect loop because on following this
// redirect, the URL will no longer be a preview URL and the embedded
// test server will respond with HTTP 400.
response->AddCustomHeader("Location", HttpsLitePageURL(kBypass).spec());
break;
case kBypassAndBlacklistOriginHost:
response->set_code(net::HTTP_TEMPORARY_REDIRECT);
// This will not cause a redirect loop because on following this
// redirect, the URL will no longer be a preview URL and the embedded
// test server will respond with HTTP 400.
response->AddCustomHeader(
"Location", HttpsLitePageURL(kBypassAndBlacklistOriginHost).spec());
response->AddCustomHeader("chrome-proxy", "host-blacklisted");
break;
case kAuthFailure:
response->set_code(net::HTTP_FORBIDDEN);
break;
case kLoadshed:
response->set_code(net::HTTP_SERVICE_UNAVAILABLE);
break;
case kSubresources:
response->set_content(subresource_body);
break;
default:
response->set_code(net::HTTP_OK);
break;
}
std::string headers_query_param;
if (net::GetValueForKeyInQuery(original_url, "headers",
&headers_query_param)) {
net::HttpRequestHeaders headers;
headers.AddHeadersFromString(headers_query_param);
net::HttpRequestHeaders::Iterator iter(headers);
while (iter.GetNext())
response->AddCustomHeader(iter.name(), iter.value());
}
return std::move(response);
}
// net::test_server::EmbeddedTestServerConnectionListener:
void ReadFromSocket(const net::StreamSocket& socket, int rv) override {}
void AcceptedSocket(const net::StreamSocket& socket) override {
// AcceptedSocket is called every time there is a new HTTP request/response
// on a socket, even if the socket is being reused. So instead of
// incrementing a counter, keep track of the addresses of the socket in use.
net::IPEndPoint server_end_point;
socket.GetLocalAddress(&server_end_point);
net::IPEndPoint remote_end_point;
socket.GetPeerAddress(&remote_end_point);
std::string unique_socket_id =
server_end_point.ToString() + remote_end_point.ToString();
previews_server_connections_.insert(unique_socket_id);
}
base::test::ScopedFeatureList scoped_parameterized_feature_list_;
base::test::ScopedFeatureList scoped_feature_list_;
base::test::ScopedFeatureList url_loader_feature_list_;
base::test::ScopedFeatureList opt_guide_keyed_service_feature_list_;
base::test::ScopedFeatureList drp_holdback_feature_list_;
std::unique_ptr<net::EmbeddedTestServer> previews_server_;
std::unique_ptr<net::EmbeddedTestServer> https_server_;
std::unique_ptr<net::EmbeddedTestServer> http_server_;
std::unique_ptr<net::EmbeddedTestServer> slow_http_server_;
GURL https_url_;
GURL blacklisted_https_url_;
GURL base_https_lite_page_url_;
GURL https_media_url_;
GURL http_url_;
GURL base_http_lite_page_url_;
GURL http_to_https_redirect_url_;
GURL http_redirect_loop_url_;
GURL https_redirect_loop_url_;
GURL https_to_https_redirect_url_;
GURL client_redirect_url_;
GURL subframe_url_;
GURL previews_server_url_;
GURL slow_http_url_;
bool origin_probe_success_ = true;
int origin_probe_count_ = 0;
uint64_t got_page_id_ = 0;
int subresources_requested_ = 0;
std::unordered_set<std::string> previews_server_connections_;
std::string intervention_report_content_;
base::OnceClosure waiting_for_report_closure_;
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
class PreviewsLitePageRedirectServerBrowserTest
: public BasePreviewsLitePageRedirectServerBrowserTest,
public ::testing::WithParamInterface<std::tuple<bool, bool>> {
public:
bool UseOptimizationGuideKeyedServiceImplementation() const override {
return std::get<0>(GetParam());
}
bool ShouldEnableDRPHoldback() const override {
return std::get<1>(GetParam());
}
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be
// enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectServerBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
// Previews InfoBar (which these tests trigger) does not work on Mac.
// See https://crbug.com/782322 for detail.
// Also occasional flakes on win7 (https://crbug.com/789542).
#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
#define DISABLE_ON_WIN_MAC_CHROMESOS(x) DISABLED_##x
#else
#define DISABLE_ON_WIN_MAC_CHROMESOS(x) x
#endif
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsTriggering)) {
// TODO(crbug.com/874150): Use ExpectUniqueSample in these tests.
// The histograms in these tests can only be checked by the expected bucket,
// and not by a unique sample. This is because each navigation to a preview
// will cause two navigations and two records, one for the original navigation
// under test, and another one for loading the preview.
{
// Verify the preview is not triggered on HTTP pageloads.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
}
{
// Verify the preview is triggered on HTTPS pageloads.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
}
{
// Verify the preview is not triggered when loading a media resource.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), https_media_url());
VerifyPreviewNotLoaded();
ClearDeciderState();
histogram_tester.ExpectBucketCount(
"Previews.EligibilityReason.LitePageRedirect",
static_cast<int>(
previews::PreviewsEligibilityReason::EXCLUDED_BY_MEDIA_SUFFIX),
1);
}
{
// Verify the preview is not triggered for POST navigations.
std::string post_data = "helloworld";
NavigateParams params(browser(), https_url(), ui::PAGE_TRANSITION_LINK);
params.window_action = NavigateParams::SHOW_WINDOW;
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
params.is_renderer_initiated = false;
params.uses_post = true;
params.post_data = network::ResourceRequestBody::CreateFromBytes(
post_data.data(), post_data.size());
ui_test_utils::NavigateToURL(&params);
base::RunLoop().RunUntilIdle();
content::WaitForLoadStop(GetWebContents());
PreviewsUITabHelper* ui_tab_helper =
PreviewsUITabHelper::FromWebContents(GetWebContents());
EXPECT_FALSE(ui_tab_helper->displayed_preview_ui());
EXPECT_FALSE(ui_tab_helper->previews_user_data());
ClearDeciderState();
}
{
// Verify the preview is not triggered when navigating to the previews
// server.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(
browser(),
previews::GetLitePageRedirectURLForURL(HttpsLitePageURL(kSuccess)));
VerifyPreviewNotLoaded();
}
{
// Verify the preview is not triggered when navigating to a private IP.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), GURL("https://0.0.0.0/"));
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.BlacklistReasons",
previews::LitePageRedirectBlacklistReason::kNavigationToPrivateDomain,
1);
VerifyErrorPageLoaded();
}
{
// Verify the preview is not triggered when navigating to a domain without a
// dot.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), GURL("https://no-dots-here/"));
VerifyErrorPageLoaded();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.BlacklistReasons",
previews::LitePageRedirectBlacklistReason::kNavigationToPrivateDomain,
1);
}
{
// Verify a preview is only shown on slow networks.
base::HistogramTester histogram_tester;
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_3G);
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
histogram_tester.ExpectTotalCount(
"Previews.ServerLitePage.PreresolvedToPreviewServer", 0);
// Reset ECT for future tests.
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_2G);
}
{
// Verify a preview is not shown for an unknown ECT.
base::HistogramTester histogram_tester;
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
// Reset ECT for future tests.
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
}
{
// Verify a preview is not shown if cookies are blocked.
base::HistogramTester histogram_tester;
int before_subresources_requested = subresources_requested();
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSubresources));
VerifyPreviewLoaded();
EXPECT_EQ(before_subresources_requested + 1, subresources_requested());
CookieSettingsFactory::GetForProfile(browser()->profile())
->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSubresources));
VerifyPreviewNotLoaded();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.IneligibleReasons",
previews::LitePageRedirectIneligibleReason::kCookiesBlocked, 1);
// Reset state for other tests.
CookieSettingsFactory::GetForProfile(browser()->profile())
->SetDefaultCookieSetting(CONTENT_SETTING_ALLOW);
}
{
// Verify a preview is not shown for a redirect loop.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kRedirectLoop));
// Make sure we're done with all the navigation restarts before running
// checks.
for (int i = 0; i < kRedirectLoopCount + 1; i++) {
base::RunLoop().RunUntilIdle();
content::WaitForLoadStop(GetWebContents());
}
VerifyPreviewNotLoaded();
ClearDeciderState();
}
{
// Verify a subframe navigation does not trigger a preview.
const base::string16 kSubframeTitle = base::ASCIIToUTF16("Subframe");
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), subframe_url());
// Navigate in the subframe and wait for it to finish. The waiting is
// accomplished by |ExecuteScriptAndExtractString| which waits for
// |window.domAutomationController.send| in the HTML page.
std::string result;
EXPECT_TRUE(ExecuteScriptAndExtractString(
GetWebContents()->GetMainFrame(),
"window.open(\"" + HttpsLitePageURL(kSuccess).spec() +
"\", \"subframe\")",
&result));
EXPECT_EQ(kSubframeTitle, base::ASCIIToUTF16(result));
}
{
base::HistogramTester histogram_tester;
NavigateParams params(browser(), https_url(), ui::PAGE_TRANSITION_FROM_API);
ui_test_utils::NavigateToURL(&params);
VerifyPreviewNotLoaded();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.IneligibleReasons",
previews::LitePageRedirectIneligibleReason::kAPIPageTransition, 1);
}
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsOriginProbe_Success)) {
set_origin_probe_success(true);
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
EXPECT_EQ(1, origin_probe_count());
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsOriginProbe_Fail)) {
set_origin_probe_success(false);
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
EXPECT_EQ(1, origin_probe_count());
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsReloadSoftOptOut)) {
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, false);
VerifyPreviewNotLoaded();
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsNoChromeProxyHeader)) {
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
// Mimic a bad proxy header update.
net::HttpRequestHeaders empty;
PreviewsService* previews_service =
PreviewsServiceFactory::GetForProfile(browser()->profile());
PreviewsLitePageRedirectDecider* decider =
previews_service->previews_lite_page_redirect_decider();
decider->OnProxyRequestHeadersChanged(empty);
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.IneligibleReasons",
static_cast<int>(
previews::LitePageRedirectIneligibleReason::kInvalidProxyHeaders),
1);
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(CoinFlipHoldbackTriggering)) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeatureWithParameters(
{previews::features::kCoinFlipHoldback},
{{"force_coin_flip_always_holdback", "true"}});
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
}
IN_PROC_BROWSER_TEST_P(PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(PredictorShownAndHidden)) {
base::HistogramTester histogram_tester;
GetWebContents()->WasHidden();
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
histogram_tester.ExpectTotalCount(
"Previews.ServerLitePage.PreconnectedToPreviewServer", 0);
GetWebContents()->WasShown();
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
// We expect a value of 2 because the timer will be triggered twice, once when
// the web contents is shown, and once when a new page is committed.
histogram_tester.ExpectUniqueSample(
"Previews.ServerLitePage.PreconnectedToPreviewServer", false, 2);
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsLoadOriginal)) {
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
PreviewsServiceFactory::GetForProfile(
Profile::FromBrowserContext(browser()
->tab_strip_model()
->GetActiveWebContents()
->GetBrowserContext()))
->previews_ui_service()
->previews_decider_impl()
->SetIgnorePreviewsBlacklistDecision(false /* ignored */);
PreviewsUITabHelper::FromWebContents(GetWebContents())
->ReloadWithoutPreviews();
VerifyPreviewNotLoaded();
}
IN_PROC_BROWSER_TEST_P(PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsRedirect)) {
{
// Verify the preview is triggered when an HTTP page redirects to HTTPS.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), http_to_https_redirect_url());
VerifyPreviewLoaded();
}
{
// Verify the preview is triggered when an HTTPS page redirects to HTTPS.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), https_to_https_redirect_url());
VerifyPreviewLoaded();
}
{
// Verify the preview is not triggered when the previews server redirects to
// a non-preview page.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(),
HttpsLitePageURL(kRedirectNonPreview));
VerifyPreviewNotLoaded();
ClearDeciderState();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.ServerResponse",
previews::LitePageRedirectServerResponse::kRedirect, 1);
}
{
// Verify the preview is triggered when the previews server redirects to a
// preview page.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kRedirectPreview));
VerifyPreviewLoaded();
ClearDeciderState();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.ServerResponse",
previews::LitePageRedirectServerResponse::kRedirect, 1);
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.ServerResponse",
previews::LitePageRedirectServerResponse::kOk, 1);
}
}
IN_PROC_BROWSER_TEST_P(PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsResponse)) {
{
// Verify the preview is not triggered when the server responds with bypass
// 307.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kBypass));
VerifyPreviewNotLoaded();
ClearDeciderState();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.ServerResponse",
previews::LitePageRedirectServerResponse::kPreviewUnavailable, 1);
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.HostBlacklistedOnBypass", false, 1);
}
{
// Verify the preview is not triggered when the server responds with bypass
// 307 and host-blacklist.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(
browser(), HttpsLitePageURL(kBypassAndBlacklistOriginHost));
VerifyPreviewNotLoaded();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.ServerResponse",
previews::LitePageRedirectServerResponse::kPreviewUnavailable, 1);
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.HostBlacklistedOnBypass", true, 1);
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.BlacklistReasons",
previews::LitePageRedirectBlacklistReason::kHostBypassBlacklisted, 1);
ClearDeciderState();
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
}
{
// Verify the preview is not triggered when the server responds with 503.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kLoadshed));
VerifyPreviewNotLoaded();
ClearDeciderState();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.ServerResponse",
previews::LitePageRedirectServerResponse::kServiceUnavailable, 1);
}
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsAuthFailure)) {
// Verify the preview is not triggered when the server responds with 403.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kAuthFailure));
VerifyPreviewNotLoaded();
ClearDeciderState();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.ServerResponse",
previews::LitePageRedirectServerResponse::kAuthFailure, 1);
// DRP config is invalid, a subsequent preview page load should fail.
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.IneligibleReasons",
previews::LitePageRedirectIneligibleReason::kInvalidProxyHeaders, 1);
}
IN_PROC_BROWSER_TEST_P(PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsLoadshed)) {
PreviewsService* previews_service =
PreviewsServiceFactory::GetForProfile(browser()->profile());
ASSERT_TRUE(previews_service);
PreviewsLitePageRedirectDecider* decider =
previews_service->previews_lite_page_redirect_decider();
ASSERT_TRUE(decider);
std::unique_ptr<base::SimpleTestTickClock> clock =
std::make_unique<base::SimpleTestTickClock>();
decider->SetClockForTesting(clock.get());
// Send a loadshed response. Client should not retry for a randomly chosen
// duration [1 min, 5 mins).
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kLoadshed));
VerifyPreviewNotLoaded();
ClearDeciderState();
clock->Advance(base::TimeDelta::FromMinutes(1));
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
clock->Advance(base::TimeDelta::FromMinutes(4));
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
// Send a loadshed response with a specific time duration, 30 seconds, to
// retry after.
std::string headers = "Retry-After: 30";
ui_test_utils::NavigateToURL(browser(),
HttpsLitePageURL(kLoadshed, &headers));
VerifyPreviewNotLoaded();
ClearDeciderState();
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
clock->Advance(base::TimeDelta::FromSeconds(31));
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePageURLNotReportedToHistory)) {
base::CancelableTaskTracker tracker_;
history::HistoryService* history_service =
HistoryServiceFactory::GetForProfile(browser()->profile(),
ServiceAccessType::EXPLICIT_ACCESS);
// Verify the lite pages URL doesn't make it into the History Service via
// the committed URL.
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
{
base::RunLoop loop;
history_service->QueryURL(
HttpsLitePageURL(kSuccess), false /* want_visits */,
base::BindLambdaForTesting([&](history::QueryURLResult result) {
EXPECT_TRUE(result.success);
loop.Quit();
}),
&tracker_);
loop.Run();
}
{
base::RunLoop loop;
history_service->QueryURL(
previews::GetLitePageRedirectURLForURL(HttpsLitePageURL(kSuccess)),
false /* want_visits */,
base::BindLambdaForTesting([&](history::QueryURLResult result) {
EXPECT_FALSE(result.success);
loop.Quit();
}),
&tracker_);
loop.Run();
}
// Verify the lite pages URL doesn't make it into the History Service via the
// redirect chain.
ui_test_utils::NavigateToURL(browser(),
HttpsLitePageURL(kRedirectNonPreview));
VerifyPreviewNotLoaded();
{
base::RunLoop loop;
history_service->QueryRedirectsFrom(
HttpsLitePageURL(kRedirectNonPreview),
base::BindLambdaForTesting([&](history::RedirectList redirects) {
EXPECT_FALSE(redirects.empty());
for (const GURL& url : redirects) {
EXPECT_FALSE(previews::IsLitePageRedirectPreviewURL(url));
}
loop.Quit();
}),
&tracker_);
loop.Run();
}
ClearDeciderState();
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsReportSavings)) {
PrefService* prefs = browser()->profile()->GetPrefs();
prefs->SetBoolean(data_reduction_proxy::prefs::kDataUsageReportingEnabled,
true);
// Give the setting notification a chance to propagate.
base::RunLoop().RunUntilIdle();
ResetDataSavings();
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
base::RunLoop().RunUntilIdle();
// Navigate to an untracked (no preview) page before checking reported savings
// to reduce flakiness.
ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
EXPECT_EQ(GetTotalOriginalContentLength() - GetTotalDataUsage(), 40U);
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsClientRedirect)) {
// Navigate to a non-preview first.
ui_test_utils::NavigateToURL(browser(), https_media_url());
VerifyPreviewNotLoaded();
// Navigate to a page that causes a client redirect to a page that will
// get a preview.
ui_test_utils::NavigateToURL(browser(), client_redirect_url());
VerifyPreviewLoaded();
EXPECT_EQ(GetWebContents()->GetController().GetEntryAtOffset(-1)->GetURL(),
https_media_url());
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsNavigation)) {
{
SCOPED_TRACE("First preview load");
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
}
{
SCOPED_TRACE("Go to a new page that doesn't Preview");
ui_test_utils::NavigateToURL(browser(), http_url());
VerifyPreviewNotLoaded();
ClearDeciderState();
}
// Note: |VerifyPreviewLoaded| calls |content::WaitForLoadStop()| so these are
// safe.
{
SCOPED_TRACE("Navigate back");
GetWebContents()->GetController().GoBack();
VerifyPreviewNotLoaded();
}
{
SCOPED_TRACE("Navigate forward");
GetWebContents()->GetController().GoForward();
VerifyPreviewNotLoaded();
ClearDeciderState();
}
{
SCOPED_TRACE("Navigate back again");
GetWebContents()->GetController().GoBack();
VerifyPreviewLoaded();
}
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePageSendsInterventionReport)) {
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
WaitForInterventionReport();
base::Value expected = base::test::ParseJson(base::StringPrintf(
R"text(
[
{
"body": {
"id": "LitePageServed",
"message": "Modified page load behavior on the page because )text"
R"text(the page was expected to take a long amount of time to load. )text"
R"text(https://www.chromestatus.com/feature/5148050062311424"
},
"type": "intervention",
"url": "%s",
}
]
)text",
previews::GetLitePageRedirectURLForURL(HttpsLitePageURL(kSuccess))
.spec()
.c_str()));
EXPECT_EQ(expected, ParsedInterventionReport());
}
class PreviewsLitePageRedirectServerTimeoutBrowserTest
: public PreviewsLitePageRedirectServerBrowserTest {
public:
PreviewsLitePageRedirectServerTimeoutBrowserTest() = default;
~PreviewsLitePageRedirectServerTimeoutBrowserTest() override = default;
void SetUp() override {
SetUpLitePageTest(true /* use_timeout */, false /* is_control */);
InProcessBrowserTest::SetUp();
}
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectServerTimeoutBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
IN_PROC_BROWSER_TEST_P(PreviewsLitePageRedirectServerTimeoutBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsTimeout)) {
{
// Ensure that a hung previews navigation doesn't wind up at the previews
// server.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(),
HttpsLitePageURL(kSuccess, nullptr, -1));
VerifyPreviewNotLoaded();
ClearDeciderState();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.ServerResponse",
previews::LitePageRedirectServerResponse::kTimeout, 1);
}
{
// Ensure that a hung normal navigation eventually loads.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), slow_http_url());
VerifyPreviewNotLoaded();
ClearDeciderState();
histogram_tester.ExpectTotalCount("Previews.ServerLitePage.ServerResponse",
0);
}
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerTimeoutBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
LitePagePreviewsOriginProbe_ExternalFailureReported)) {
set_origin_probe_success(true);
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(),
HttpsLitePageURL(kSuccess, nullptr, -1));
VerifyPreviewNotLoaded();
ClearDeciderState();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.ServerResponse",
previews::LitePageRedirectServerResponse::kTimeout, 1);
WaitForServerProbe();
histogram_tester.ExpectUniqueSample(
"Availability.Prober.DidSucceed.AfterReportedFailure.Litepages", true, 1);
}
class PreviewsLitePageRedirectServerBadServerBrowserTest
: public PreviewsLitePageRedirectServerBrowserTest {
public:
PreviewsLitePageRedirectServerBadServerBrowserTest() = default;
~PreviewsLitePageRedirectServerBadServerBrowserTest() override = default;
// Override the previews_server URL so that a bad value will be configured.
GURL previews_server_url() const override {
return GURL("https://bad-server.com");
}
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectServerBadServerBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerBadServerBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsBadServer)) {
// TODO(crbug.com/874150): Use ExpectUniqueSample in this tests.
// The histograms in this tests can only be checked by the expected bucket,
// and not by a unique sample. This is because each navigation to a preview
// will cause two navigations and two records, one for the original navigation
// under test, and another one for loading the preview.
{
// Verify the preview is not shown on a bad previews server because it was
// never triggered due to a failed probe.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.IneligibleReasons",
previews::LitePageRedirectIneligibleReason::kServiceProbeFailed, 1);
}
}
class PreviewsLitePageRedirectServerDataSaverBrowserTest
: public PreviewsLitePageRedirectServerBrowserTest {
public:
PreviewsLitePageRedirectServerDataSaverBrowserTest() = default;
~PreviewsLitePageRedirectServerDataSaverBrowserTest() override = default;
// Overrides the cmd line in PreviewsLitePageRedirectServerBrowserTest and
// leave out the flag to enable DataSaver.
void SetUpCommandLine(base::CommandLine* cmd) override {
// Due to race conditions, it's possible that blacklist data is not loaded
// at the time of first navigation. That may prevent Preview from
// triggering, and causing the test to flake.
cmd->AppendSwitch(previews::switches::kIgnorePreviewsBlacklist);
cmd->AppendSwitchASCII("force-effective-connection-type", "Slow-2G");
cmd->AppendSwitchASCII("host-rules", "MAP * 127.0.0.1");
cmd->AppendSwitch("ignore-litepage-redirect-optimization-blacklist");
}
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectServerDataSaverBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerDataSaverBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsDSTriggering)) {
// Verify the preview is not triggered on HTTPS pageloads without DataSaver.
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
}
class PreviewsLitePageRedirectServerNoDataSaverHeaderBrowserTest
: public PreviewsLitePageRedirectServerBrowserTest {
public:
PreviewsLitePageRedirectServerNoDataSaverHeaderBrowserTest() = default;
~PreviewsLitePageRedirectServerNoDataSaverHeaderBrowserTest() override =
default;
// Overrides the command line in PreviewsLitePageRedirectServerBrowserTest to
// leave out the flag that manually adds the chrome-proxy header.
void SetUpCommandLine(base::CommandLine* cmd) override {
// Due to race conditions, it's possible that blacklist data is not loaded
// at the time of first navigation. That may prevent Preview from
// triggering, and causing the test to flake.
cmd->AppendSwitch(previews::switches::kIgnorePreviewsBlacklist);
cmd->AppendSwitch("enable-spdy-proxy-auth");
cmd->AppendSwitchASCII("force-effective-connection-type", "Slow-2G");
cmd->AppendSwitchASCII("host-rules", "MAP * 127.0.0.1");
cmd->AppendSwitch("ignore-litepage-redirect-optimization-blacklist");
}
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectServerNoDataSaverHeaderBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerNoDataSaverHeaderBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsDSNoHeaderTriggering)) {
// Verify the preview is not triggered on HTTPS pageloads without data saver.
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
}
class PreviewsLitePageRedirectNotificationDSEnabledBrowserTest
: public PreviewsLitePageRedirectServerBrowserTest {
public:
PreviewsLitePageRedirectNotificationDSEnabledBrowserTest() = default;
~PreviewsLitePageRedirectNotificationDSEnabledBrowserTest() override =
default;
void SetUp() override {
SetUpLitePageTest(false /* use_timeout */, false /* is_control */);
InProcessBrowserTest::SetUp();
}
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
InitializeOptimizationHints();
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_2G);
WaitForServerProbe();
}
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectNotificationDSEnabledBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectNotificationDSEnabledBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsInfoBarDataSaverUser)) {
// Ensure the preview is not shown the first time before the infobar is shown
// for users who have DRP enabled.
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
ASSERT_EQ(1U, GetInfoBarService()->infobar_count());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_LITE_PAGE_PREVIEWS_MESSAGE),
static_cast<ConfirmInfoBarDelegate*>(
GetInfoBarService()->infobar_at(0)->delegate())
->GetMessageText());
histogram_tester.ExpectBucketCount(
"Previews.ServerLitePage.IneligibleReasons",
previews::LitePageRedirectIneligibleReason::kInfoBarNotSeen, 1);
}
class PreviewsLitePageRedirectDSDisabledBrowserTest
: public PreviewsLitePageRedirectServerBrowserTest {
public:
PreviewsLitePageRedirectDSDisabledBrowserTest() = default;
~PreviewsLitePageRedirectDSDisabledBrowserTest() override = default;
void SetUp() override {
SetUpLitePageTest(false /* use_timeout */, false /* is_control */);
InProcessBrowserTest::SetUp();
}
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_2G);
}
// Overrides the cmd line in PreviewsLitePageRedirectServerBrowserTest and
// leave out the flag to enable DataSaver.
void SetUpCommandLine(base::CommandLine* cmd) override {
// Due to race conditions, it's possible that blacklist data is not loaded
// at the time of first navigation. That may prevent Preview from
// triggering, and causing the test to flake.
cmd->AppendSwitch(previews::switches::kIgnorePreviewsBlacklist);
cmd->AppendSwitchASCII("force-effective-connection-type", "Slow-2G");
cmd->AppendSwitchASCII("host-rules", "MAP * 127.0.0.1");
cmd->AppendSwitch("ignore-litepage-redirect-optimization-blacklist");
}
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectDSDisabledBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectDSDisabledBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsInfoBarNonDataSaverUser)) {
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
EXPECT_EQ(0U, GetInfoBarService()->infobar_count());
histogram_tester.ExpectTotalCount(
"Previews.ServerLitePage.PreresolvedToPreviewServer", 0);
}
class PreviewsLitePageRedirectControlBrowserTest
: public PreviewsLitePageRedirectServerBrowserTest {
public:
PreviewsLitePageRedirectControlBrowserTest() = default;
~PreviewsLitePageRedirectControlBrowserTest() override = default;
void SetUp() override {
SetUpLitePageTest(false /* use_timeout */, true /* is_control */);
InProcessBrowserTest::SetUp();
}
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectControlBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectControlBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsControlGroup)) {
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewNotLoaded();
ClearDeciderState();
}
enum class NetworkIsolationKeyMode {
kNone,
kTopFrameOrigin,
kTopFrameAndFrameOrigins,
};
class PreviewsLitePageRedirectServerNetworkIsolationBrowserTest
: public BasePreviewsLitePageRedirectServerBrowserTest,
public testing::WithParamInterface<NetworkIsolationKeyMode> {
public:
void SetUp() override {
BasePreviewsLitePageRedirectServerBrowserTest::SetUp();
switch (GetParam()) {
case NetworkIsolationKeyMode::kNone:
break;
case NetworkIsolationKeyMode::kTopFrameOrigin:
scoped_feature_list_.InitWithFeatures(
// enabled_features
{net::features::kPartitionConnectionsByNetworkIsolationKey,
// While these tests are focusing on partitioning the socket pools,
// some depend on cache behavior, and it would be
// unfortunate if splitting the cache by the key as well broke
// them.
net::features::kSplitCacheByNetworkIsolationKey},
// disabled_features
{net::features::kAppendFrameOriginToNetworkIsolationKey});
break;
case NetworkIsolationKeyMode::kTopFrameAndFrameOrigins:
scoped_feature_list_.InitWithFeatures(
// enabled_features
{net::features::kPartitionConnectionsByNetworkIsolationKey,
net::features::kSplitCacheByNetworkIsolationKey,
net::features::kAppendFrameOriginToNetworkIsolationKey},
// disabled_features
{});
break;
}
}
bool UseOptimizationGuideKeyedServiceImplementation() const override {
return false;
}
bool ShouldEnableDRPHoldback() const override { return false; }
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectServerNetworkIsolationBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(PreconnectToPreviewsServer)) {
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), https_media_url());
VerifyPreviewNotLoaded();
histogram_tester.ExpectUniqueSample(
"Previews.ServerLitePage.PredictorToggled", true, 1);
histogram_tester.ExpectUniqueSample(
"Previews.ServerLitePage.PreconnectedToPreviewServer", true, 1);
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
WaitForInterventionReport();
// Proving which socket is reused for which purpose is tricky in a browsertest
// because everything happens so quickly. Instead, just prove by
// pigeon-holing. These connections are sent to server, and we expect at least
// one to be reused:
// * Startup probe
// * Preconnect
// * Main page request
// * Favicon request
// * Browser intervention report
EXPECT_LT(previews_server_connections(), 5);
}
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectServerNetworkIsolationBrowserTest,
::testing::Values(NetworkIsolationKeyMode::kNone,
NetworkIsolationKeyMode::kTopFrameOrigin,
NetworkIsolationKeyMode::kTopFrameAndFrameOrigins));
class PreviewsLitePageRedirectAndPageHintsBrowserTest
: public PreviewsLitePageRedirectServerBrowserTest {
public:
PreviewsLitePageRedirectAndPageHintsBrowserTest() = default;
~PreviewsLitePageRedirectAndPageHintsBrowserTest() override = default;
void SetResourceLoadingHints(const std::vector<std::string>& hints_sites) {
std::vector<std::string> resource_patterns;
resource_patterns.push_back("foo.jpg");
resource_patterns.push_back("png");
resource_patterns.push_back("woff2");
ProcessHintsComponent(
test_hints_component_creator_.CreateHintsComponentInfoWithPageHints(
optimization_guide::proto::RESOURCE_LOADING, hints_sites, "*",
resource_patterns));
}
void SetUpCommandLine(base::CommandLine* cmd) override {
PreviewsLitePageRedirectServerBrowserTest::SetUpCommandLine(cmd);
cmd->AppendSwitch("optimization-guide-disable-installer");
cmd->AppendSwitch("purge_hint_cache_store");
}
void WriteConfigToFile(const optimization_guide::proto::Configuration& config,
const base::FilePath& filePath) {
std::string serialized_config;
ASSERT_TRUE(config.SerializeToString(&serialized_config));
ASSERT_EQ(static_cast<int32_t>(serialized_config.length()),
base::WriteFile(filePath, serialized_config.data(),
serialized_config.length()));
}
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
PreviewsLitePageRedirectAndPageHintsBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
// Regression test for crbug.com/954554.
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectAndPageHintsBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(PreviewsServerIsInBloomFilter)) {
optimization_guide::BloomFilter blacklist_bloom_filter(7, 511);
blacklist_bloom_filter.Add(previews_server_url().host());
blacklist_bloom_filter.Add("subdomain." + previews_server_url().host());
std::string blacklist_data((char*)&blacklist_bloom_filter.bytes()[0],
blacklist_bloom_filter.bytes().size());
optimization_guide::proto::Configuration config;
optimization_guide::proto::OptimizationFilter* blacklist_proto =
config.add_optimization_blacklists();
blacklist_proto->set_optimization_type(
optimization_guide::proto::LITE_PAGE_REDIRECT);
std::unique_ptr<optimization_guide::proto::BloomFilter> bloom_filter_proto =
std::make_unique<optimization_guide::proto::BloomFilter>();
bloom_filter_proto->set_num_hash_functions(7);
bloom_filter_proto->set_num_bits(511);
bloom_filter_proto->set_data(blacklist_data);
blacklist_proto->set_allocated_bloom_filter(bloom_filter_proto.release());
base::ScopedAllowBlockingForTesting allow_blocking;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
optimization_guide::HintsComponentInfo info(
base::Version("2.0.0"),
temp_dir.GetPath().Append(FILE_PATH_LITERAL("somefile.pb")));
ASSERT_NO_FATAL_FAILURE(WriteConfigToFile(config, info.path));
ProcessHintsComponent(info);
ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
VerifyPreviewLoaded();
}
IN_PROC_BROWSER_TEST_P(
PreviewsLitePageRedirectAndPageHintsBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsDoesNotOverridePageHints)) {
base::HistogramTester histogram_tester;
// Whitelist test URL for resource loading hints.
GURL url = HttpsLitePageURL(kSuccess);
SetResourceLoadingHints({url.host()});
ui_test_utils::NavigateToURL(browser(), url);
base::RunLoop().RunUntilIdle();
content::WaitForLoadStop(GetWebContents());
// Verify the committed previews type is resource loading hints.
PreviewsUITabHelper* ui_tab_helper =
PreviewsUITabHelper::FromWebContents(GetWebContents());
EXPECT_TRUE(ui_tab_helper->displayed_preview_ui());
previews::PreviewsUserData* previews_data =
ui_tab_helper->previews_user_data();
EXPECT_TRUE(previews_data->HasCommittedPreviewsType());
EXPECT_EQ(previews_data->CommittedPreviewsType(),
previews::PreviewsType::RESOURCE_LOADING_HINTS);
ClearDeciderState();
}
class CoinFlipHoldbackExperimentBrowserTest
: public PreviewsLitePageRedirectAndPageHintsBrowserTest {
public:
CoinFlipHoldbackExperimentBrowserTest() = default;
~CoinFlipHoldbackExperimentBrowserTest() override = default;
void SetUp() override {
PreviewsLitePageRedirectAndPageHintsBrowserTest::SetUp();
ukm_feature_list_.InitAndEnableFeature(ukm::kUkmFeature);
}
void SetUpCommandLine(base::CommandLine* cmd) override {
PreviewsLitePageRedirectAndPageHintsBrowserTest::SetUpCommandLine(cmd);
cmd->AppendSwitch("litepage_redirect_overrides_page_hints");
}
void PreRunTestOnMainThread() override {
InProcessBrowserTest::PreRunTestOnMainThread();
ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
}
// |coin_flip_holdback_enabled|: Whether the coin flip holdback feature flag
// should be enabled.
//
// |redirect_navigation|: Whether a preview should only be eligible on a
// redirect.
//
// |allow_lite_page_redirect|: Whether a lite page redirect preview should be
// eligible.
//
// |allow_resource_loading|: Whether a resource loading preview should be
// eligible.
//
// |set_random_navigation_coin_flip|: What the random coin flip should be.
// True is holdback, false is allowed.
void RunTest(bool coin_flip_holdback_enabled,
bool redirect_navigation,
bool allow_lite_page_redirect,
bool allow_resource_loading,
bool set_random_navigation_coin_flip) {
ukm::InitializeSourceUrlRecorderForWebContents(GetWebContents());
if (coin_flip_holdback_enabled) {
scoped_feature_list_.InitAndEnableFeatureWithParameters(
previews::features::kCoinFlipHoldback,
{{"force_coin_flip_always_holdback",
set_random_navigation_coin_flip ? "true" : "false"},
{"force_coin_flip_always_allow",
!set_random_navigation_coin_flip ? "true" : "false"}});
} else {
scoped_feature_list_.InitAndDisableFeature(
previews::features::kCoinFlipHoldback);
}
GURL final_url = blacklisted_https_url();
GURL starting_url = redirect_navigation
? HttpsLitePageURL(kRedirectNonPreview)
: blacklisted_https_url();
if (allow_lite_page_redirect) {
final_url = HttpsLitePageURL(kSuccess);
starting_url = redirect_navigation ? http_to_https_redirect_url()
: HttpsLitePageURL(kSuccess);
}
if (allow_resource_loading)
SetResourceLoadingHints({final_url.host()});
ASSERT_EQ(redirect_navigation, starting_url != final_url);
ui_test_utils::NavigateToURL(browser(), starting_url);
base::RunLoop().RunUntilIdle();
content::WaitForLoadStop(GetWebContents());
}
void ValidateResult(bool want_lite_page_redirect_committed,
bool want_resource_loading_committed,
int want_ukm_coin_flip_holdback_result,
bool want_ukm_previews_likely) {
PreviewsUITabHelper* ui_tab_helper =
PreviewsUITabHelper::FromWebContents(GetWebContents());
EXPECT_EQ(
want_lite_page_redirect_committed || want_resource_loading_committed,
ui_tab_helper->displayed_preview_ui());
previews::PreviewsUserData* previews_data =
ui_tab_helper->previews_user_data();
if (want_lite_page_redirect_committed) {
VerifyPreviewLoaded();
EXPECT_NE(previews_data->coin_flip_holdback_result(),
previews::CoinFlipHoldbackResult::kHoldback);
}
if (want_resource_loading_committed) {
EXPECT_EQ(previews_data->CommittedPreviewsType(),
previews::PreviewsType::RESOURCE_LOADING_HINTS);
}
EXPECT_EQ(want_ukm_coin_flip_holdback_result,
static_cast<int>(previews_data->coin_flip_holdback_result()));
ValidateUKM(want_lite_page_redirect_committed,
want_resource_loading_committed,
want_ukm_coin_flip_holdback_result, want_ukm_previews_likely);
}
void ValidateUKM(bool want_lite_page_redirect_committed,
bool want_resource_loading_committed,
int want_ukm_coin_flip_holdback_result,
bool want_ukm_previews_likely) {
if (!want_lite_page_redirect_committed &&
!want_resource_loading_committed) {
return;
}
if (want_ukm_coin_flip_holdback_result ==
static_cast<int>(previews::CoinFlipHoldbackResult::kNotSet)) {
return;
}
{
using UkmEntry = ukm::builders::PreviewsCoinFlip;
auto entries = ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
// EXPECT_EQ(1u, entries.size());
for (auto* entry : entries) {
ukm_recorder_->ExpectEntryMetric(entry, UkmEntry::kcoin_flip_resultName,
want_ukm_coin_flip_holdback_result);
}
}
// Navigate to a non-preview page to trigger the UKM PLM Observer to
// record.
ui_test_utils::NavigateToURL(browser(), GURL("http://nopreviews"));
base::RunLoop().RunUntilIdle();
content::WaitForLoadStop(GetWebContents());
{
using UkmEntry = ukm::builders::Previews;
auto entries = ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
EXPECT_EQ(1u, entries.size());
for (auto* entry : entries) {
ukm_recorder_->ExpectEntryMetric(entry, UkmEntry::kpreviews_likelyName,
want_ukm_previews_likely ? 1 : 0);
}
}
}
private:
std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;
base::test::ScopedFeatureList scoped_feature_list_;
base::test::ScopedFeatureList ukm_feature_list_;
};
// First param is true if testing using the OptimizationGuideKeyedService
// implementation. Second param is true if DRP holdback should be enabled.
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
CoinFlipHoldbackExperimentBrowserTest,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
IN_PROC_BROWSER_TEST_P(CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(NoPreviews_NoCoinFlip)) {
// Set ECT so that we are sure to not trigger any preview.
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_4G);
RunTest(false /* coin_flip_holdback_enabled */,
false /* redirect_navigation*/, false /* allow_lite_page_redirect*/,
false /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
false /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(BothPreviewsAllowedWantLPR_NoCoinFlip)) {
RunTest(false /* coin_flip_holdback_enabled */,
false /* redirect_navigation*/, true /* allow_lite_page_redirect*/,
true /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(true /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LPRAllowed_NoCoinFlip)) {
RunTest(false /* coin_flip_holdback_enabled */,
false /* redirect_navigation*/, true /* allow_lite_page_redirect*/,
false /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(true /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(RLHAllowed_NoCoinFlip)) {
RunTest(false /* coin_flip_holdback_enabled */,
false /* redirect_navigation*/, false /* allow_lite_page_redirect*/,
true /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
true /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(NoPreviews_WithRedirect_NoCoinFlip)) {
// Set ECT so that we are sure to not trigger any preview.
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_4G);
RunTest(false /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
false /* allow_lite_page_redirect*/,
false /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
false /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
BothPreviewsAllowedWantLPR_WithRedirect_NoCoinFlip)) {
RunTest(false /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
true /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(true /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LPRAllowed_WithRedirect_NoCoinFlip)) {
RunTest(false /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
true /* allow_lite_page_redirect*/,
false /* allow_resource_loading */,
false /* set_random_navigation_coin_flip*/);
ValidateResult(true /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(RLHAllowed_WithRedirect_NoCoinFlip)) {
RunTest(false /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
false /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
true /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(NoPreviews_CoinFlipEnabled_Allowed)) {
// Set ECT so that we are sure to not trigger any preview.
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_4G);
RunTest(true /* coin_flip_holdback_enabled */, false /* redirect_navigation*/,
false /* allow_lite_page_redirect*/,
false /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
false /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
BothPreviewsAllowedWantLPR_CoinFlipEnabled_Allowed)) {
RunTest(true /* coin_flip_holdback_enabled */, false /* redirect_navigation*/,
true /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(true /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
1 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LPRAllowed_CoinFlipEnabled_Allowed)) {
RunTest(true /* coin_flip_holdback_enabled */, false /* redirect_navigation*/,
true /* allow_lite_page_redirect*/, false /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(true /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
1 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(RLHAllowed_CoinFlipEnabled_Allowed)) {
RunTest(true /* coin_flip_holdback_enabled */, false /* redirect_navigation*/,
false /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
true /* want_resource_loading_committed */,
1 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
NoPreviews_WithRedirect_CoinFlipEnabled_Allowed)) {
// Set ECT so that we are sure to not trigger any preview.
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_4G);
RunTest(true /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
false /* allow_lite_page_redirect*/,
false /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
false /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
BothPreviewsAllowedWantLPR_WithRedirect_CoinFlipEnabled_Allowed)) {
RunTest(true /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
true /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(true /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
1 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
LPRAllowed_WithRedirect_CoinFlipEnabled_Allowed)) {
RunTest(true /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
true /* allow_lite_page_redirect*/,
false /* allow_resource_loading */,
false /* set_random_navigation_coin_flip*/);
ValidateResult(true /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
1 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
RLHAllowed_WithRedirect_CoinFlipEnabled_Allowed)) {
RunTest(true /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
false /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
false /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
true /* want_resource_loading_committed */,
1 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(NoPreviews_CoinFlipEnabled_Holdback)) {
// Set ECT so that we are sure to not trigger any preview.
g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_4G);
RunTest(true /* coin_flip_holdback_enabled */, false /* redirect_navigation*/,
false /* allow_lite_page_redirect*/,
false /* allow_resource_loading*/,
true /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
0 /* want_ukm_coin_flip_holdback_result */,
false /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
BothPreviewsAllowedWantLPR_CoinFlipEnabled_Holdback)) {
RunTest(true /* coin_flip_holdback_enabled */, false /* redirect_navigation*/,
true /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
true /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
2 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(LPRAllowed_CoinFlipEnabled_Holdback)) {
RunTest(true /* coin_flip_holdback_enabled */, false /* redirect_navigation*/,
true /* allow_lite_page_redirect*/, false /* allow_resource_loading*/,
true /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
2 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(RLHAllowed_CoinFlipEnabled_Holdback)) {
RunTest(true /* coin_flip_holdback_enabled */, false /* redirect_navigation*/,
false /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
true /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
2 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(
CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
BothPreviewsAllowedWantLPR_WithRedirect_CoinFlipEnabled_Holdback)) {
RunTest(true /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
true /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
true /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
2 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
LPRAllowed_WithRedirect_CoinFlipEnabled_Holdback)) {
RunTest(true /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
true /* allow_lite_page_redirect*/,
false /* allow_resource_loading */,
true /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
2 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}
IN_PROC_BROWSER_TEST_P(CoinFlipHoldbackExperimentBrowserTest,
DISABLE_ON_WIN_MAC_CHROMESOS(
RLHAllowed_WithRedirect_CoinFlipEnabled_Holdback)) {
RunTest(true /* coin_flip_holdback_enabled */, true /* redirect_navigation*/,
false /* allow_lite_page_redirect*/, true /* allow_resource_loading*/,
true /* set_random_navigation_coin_flip*/);
ValidateResult(false /* want_lite_page_redirect_committed */,
false /* want_resource_loading_committed */,
2 /* want_ukm_coin_flip_holdback_result */,
true /* want_ukm_previews_likely */);
}