prerender: Add a same-site cross-origin speculation tags test
This CL adds a test verifying speculation rules tags header field is sent in same-site cross-origin situation. See the section in the related spec: https://github.com/WICG/nav-speculation/blob/main/speculation-rules-tags.md#the-cross-site-case Bug: 381687257 Change-Id: I4aa56054934c7a132dcee460fe099e804b4833c4 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6433267 Commit-Queue: Huanpo Lin <robertlin@chromium.org> Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org> Reviewed-by: Domenic Denicola <domenic@chromium.org> Cr-Commit-Position: refs/heads/main@{#1444507}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
254252eb57
commit
3c0b3f803d
content
browser
preloading
prerender
public
@ -428,12 +428,20 @@ class PrerenderBrowserTest : public ContentBrowserTest,
|
||||
return prerender_helper_->AddPrerender(prerendering_url, world_id);
|
||||
}
|
||||
|
||||
FrameTreeNodeId AddPrerenderWithTags(const GURL& prerendering_url,
|
||||
std::optional<std::string> tag) {
|
||||
return prerender_helper_->AddPrerender(
|
||||
prerendering_url, /*eagerness=*/std::nullopt,
|
||||
/*no_vary_search_hint=*/std::string(),
|
||||
/*target_hint=*/std::string(), tag);
|
||||
}
|
||||
|
||||
FrameTreeNodeId AddPrerender(const GURL& prerendering_url,
|
||||
std::string no_vary_search_hint,
|
||||
int32_t world_id = ISOLATED_WORLD_ID_GLOBAL) {
|
||||
return prerender_helper_->AddPrerender(
|
||||
prerendering_url, /*eagerness=*/std::nullopt, no_vary_search_hint,
|
||||
/*target_hint=*/std::string(), world_id);
|
||||
/*target_hint=*/std::string(), /*ruleset_tag=*/std::nullopt, world_id);
|
||||
}
|
||||
|
||||
void AddPrerenderAsync(const GURL& prerendering_url) {
|
||||
@ -12775,6 +12783,26 @@ IN_PROC_BROWSER_TEST_P(PrerenderRequestHeadersBrowserTest,
|
||||
}
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_P(PrerenderRequestHeadersBrowserTest,
|
||||
SpeculationRulesTagForSameSiteCrossOrigin) {
|
||||
const GURL initial_url = GetUrl("/prerender/empty.html");
|
||||
const GURL prerender_url =
|
||||
GetSameSiteCrossOriginUrl("/prerender/prerender_with_opt_in_header.html");
|
||||
|
||||
// Navigate to an initial page.
|
||||
ASSERT_TRUE(NavigateToURL(shell(), initial_url));
|
||||
FrameTreeNodeId host_id = AddPrerenderWithTags(prerender_url, "tag1");
|
||||
auto* prerendered_rfh = GetPrerenderedMainFrameHost(host_id);
|
||||
EXPECT_TRUE(prerendered_rfh != nullptr);
|
||||
|
||||
if (IsSpeculationRulesTagsEnabled()) {
|
||||
EXPECT_TRUE(HasSecSpeculationTagsHeader(prerender_url));
|
||||
EXPECT_EQ(GetSecSpeculationTagsHeader(prerender_url), "\"tag1\"");
|
||||
} else {
|
||||
EXPECT_FALSE(HasSecSpeculationTagsHeader(prerender_url));
|
||||
}
|
||||
}
|
||||
|
||||
// This prefetch test is tentatively implemented here to reuse the test infra.
|
||||
// TODO(crbug.com/381687257): Move this test to prefetch browser tests.
|
||||
IN_PROC_BROWSER_TEST_P(PrerenderRequestHeadersBrowserTest, Prefetch) {
|
||||
|
@ -40,6 +40,16 @@ constexpr char kAddSpeculationRuleScript[] = R"({
|
||||
document.head.appendChild(script);
|
||||
})";
|
||||
|
||||
constexpr char kAddSpeculationRuleWithRulesetTagScript[] = R"({
|
||||
const script = document.createElement('script');
|
||||
script.type = 'speculationrules';
|
||||
script.text = `{
|
||||
"tag": "$1",
|
||||
"prerender": [{ $2 }]
|
||||
}`;
|
||||
document.head.appendChild(script);
|
||||
})";
|
||||
|
||||
std::string ConvertEagernessToString(
|
||||
blink::mojom::SpeculationEagerness eagerness) {
|
||||
switch (eagerness) {
|
||||
@ -57,7 +67,8 @@ std::string BuildScriptElementSpeculationRules(
|
||||
const std::vector<GURL>& prerendering_urls,
|
||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||
std::optional<std::string> no_vary_search_hint,
|
||||
const std::string& target_hint) {
|
||||
const std::string& target_hint,
|
||||
std::optional<std::string> ruleset_tag) {
|
||||
std::stringstream ss;
|
||||
|
||||
// Add source filed.
|
||||
@ -92,8 +103,12 @@ std::string BuildScriptElementSpeculationRules(
|
||||
ss << base::StringPrintf(R"(, "target_hint": "%s")", target_hint.c_str());
|
||||
}
|
||||
|
||||
return base::ReplaceStringPlaceholders(kAddSpeculationRuleScript, {ss.str()},
|
||||
nullptr);
|
||||
return ruleset_tag.has_value()
|
||||
? base::ReplaceStringPlaceholders(
|
||||
kAddSpeculationRuleWithRulesetTagScript,
|
||||
{ruleset_tag.value(), ss.str()}, nullptr)
|
||||
: base::ReplaceStringPlaceholders(kAddSpeculationRuleScript,
|
||||
{ss.str()}, nullptr);
|
||||
}
|
||||
|
||||
constexpr char kAddSpeculationRulePrefetchScript[] = R"({
|
||||
@ -549,7 +564,7 @@ FrameTreeNodeId PrerenderTestHelper::AddPrerender(
|
||||
int32_t world_id) {
|
||||
return AddPrerender(prerendering_url, eagerness,
|
||||
/*no_vary_search_hint=*/std::nullopt, target_hint,
|
||||
world_id);
|
||||
/*ruleset_tag=*/std::nullopt, world_id);
|
||||
}
|
||||
|
||||
FrameTreeNodeId PrerenderTestHelper::AddPrerender(
|
||||
@ -557,6 +572,7 @@ FrameTreeNodeId PrerenderTestHelper::AddPrerender(
|
||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||
std::optional<std::string> no_vary_search_hint,
|
||||
const std::string& target_hint,
|
||||
std::optional<std::string> ruleset_tag,
|
||||
int32_t world_id) {
|
||||
TRACE_EVENT("test", "PrerenderTestHelper::AddPrerender", "prerendering_url",
|
||||
prerendering_url);
|
||||
@ -573,14 +589,14 @@ FrameTreeNodeId PrerenderTestHelper::AddPrerender(
|
||||
run_loop.QuitClosure().Run();
|
||||
}));
|
||||
AddPrerendersAsync({prerendering_url}, eagerness, no_vary_search_hint,
|
||||
target_hint, world_id);
|
||||
target_hint, ruleset_tag, world_id);
|
||||
run_loop.Run();
|
||||
} else {
|
||||
// For other target hints, the initiator's WebContents will host a
|
||||
// prerendered page.
|
||||
prerender_web_contents = GetWebContents();
|
||||
AddPrerendersAsync({prerendering_url}, eagerness, no_vary_search_hint,
|
||||
target_hint, world_id);
|
||||
target_hint, ruleset_tag, world_id);
|
||||
}
|
||||
|
||||
WaitForPrerenderLoadCompletion(*prerender_web_contents, prerendering_url);
|
||||
@ -602,7 +618,7 @@ void PrerenderTestHelper::AddPrerendersAsync(
|
||||
int32_t world_id) {
|
||||
AddPrerendersAsync(prerendering_urls, eagerness,
|
||||
/*no_vary_search_hint=*/std::nullopt, target_hint,
|
||||
world_id);
|
||||
/*ruleset_tag=*/std::nullopt, world_id);
|
||||
}
|
||||
|
||||
void PrerenderTestHelper::AddPrerendersAsync(
|
||||
@ -610,6 +626,7 @@ void PrerenderTestHelper::AddPrerendersAsync(
|
||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||
std::optional<std::string> no_vary_search_hint,
|
||||
const std::string& target_hint,
|
||||
std::optional<std::string> ruleset_tag,
|
||||
int32_t world_id) {
|
||||
TRACE_EVENT(
|
||||
"test", "PrerenderTestHelper::AddPrerendersAsync", "prerendering_urls",
|
||||
@ -621,7 +638,8 @@ void PrerenderTestHelper::AddPrerendersAsync(
|
||||
"target_hint", target_hint.empty() ? "(empty)" : target_hint);
|
||||
EXPECT_TRUE(content::BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
std::string script = BuildScriptElementSpeculationRules(
|
||||
prerendering_urls, eagerness, no_vary_search_hint, target_hint);
|
||||
prerendering_urls, eagerness, no_vary_search_hint, target_hint,
|
||||
ruleset_tag);
|
||||
|
||||
if (world_id == ISOLATED_WORLD_ID_GLOBAL) {
|
||||
// Have to use ExecuteJavaScriptForTests instead of ExecJs/EvalJs here,
|
||||
|
@ -186,6 +186,7 @@ class PrerenderTestHelper {
|
||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||
std::optional<std::string> no_vary_search_hint,
|
||||
const std::string& target_hint,
|
||||
std::optional<std::string> ruleset_tag = std::nullopt,
|
||||
int32_t world_id = ISOLATED_WORLD_ID_GLOBAL);
|
||||
// AddPrerenderAsync() is the same as AddPrerender(), but does not wait until
|
||||
// the completion of prerendering.
|
||||
@ -201,6 +202,7 @@ class PrerenderTestHelper {
|
||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||
std::optional<std::string> no_vary_search_hint,
|
||||
const std::string& target_hint,
|
||||
std::optional<std::string> ruleset_tag = std::nullopt,
|
||||
int32_t world_id = ISOLATED_WORLD_ID_GLOBAL);
|
||||
|
||||
void AddPrefetchAsync(const GURL& prefetch_url);
|
||||
|
Reference in New Issue
Block a user