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);
|
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,
|
FrameTreeNodeId AddPrerender(const GURL& prerendering_url,
|
||||||
std::string no_vary_search_hint,
|
std::string no_vary_search_hint,
|
||||||
int32_t world_id = ISOLATED_WORLD_ID_GLOBAL) {
|
int32_t world_id = ISOLATED_WORLD_ID_GLOBAL) {
|
||||||
return prerender_helper_->AddPrerender(
|
return prerender_helper_->AddPrerender(
|
||||||
prerendering_url, /*eagerness=*/std::nullopt, no_vary_search_hint,
|
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) {
|
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.
|
// This prefetch test is tentatively implemented here to reuse the test infra.
|
||||||
// TODO(crbug.com/381687257): Move this test to prefetch browser tests.
|
// TODO(crbug.com/381687257): Move this test to prefetch browser tests.
|
||||||
IN_PROC_BROWSER_TEST_P(PrerenderRequestHeadersBrowserTest, Prefetch) {
|
IN_PROC_BROWSER_TEST_P(PrerenderRequestHeadersBrowserTest, Prefetch) {
|
||||||
|
@ -40,6 +40,16 @@ constexpr char kAddSpeculationRuleScript[] = R"({
|
|||||||
document.head.appendChild(script);
|
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(
|
std::string ConvertEagernessToString(
|
||||||
blink::mojom::SpeculationEagerness eagerness) {
|
blink::mojom::SpeculationEagerness eagerness) {
|
||||||
switch (eagerness) {
|
switch (eagerness) {
|
||||||
@ -57,7 +67,8 @@ std::string BuildScriptElementSpeculationRules(
|
|||||||
const std::vector<GURL>& prerendering_urls,
|
const std::vector<GURL>& prerendering_urls,
|
||||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||||
std::optional<std::string> no_vary_search_hint,
|
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;
|
std::stringstream ss;
|
||||||
|
|
||||||
// Add source filed.
|
// Add source filed.
|
||||||
@ -92,8 +103,12 @@ std::string BuildScriptElementSpeculationRules(
|
|||||||
ss << base::StringPrintf(R"(, "target_hint": "%s")", target_hint.c_str());
|
ss << base::StringPrintf(R"(, "target_hint": "%s")", target_hint.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return base::ReplaceStringPlaceholders(kAddSpeculationRuleScript, {ss.str()},
|
return ruleset_tag.has_value()
|
||||||
nullptr);
|
? base::ReplaceStringPlaceholders(
|
||||||
|
kAddSpeculationRuleWithRulesetTagScript,
|
||||||
|
{ruleset_tag.value(), ss.str()}, nullptr)
|
||||||
|
: base::ReplaceStringPlaceholders(kAddSpeculationRuleScript,
|
||||||
|
{ss.str()}, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr char kAddSpeculationRulePrefetchScript[] = R"({
|
constexpr char kAddSpeculationRulePrefetchScript[] = R"({
|
||||||
@ -549,7 +564,7 @@ FrameTreeNodeId PrerenderTestHelper::AddPrerender(
|
|||||||
int32_t world_id) {
|
int32_t world_id) {
|
||||||
return AddPrerender(prerendering_url, eagerness,
|
return AddPrerender(prerendering_url, eagerness,
|
||||||
/*no_vary_search_hint=*/std::nullopt, target_hint,
|
/*no_vary_search_hint=*/std::nullopt, target_hint,
|
||||||
world_id);
|
/*ruleset_tag=*/std::nullopt, world_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameTreeNodeId PrerenderTestHelper::AddPrerender(
|
FrameTreeNodeId PrerenderTestHelper::AddPrerender(
|
||||||
@ -557,6 +572,7 @@ FrameTreeNodeId PrerenderTestHelper::AddPrerender(
|
|||||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||||
std::optional<std::string> no_vary_search_hint,
|
std::optional<std::string> no_vary_search_hint,
|
||||||
const std::string& target_hint,
|
const std::string& target_hint,
|
||||||
|
std::optional<std::string> ruleset_tag,
|
||||||
int32_t world_id) {
|
int32_t world_id) {
|
||||||
TRACE_EVENT("test", "PrerenderTestHelper::AddPrerender", "prerendering_url",
|
TRACE_EVENT("test", "PrerenderTestHelper::AddPrerender", "prerendering_url",
|
||||||
prerendering_url);
|
prerendering_url);
|
||||||
@ -573,14 +589,14 @@ FrameTreeNodeId PrerenderTestHelper::AddPrerender(
|
|||||||
run_loop.QuitClosure().Run();
|
run_loop.QuitClosure().Run();
|
||||||
}));
|
}));
|
||||||
AddPrerendersAsync({prerendering_url}, eagerness, no_vary_search_hint,
|
AddPrerendersAsync({prerendering_url}, eagerness, no_vary_search_hint,
|
||||||
target_hint, world_id);
|
target_hint, ruleset_tag, world_id);
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
} else {
|
} else {
|
||||||
// For other target hints, the initiator's WebContents will host a
|
// For other target hints, the initiator's WebContents will host a
|
||||||
// prerendered page.
|
// prerendered page.
|
||||||
prerender_web_contents = GetWebContents();
|
prerender_web_contents = GetWebContents();
|
||||||
AddPrerendersAsync({prerendering_url}, eagerness, no_vary_search_hint,
|
AddPrerendersAsync({prerendering_url}, eagerness, no_vary_search_hint,
|
||||||
target_hint, world_id);
|
target_hint, ruleset_tag, world_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitForPrerenderLoadCompletion(*prerender_web_contents, prerendering_url);
|
WaitForPrerenderLoadCompletion(*prerender_web_contents, prerendering_url);
|
||||||
@ -602,7 +618,7 @@ void PrerenderTestHelper::AddPrerendersAsync(
|
|||||||
int32_t world_id) {
|
int32_t world_id) {
|
||||||
AddPrerendersAsync(prerendering_urls, eagerness,
|
AddPrerendersAsync(prerendering_urls, eagerness,
|
||||||
/*no_vary_search_hint=*/std::nullopt, target_hint,
|
/*no_vary_search_hint=*/std::nullopt, target_hint,
|
||||||
world_id);
|
/*ruleset_tag=*/std::nullopt, world_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrerenderTestHelper::AddPrerendersAsync(
|
void PrerenderTestHelper::AddPrerendersAsync(
|
||||||
@ -610,6 +626,7 @@ void PrerenderTestHelper::AddPrerendersAsync(
|
|||||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||||
std::optional<std::string> no_vary_search_hint,
|
std::optional<std::string> no_vary_search_hint,
|
||||||
const std::string& target_hint,
|
const std::string& target_hint,
|
||||||
|
std::optional<std::string> ruleset_tag,
|
||||||
int32_t world_id) {
|
int32_t world_id) {
|
||||||
TRACE_EVENT(
|
TRACE_EVENT(
|
||||||
"test", "PrerenderTestHelper::AddPrerendersAsync", "prerendering_urls",
|
"test", "PrerenderTestHelper::AddPrerendersAsync", "prerendering_urls",
|
||||||
@ -621,7 +638,8 @@ void PrerenderTestHelper::AddPrerendersAsync(
|
|||||||
"target_hint", target_hint.empty() ? "(empty)" : target_hint);
|
"target_hint", target_hint.empty() ? "(empty)" : target_hint);
|
||||||
EXPECT_TRUE(content::BrowserThread::CurrentlyOn(BrowserThread::UI));
|
EXPECT_TRUE(content::BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||||
std::string script = BuildScriptElementSpeculationRules(
|
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) {
|
if (world_id == ISOLATED_WORLD_ID_GLOBAL) {
|
||||||
// Have to use ExecuteJavaScriptForTests instead of ExecJs/EvalJs here,
|
// Have to use ExecuteJavaScriptForTests instead of ExecJs/EvalJs here,
|
||||||
|
@ -186,6 +186,7 @@ class PrerenderTestHelper {
|
|||||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||||
std::optional<std::string> no_vary_search_hint,
|
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::nullopt,
|
||||||
int32_t world_id = ISOLATED_WORLD_ID_GLOBAL);
|
int32_t world_id = ISOLATED_WORLD_ID_GLOBAL);
|
||||||
// AddPrerenderAsync() is the same as AddPrerender(), but does not wait until
|
// AddPrerenderAsync() is the same as AddPrerender(), but does not wait until
|
||||||
// the completion of prerendering.
|
// the completion of prerendering.
|
||||||
@ -201,6 +202,7 @@ class PrerenderTestHelper {
|
|||||||
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
std::optional<blink::mojom::SpeculationEagerness> eagerness,
|
||||||
std::optional<std::string> no_vary_search_hint,
|
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::nullopt,
|
||||||
int32_t world_id = ISOLATED_WORLD_ID_GLOBAL);
|
int32_t world_id = ISOLATED_WORLD_ID_GLOBAL);
|
||||||
|
|
||||||
void AddPrefetchAsync(const GURL& prefetch_url);
|
void AddPrefetchAsync(const GURL& prefetch_url);
|
||||||
|
Reference in New Issue
Block a user