blob: acac219c3b46ac3934c90232a9b1c93cd7339813 [file] [log] [blame]
// Copyright 2022 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 <string>
#include "chrome/browser/prerender/prerender_manager.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/prerender/prerender_utils.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/web_contents_tester.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class PrerenderManagerTest : public ChromeRenderViewHostTestHarness {
public:
PrerenderManagerTest(const PrerenderManagerTest&) = delete;
PrerenderManagerTest& operator=(const PrerenderManagerTest&) = delete;
PrerenderManagerTest()
: prerender_helper_(
base::BindRepeating(&PrerenderManagerTest::GetActiveWebContents,
base::Unretained(this))) {
scoped_feature_list_.InitAndEnableFeatureWithParameters(
features::kOmniboxTriggerForPrerender2,
{{"SupportSearchSuggestion", "true"}});
}
void SetUp() override {
prerender_helper_.SetUp(&test_server_);
ASSERT_TRUE(test_server_.Start());
ChromeRenderViewHostTestHarness::SetUp();
PrerenderManager::CreateForWebContents(GetActiveWebContents());
prerender_manager_ = PrerenderManager::FromWebContents(web_contents());
ASSERT_TRUE(prerender_manager_);
prerender_manager_->set_skip_template_url_service_for_testing();
}
content::WebContents* GetActiveWebContents() { return web_contents(); }
GURL GetSearchSuggestionUrl(const std::string& search_site,
const std::string& original_query,
const std::string& search_terms) {
return test_server_.GetURL(search_site + "?q=" + search_terms +
"&oq=" + original_query);
}
content::WebContentsTester* web_contents_tester() {
return content::WebContentsTester::For(web_contents());
}
protected:
AutocompleteMatch CreateSearchSuggestionMatch(
const std::string& search_site,
const std::string& original_query,
const std::string& search_terms) {
AutocompleteMatch match;
match.search_terms_args = std::make_unique<TemplateURLRef::SearchTermsArgs>(
base::UTF8ToUTF16(search_terms));
match.search_terms_args->original_query = base::UTF8ToUTF16(original_query);
match.destination_url =
GetSearchSuggestionUrl(search_site, original_query, search_terms);
match.keyword = base::UTF8ToUTF16(original_query);
match.RecordAdditionalInfo("should_prerender", "true");
return match;
}
GURL GetUrl(const std::string& path) { return test_server_.GetURL(path); }
PrerenderManager* prerender_manager() { return prerender_manager_; }
content::test::PrerenderTestHelper& prerender_helper() {
return prerender_helper_;
}
private:
content::test::PrerenderTestHelper prerender_helper_;
base::test::ScopedFeatureList scoped_feature_list_;
net::EmbeddedTestServer test_server_;
raw_ptr<PrerenderManager> prerender_manager_;
};
TEST_F(PrerenderManagerTest, StartCleanSearchSuggestionPrerender) {
GURL prerendering_url =
GetSearchSuggestionUrl("/title1.html", "pre", "prerender");
content::test::PrerenderHostRegistryObserver registry_observer(
*GetActiveWebContents());
AutocompleteMatch match =
CreateSearchSuggestionMatch("/title1.html", "pre", "prerender");
prerender_manager()->StartPrerenderSearchSuggestion(match);
registry_observer.WaitForTrigger(prerendering_url);
int prerender_host_id = prerender_helper().GetHostForUrl(prerendering_url);
EXPECT_NE(prerender_host_id, content::RenderFrameHost::kNoFrameTreeNodeId);
}
// Tests that the old prerender will be destroyed when starting prerendering a
// different search result.
TEST_F(PrerenderManagerTest, StartNewSuggestionPrerender) {
GURL prerendering_url =
GetSearchSuggestionUrl("/title1.html", "pre", "prefetch");
content::test::PrerenderHostRegistryObserver registry_observer(
*GetActiveWebContents());
AutocompleteMatch match =
CreateSearchSuggestionMatch("/title1.html", "pre", "prefetch");
prerender_manager()->StartPrerenderSearchSuggestion(match);
registry_observer.WaitForTrigger(prerendering_url);
int prerender_host_id = prerender_helper().GetHostForUrl(prerendering_url);
ASSERT_NE(prerender_host_id, content::RenderFrameHost::kNoFrameTreeNodeId);
content::test::PrerenderHostObserver host_observer(*GetActiveWebContents(),
prerender_host_id);
GURL prerendering_url2 =
GetSearchSuggestionUrl("/title1.html", "prer", "prerender");
match = CreateSearchSuggestionMatch("/title1.html", "prer", "prerender");
prerender_manager()->StartPrerenderSearchSuggestion(match);
host_observer.WaitForDestroyed();
registry_observer.WaitForTrigger(prerendering_url2);
EXPECT_TRUE(prerender_manager()->HasSearchResultPagePrerendered());
EXPECT_EQ(std::u16string(u"prerender"),
prerender_manager()->GetPrerenderSearchTermForTesting());
}
// Tests that the old prerender is not destroyed when starting prerendering the
// same search suggestion.
TEST_F(PrerenderManagerTest, StartSameSuggestionPrerender) {
GURL prerendering_url =
GetSearchSuggestionUrl("/title1.html", "pre", "prerender");
content::test::PrerenderHostRegistryObserver registry_observer(
*GetActiveWebContents());
AutocompleteMatch match =
CreateSearchSuggestionMatch("/title1.html", "pre", "prerender");
prerender_manager()->StartPrerenderSearchSuggestion(match);
registry_observer.WaitForTrigger(prerendering_url);
int prerender_host_id = prerender_helper().GetHostForUrl(prerendering_url);
EXPECT_NE(prerender_host_id, content::RenderFrameHost::kNoFrameTreeNodeId);
match = CreateSearchSuggestionMatch("/title1.html", "prer", "prerender");
prerender_manager()->StartPrerenderSearchSuggestion(match);
EXPECT_TRUE(prerender_manager()->HasSearchResultPagePrerendered());
// The created prerender for `prerendering_url` still exists, so the
// prerender_host_id should be the same.
int prerender_host_id2 = prerender_helper().GetHostForUrl(prerendering_url);
EXPECT_EQ(prerender_host_id2, prerender_host_id);
}
// Tests that the PrerenderHandle is destroyed when the primary page changed.
TEST_F(PrerenderManagerTest, DestroyedOnNavigateAway) {
GURL prerendering_url =
GetSearchSuggestionUrl("/title1.html", "pre", "prerende");
content::test::PrerenderHostRegistryObserver registry_observer(
*GetActiveWebContents());
AutocompleteMatch match =
CreateSearchSuggestionMatch("/title1.html", "pre", "prerende");
prerender_manager()->StartPrerenderSearchSuggestion(match);
registry_observer.WaitForTrigger(prerendering_url);
int prerender_host_id = prerender_helper().GetHostForUrl(prerendering_url);
EXPECT_NE(prerender_host_id, content::RenderFrameHost::kNoFrameTreeNodeId);
content::test::PrerenderHostObserver host_observer(*GetActiveWebContents(),
prerender_host_id);
web_contents_tester()->NavigateAndCommit(GetUrl("/empty.html"));
host_observer.WaitForDestroyed();
EXPECT_FALSE(prerender_manager()->HasSearchResultPagePrerendered());
}
} // namespace