| // 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 "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/scoped_task_environment.h" |
| #include "base/test/simple_test_tick_clock.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_decider.h" |
| #include "chrome/browser/previews/previews_lite_page_navigation_throttle.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_pingback_client.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/hints_component_info.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_hints.h" |
| #include "components/previews/content/previews_optimization_guide.h" |
| #include "components/previews/content/previews_ui_service.h" |
| #include "components/previews/content/previews_user_data.h" |
| #include "components/previews/core/bloom_filter.h" |
| #include "components/previews/core/previews_constants.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/http/http_request_headers.h" |
| #include "net/http/http_status_code.h" |
| #include "net/nqe/effective_connection_type.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"; |
| } // namespace |
| |
| class PreviewsLitePageServerBrowserTest |
| : public InProcessBrowserTest, |
| public testing::WithParamInterface<bool> { |
| public: |
| PreviewsLitePageServerBrowserTest() {} |
| |
| ~PreviewsLitePageServerBrowserTest() override {} |
| |
| 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, |
| }; |
| |
| 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("enable-data-reduction-proxy-force-pingback"); |
| 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( |
| &PreviewsLitePageServerBrowserTest::HandleRedirectRequest, |
| 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( |
| &PreviewsLitePageServerBrowserTest::HandleRedirectRequest, |
| 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( |
| &PreviewsLitePageServerBrowserTest::HandleResourceRequest, |
| base::Unretained(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( |
| &PreviewsLitePageServerBrowserTest::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)); |
| |
| pingback_server_ = std::make_unique<net::EmbeddedTestServer>( |
| net::EmbeddedTestServer::TYPE_HTTPS); |
| |
| pingback_server_->RegisterRequestHandler(base::BindRepeating( |
| &PreviewsLitePageServerBrowserTest::HandlePingbackRequest, |
| base::Unretained(this))); |
| ASSERT_TRUE(pingback_server_->Start()); |
| |
| std::map<std::string, std::string> feature_parameters = { |
| {"previews_host", 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"}}; |
| |
| base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| "data-reduction-proxy-pingback-url", |
| pingback_server_->GetURL("pingback.com", "/").spec()); |
| |
| scoped_parameterized_feature_list_.InitAndEnableFeatureWithParameters( |
| previews::features::kLitePageServerPreviews, feature_parameters); |
| |
| scoped_feature_list_.InitWithFeatures( |
| {previews::features::kPreviews, previews::features::kOptimizationHints, |
| previews::features::kResourceLoadingHints, |
| data_reduction_proxy::features:: |
| kDataReductionProxyEnabledWithNetworkService}, |
| {}); |
| |
| if (GetParam()) { |
| url_loader_feature_list_.InitWithFeatures( |
| {previews::features::kHTTPSServerPreviewsUsingURLLoader}, {}); |
| } |
| } |
| |
| 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()); |
| PreviewsLitePageDecider* decider = |
| previews_service->previews_lite_page_decider(); |
| decider->SetUserHasSeenUINotification(); |
| |
| decider->BlacklistBypassedHost(kBlacklistedHost, |
| base::TimeDelta::FromHours(1)); |
| } |
| |
| void InitializeOptimizationHints() { |
| std::unique_ptr<optimization_guide::proto::Configuration> config = |
| std::make_unique<optimization_guide::proto::Configuration>(); |
| std::unique_ptr<previews::PreviewsHints> hints = |
| previews::PreviewsHints::CreateFromHintsConfiguration(std::move(config), |
| nullptr); |
| |
| PreviewsService* previews_service = |
| PreviewsServiceFactory::GetForProfile(browser()->profile()); |
| |
| previews_service->previews_ui_service() |
| ->previews_decider_impl() |
| ->previews_opt_guide() |
| ->UpdateHints(base::DoNothing(), std::move(hints)); |
| } |
| |
| 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 VerifyInfoStatus(base::HistogramTester* histogram_tester, |
| previews::ServerLitePageStatus status) { |
| PreviewsUITabHelper* ui_tab_helper = |
| PreviewsUITabHelper::FromWebContents(GetWebContents()); |
| previews::PreviewsUserData* previews_data = |
| ui_tab_helper->previews_user_data(); |
| if (!GetParam()) { |
| EXPECT_TRUE(previews_data->server_lite_page_info()); |
| EXPECT_EQ(previews_data->server_lite_page_info()->status, status); |
| } |
| // This UMA is not recorded for an unknown or control group status |
| if (status == previews::ServerLitePageStatus::kUnknown || |
| status == previews::ServerLitePageStatus::kControl) { |
| return; |
| } |
| |
| if (!GetParam()) { |
| histogram_tester->ExpectTotalCount( |
| "Previews.ServerLitePage.Penalty." + |
| previews::ServerLitePageStatusToString(status), |
| 1); |
| } |
| } |
| |
| 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->committed_previews_type(), |
| 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(); |
| |
| if (!GetParam()) { |
| // server_lite_page_info does not exist on forward/back navigations. |
| if (!(entry->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK)) { |
| EXPECT_TRUE(previews_data->server_lite_page_info()); |
| EXPECT_NE( |
| previews_data->server_lite_page_info()->original_navigation_start, |
| base::TimeTicks()); |
| EXPECT_NE(previews_data->server_lite_page_info()->page_id, 0U); |
| EXPECT_NE(previews_data->server_lite_page_info()->drp_session_key, ""); |
| } |
| } |
| |
| 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, |
| PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL( |
| 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->committed_previews_type(), |
| 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(); |
| } |
| |
| // 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); |
| PreviewsLitePageDecider* decider = |
| previews_service->previews_lite_page_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_; } |
| uint64_t got_page_id() const { return got_page_id_; } |
| int subresources_requested() const { return subresources_requested_; } |
| |
| void WaitForPingback() { |
| base::RunLoop run_loop; |
| waiting_for_pingback_closure_ = run_loop.QuitClosure(); |
| run_loop.Run(); |
| } |
| |
| private: |
| std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| const net::test_server::HttpRequest& request) { |
| 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> HandlePingbackRequest( |
| const net::test_server::HttpRequest& request) { |
| std::unique_ptr<net::test_server::BasicHttpResponse> response = |
| std::make_unique<net::test_server::BasicHttpResponse>(); |
| response->set_code(net::HTTP_OK); |
| |
| if (!waiting_for_pingback_closure_.is_null()) { |
| std::move(waiting_for_pingback_closure_).Run(); |
| } |
| |
| return 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; |
| } |
| |
| 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"); |
| 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); |
| } |
| |
| base::test::ScopedFeatureList scoped_parameterized_feature_list_; |
| base::test::ScopedFeatureList scoped_feature_list_; |
| base::test::ScopedFeatureList url_loader_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_; |
| std::unique_ptr<net::EmbeddedTestServer> pingback_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_; |
| uint64_t got_page_id_ = 0; |
| int subresources_requested_ = 0; |
| base::OnceClosure waiting_for_pingback_closure_; |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| PreviewsLitePageServerBrowserTest, |
| 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( |
| PreviewsLitePageServerBrowserTest, |
| 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(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kSuccess); |
| } |
| |
| { |
| // 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(¶ms); |
| 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(), PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL( |
| 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", |
| PreviewsLitePageNavigationThrottle::BlacklistReason:: |
| 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", |
| PreviewsLitePageNavigationThrottle::BlacklistReason:: |
| 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(); |
| |
| // 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", |
| PreviewsLitePageNavigationThrottle::IneligibleReason::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(); |
| |
| if (!GetParam()) { |
| // It takes a few redirects to reach the end case. Just make sure at least |
| // one sample has been recorded in the correct bucket. |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.IneligibleReasons", |
| static_cast<int>( |
| PreviewsLitePageNavigationThrottle::IneligibleReason:: |
| kExceededMaxNavigationRestarts), |
| 1); |
| } |
| } |
| |
| { |
| // 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)); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P( |
| PreviewsLitePageServerBrowserTest, |
| 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( |
| PreviewsLitePageServerBrowserTest, |
| 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( |
| PreviewsLitePageServerBrowserTest, |
| DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsLoadOriginal)) { |
| base::HistogramTester histogram_tester; |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); |
| VerifyPreviewLoaded(); |
| VerifyInfoStatus(&histogram_tester, previews::ServerLitePageStatus::kSuccess); |
| |
| 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(PreviewsLitePageServerBrowserTest, |
| 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(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kSuccess); |
| } |
| |
| { |
| // 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(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kSuccess); |
| } |
| |
| { |
| // 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(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kRedirect); |
| ClearDeciderState(); |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.ServerResponse", |
| PreviewsLitePageNavigationThrottle::ServerResponse::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(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kSuccess); |
| ClearDeciderState(); |
| |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.ServerResponse", |
| PreviewsLitePageNavigationThrottle::ServerResponse::kRedirect, 1); |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.ServerResponse", |
| PreviewsLitePageNavigationThrottle::ServerResponse::kOk, 1); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest, |
| 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(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kBypass); |
| ClearDeciderState(); |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.ServerResponse", |
| PreviewsLitePageNavigationThrottle::ServerResponse:: |
| 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(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kBypass); |
| |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.ServerResponse", |
| PreviewsLitePageNavigationThrottle::ServerResponse:: |
| kPreviewUnavailable, |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.HostBlacklistedOnBypass", true, 1); |
| |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); |
| VerifyPreviewNotLoaded(); |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.BlacklistReasons", |
| PreviewsLitePageNavigationThrottle::BlacklistReason:: |
| kHostBypassBlacklisted, |
| 1); |
| ClearDeciderState(); |
| |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); |
| VerifyPreviewLoaded(); |
| } |
| |
| { |
| // Verify the preview is not triggered when the server responds with 403. |
| base::HistogramTester histogram_tester; |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kAuthFailure)); |
| VerifyPreviewNotLoaded(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kFailure); |
| ClearDeciderState(); |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.ServerResponse", |
| PreviewsLitePageNavigationThrottle::ServerResponse::kAuthFailure, 1); |
| } |
| |
| { |
| // Verify the preview is not triggered when the server responds with 503. |
| base::HistogramTester histogram_tester; |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kLoadshed)); |
| VerifyPreviewNotLoaded(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kFailure); |
| ClearDeciderState(); |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.ServerResponse", |
| PreviewsLitePageNavigationThrottle::ServerResponse:: |
| kServiceUnavailable, |
| 1); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest, |
| DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsLoadshed)) { |
| PreviewsService* previews_service = |
| PreviewsServiceFactory::GetForProfile(browser()->profile()); |
| ASSERT_TRUE(previews_service); |
| PreviewsLitePageDecider* decider = |
| previews_service->previews_lite_page_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( |
| PreviewsLitePageServerBrowserTest, |
| 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([&](bool success, const history::URLRow& row, |
| const history::VisitVector&) { |
| EXPECT_TRUE(success); |
| loop.Quit(); |
| }), |
| &tracker_); |
| loop.Run(); |
| } |
| { |
| base::RunLoop loop; |
| history_service->QueryURL( |
| PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL( |
| HttpsLitePageURL(kSuccess)), |
| false /* want_visits */, |
| base::BindLambdaForTesting([&](bool success, const history::URLRow& row, |
| const history::VisitVector&) { |
| EXPECT_FALSE(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([&](const 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( |
| PreviewsLitePageServerBrowserTest, |
| 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( |
| PreviewsLitePageServerBrowserTest, |
| 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( |
| PreviewsLitePageServerBrowserTest, |
| 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(); |
| if (GetParam()) { |
| VerifyPreviewNotLoaded(); |
| } else { |
| VerifyPreviewLoaded(); |
| } |
| } |
| |
| { |
| SCOPED_TRACE("Navigate forward"); |
| GetWebContents()->GetController().GoForward(); |
| VerifyPreviewNotLoaded(); |
| ClearDeciderState(); |
| } |
| |
| { |
| SCOPED_TRACE("Navigate back again"); |
| GetWebContents()->GetController().GoBack(); |
| VerifyPreviewLoaded(); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest, |
| DISABLE_ON_WIN_MAC_CHROMESOS(LitePageCreatesPingback)) { |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); |
| VerifyPreviewLoaded(); |
| |
| // Starting a new page load will send a pingback for the previous page load. |
| GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, false); |
| WaitForPingback(); |
| } |
| |
| class TestDataReductionProxyPingbackClient |
| : public data_reduction_proxy::DataReductionProxyPingbackClient { |
| public: |
| void WaitForPingback() { |
| base::RunLoop run_loop; |
| wait_for_pingback_closure_ = run_loop.QuitClosure(); |
| run_loop.Run(); |
| } |
| |
| data_reduction_proxy::DataReductionProxyData* data() { return data_.get(); } |
| |
| private: |
| void SendPingback( |
| const data_reduction_proxy::DataReductionProxyData& data, |
| const data_reduction_proxy::DataReductionProxyPageLoadTiming& timing) |
| override { |
| data_ = data.DeepCopy(); |
| if (wait_for_pingback_closure_) |
| std::move(wait_for_pingback_closure_).Run(); |
| } |
| |
| void SetPingbackReportingFraction( |
| float pingback_reporting_fraction) override {} |
| |
| base::OnceClosure wait_for_pingback_closure_; |
| std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest, |
| DISABLE_ON_WIN_MAC_CHROMESOS(PingbackContent)) { |
| TestDataReductionProxyPingbackClient* pingback_client = |
| new TestDataReductionProxyPingbackClient(); |
| DataReductionProxyChromeSettingsFactory::GetForBrowserContext( |
| browser()->profile()) |
| ->data_reduction_proxy_service() |
| ->SetPingbackClientForTesting(pingback_client); |
| |
| // This test should pass whether or not |
| // |kDataReductionProxyPopulatePreviewsPageIDToPingback| is enabled. |
| for (const bool drp_pageid_feature_enabled : {false, true}) { |
| base::test::ScopedFeatureList scoped_feature_list; |
| scoped_feature_list.InitWithFeatureState( |
| data_reduction_proxy::features:: |
| kDataReductionProxyPopulatePreviewsPageIDToPingback, |
| drp_pageid_feature_enabled); |
| |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); |
| VerifyPreviewLoaded(); |
| |
| PreviewsUITabHelper* ui_tab_helper = |
| PreviewsUITabHelper::FromWebContents(GetWebContents()); |
| previews::PreviewsUserData* previews_data = |
| ui_tab_helper->previews_user_data(); |
| // Grab the page id and session now because they may change after the |
| // reload. |
| uint64_t expected_page_id = previews_data->server_lite_page_info()->page_id; |
| std::string expected_session_key = |
| previews_data->server_lite_page_info()->drp_session_key; |
| |
| // Starting a new page load will send a pingback for the previous page load. |
| GetWebContents()->GetController().Reload(content::ReloadType::NORMAL, |
| false); |
| pingback_client->WaitForPingback(); |
| |
| data_reduction_proxy::DataReductionProxyData* data = |
| pingback_client->data(); |
| EXPECT_TRUE(data->used_data_reduction_proxy()); |
| EXPECT_TRUE(data->lite_page_received()); |
| EXPECT_FALSE(data->lofi_policy_received()); |
| EXPECT_FALSE(data->lofi_received()); |
| EXPECT_FALSE(data->was_cached_data_reduction_proxy_response()); |
| EXPECT_EQ(data->page_id().value(), expected_page_id); |
| EXPECT_EQ(data->page_id().value(), got_page_id()); |
| EXPECT_EQ(data->session_key(), expected_session_key); |
| } |
| } |
| |
| class PreviewsLitePageServerTimeoutBrowserTest |
| : public PreviewsLitePageServerBrowserTest { |
| public: |
| PreviewsLitePageServerTimeoutBrowserTest() = default; |
| |
| ~PreviewsLitePageServerTimeoutBrowserTest() override = default; |
| |
| void SetUp() override { |
| SetUpLitePageTest(true /* use_timeout */, false /* is_control */); |
| |
| InProcessBrowserTest::SetUp(); |
| } |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| PreviewsLitePageServerTimeoutBrowserTest, |
| testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerTimeoutBrowserTest, |
| 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(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kFailure); |
| ClearDeciderState(); |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.ServerResponse", |
| PreviewsLitePageNavigationThrottle::ServerResponse::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); |
| } |
| } |
| |
| class PreviewsLitePageServerBadServerBrowserTest |
| : public PreviewsLitePageServerBrowserTest { |
| public: |
| PreviewsLitePageServerBadServerBrowserTest() = default; |
| |
| ~PreviewsLitePageServerBadServerBrowserTest() 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"); |
| } |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| PreviewsLitePageServerBadServerBrowserTest, |
| testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P( |
| PreviewsLitePageServerBadServerBrowserTest, |
| 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. |
| base::HistogramTester histogram_tester; |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); |
| VerifyPreviewNotLoaded(); |
| VerifyInfoStatus(&histogram_tester, |
| previews::ServerLitePageStatus::kFailure); |
| ClearDeciderState(); |
| histogram_tester.ExpectBucketCount( |
| "Previews.ServerLitePage.ServerResponse", |
| PreviewsLitePageNavigationThrottle::ServerResponse::kFailed, 1); |
| } |
| } |
| |
| class PreviewsLitePageServerDataSaverBrowserTest |
| : public PreviewsLitePageServerBrowserTest { |
| public: |
| PreviewsLitePageServerDataSaverBrowserTest() = default; |
| |
| ~PreviewsLitePageServerDataSaverBrowserTest() override = default; |
| |
| // Overrides the cmd line in PreviewsLitePageServerBrowserTest 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"); |
| } |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| PreviewsLitePageServerDataSaverBrowserTest, |
| testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P( |
| PreviewsLitePageServerDataSaverBrowserTest, |
| 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 PreviewsLitePageServerNoDataSaverHeaderBrowserTest |
| : public PreviewsLitePageServerBrowserTest { |
| public: |
| PreviewsLitePageServerNoDataSaverHeaderBrowserTest() = default; |
| |
| ~PreviewsLitePageServerNoDataSaverHeaderBrowserTest() override = default; |
| |
| // Overrides the command line in PreviewsLitePageServerBrowserTest 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"); |
| } |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| PreviewsLitePageServerNoDataSaverHeaderBrowserTest, |
| testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P( |
| PreviewsLitePageServerNoDataSaverHeaderBrowserTest, |
| 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 PreviewsLitePageNotificationDSEnabledBrowserTest |
| : public PreviewsLitePageServerBrowserTest { |
| public: |
| PreviewsLitePageNotificationDSEnabledBrowserTest() = default; |
| |
| ~PreviewsLitePageNotificationDSEnabledBrowserTest() 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); |
| } |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| PreviewsLitePageNotificationDSEnabledBrowserTest, |
| testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P( |
| PreviewsLitePageNotificationDSEnabledBrowserTest, |
| 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", |
| PreviewsLitePageNavigationThrottle::IneligibleReason::kInfoBarNotSeen, 1); |
| } |
| |
| class PreviewsLitePageNotificationDSDisabledBrowserTest |
| : public PreviewsLitePageServerBrowserTest { |
| public: |
| PreviewsLitePageNotificationDSDisabledBrowserTest() = default; |
| |
| ~PreviewsLitePageNotificationDSDisabledBrowserTest() 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 PreviewsLitePageServerBrowserTest 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"); |
| } |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| PreviewsLitePageNotificationDSDisabledBrowserTest, |
| testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P( |
| PreviewsLitePageNotificationDSDisabledBrowserTest, |
| DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsInfoBarNonDataSaverUser)) { |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); |
| VerifyPreviewNotLoaded(); |
| ClearDeciderState(); |
| EXPECT_EQ(0U, GetInfoBarService()->infobar_count()); |
| } |
| |
| class PreviewsLitePageControlBrowserTest |
| : public PreviewsLitePageServerBrowserTest { |
| public: |
| PreviewsLitePageControlBrowserTest() = default; |
| |
| ~PreviewsLitePageControlBrowserTest() override = default; |
| |
| void SetUp() override { |
| SetUpLitePageTest(false /* use_timeout */, true /* is_control */); |
| |
| InProcessBrowserTest::SetUp(); |
| } |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| PreviewsLitePageControlBrowserTest, |
| testing::Bool()); |
| |
| IN_PROC_BROWSER_TEST_P( |
| PreviewsLitePageControlBrowserTest, |
| DISABLE_ON_WIN_MAC_CHROMESOS(LitePagePreviewsControlGroup)) { |
| base::HistogramTester histogram_tester; |
| ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess)); |
| VerifyPreviewNotLoaded(); |
| VerifyInfoStatus(&histogram_tester, previews::ServerLitePageStatus::kControl); |
| ClearDeciderState(); |
| } |
| |
| class PreviewsLitePageAndPageHintsBrowserTest |
| : public PreviewsLitePageServerBrowserTest { |
| public: |
| PreviewsLitePageAndPageHintsBrowserTest() = default; |
| |
| ~PreviewsLitePageAndPageHintsBrowserTest() override = default; |
| |
| void ProcessHintsComponent( |
| const optimization_guide::HintsComponentInfo& component_info) { |
| // Register a QuitClosure for when the next hint update is started below. |
| base::RunLoop run_loop; |
| PreviewsServiceFactory::GetForProfile( |
| Profile::FromBrowserContext(browser() |
| ->tab_strip_model() |
| ->GetActiveWebContents() |
| ->GetBrowserContext())) |
| ->previews_ui_service() |
| ->previews_decider_impl() |
| ->previews_opt_guide() |
| ->ListenForNextUpdateForTesting(run_loop.QuitClosure()); |
| |
| g_browser_process->optimization_guide_service() |
| ->MaybeUpdateHintsComponentOnUIThread(component_info); |
| |
| run_loop.Run(); |
| } |
| |
| 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 { |
| PreviewsLitePageServerBrowserTest::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())); |
| } |
| |
| private: |
| optimization_guide::testing::TestHintsComponentCreator |
| test_hints_component_creator_; |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| PreviewsLitePageAndPageHintsBrowserTest, |
| testing::Bool()); |
| |
| // Regression test for crbug.com/954554. |
| IN_PROC_BROWSER_TEST_P( |
| PreviewsLitePageAndPageHintsBrowserTest, |
| DISABLE_ON_WIN_MAC_CHROMESOS(PreviewsServerIsInBloomFilter)) { |
| previews::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( |
| PreviewsLitePageAndPageHintsBrowserTest, |
| 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->committed_previews_type(), |
| previews::PreviewsType::RESOURCE_LOADING_HINTS); |
| |
| ClearDeciderState(); |
| } |
| |
| class CoinFlipHoldbackExperimentBrowserTest |
| : public PreviewsLitePageAndPageHintsBrowserTest { |
| public: |
| CoinFlipHoldbackExperimentBrowserTest() = default; |
| |
| ~CoinFlipHoldbackExperimentBrowserTest() override = default; |
| |
| void SetUp() override { |
| ukm_feature_list_.InitAndEnableFeature(ukm::kUkmFeature); |
| PreviewsLitePageAndPageHintsBrowserTest::SetUp(); |
| } |
| |
| void SetUpCommandLine(base::CommandLine* cmd) override { |
| PreviewsLitePageAndPageHintsBrowserTest::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->committed_previews_type(), |
| previews::PreviewsType::RESOURCE_LOADING_HINTS); |
| EXPECT_NE(previews_data->coin_flip_holdback_result(), |
| previews::CoinFlipHoldbackResult::kHoldback); |
| } |
| |
| EXPECT_EQ(want_ukm_coin_flip_holdback_result, |
| static_cast<int>(previews_data->coin_flip_holdback_result())); |
| |
| if (want_lite_page_redirect_committed || want_resource_loading_committed) { |
| // 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); |
| ASSERT_EQ(1u, entries.size()); |
| auto* entry = entries.at(0); |
| |
| ukm_recorder_->ExpectEntryMetric(entry, UkmEntry::kcoin_flip_resultName, |
| want_ukm_coin_flip_holdback_result); |
| 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_; |
| }; |
| |
| // True if testing using the URLLoader Interceptor implementation. |
| INSTANTIATE_TEST_SUITE_P(URLLoaderImplementation, |
| CoinFlipHoldbackExperimentBrowserTest, |
| 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 */); |
| } |