Prerender: Upstream tests for the referrer on prerendering navigation

This CL upstreams tests that prerender uses the page's default referrer
policy. The behavior isn't described in spec, but discussed in [1].

[1] https://github.com/WICG/nav-speculation/issues/51

Bug: 1253158
Change-Id: I8ea931af24ecefc8da84f9710945b36c8e1ea98d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3907161
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Commit-Queue: Yeunjoo Choi <ychoi@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1049450}
diff --git a/speculation-rules/prerender/referrer-policy-no-referrer.html b/speculation-rules/prerender/referrer-policy-no-referrer.html
new file mode 100644
index 0000000..a2bdda9
--- /dev/null
+++ b/speculation-rules/prerender/referrer-policy-no-referrer.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta name="referrer" content="no-referrer">
+<meta name="timeout" content="long">
+<title>Test noreferrer</title>
+<script src="/common/utils.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/speculation-rules/prerender/resources/utils.js"></script>
+<script src="resources/referrer-test.js"></script>
+<body>
+<script>
+setup(() => assertSpeculationRulesIsSupported());
+
+// Tests that the referrer on the prerendering navigation request is not sent
+// when the triggering page's referrer policy is set to no-referrer.
+promise_test(async t => {
+  await referrer_test('(none)', token());
+}, 'no referrer');
+
+</script>
+</body>
diff --git a/speculation-rules/prerender/referrer-policy-origin.html b/speculation-rules/prerender/referrer-policy-origin.html
new file mode 100644
index 0000000..1e7b455
--- /dev/null
+++ b/speculation-rules/prerender/referrer-policy-origin.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta name="referrer" content="origin">
+<meta name="timeout" content="long">
+<title>Test origin referrer</title>
+<script src="/common/utils.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/speculation-rules/prerender/resources/utils.js"></script>
+<script src="resources/referrer-test.js"></script>
+<body>
+<script>
+setup(() => assertSpeculationRulesIsSupported());
+
+// Tests that the referrer on the prerendering navigation request is the
+// triggering page's origin when the referrer policy is set to origin.
+promise_test(async t => {
+  const expected = new URL('', window.origin).href;
+  await referrer_test(expected, token());
+}, 'origin referrer');
+
+</script>
+</body>
diff --git a/speculation-rules/prerender/referrer.html b/speculation-rules/prerender/referrer.html
new file mode 100644
index 0000000..f10d64a
--- /dev/null
+++ b/speculation-rules/prerender/referrer.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Test default referrer</title>
+<meta name="timeout" content="long">
+<script src="/common/utils.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/speculation-rules/prerender/resources/utils.js"></script>
+<script src="resources/referrer-test.js"></script>
+<body>
+<script>
+setup(() => assertSpeculationRulesIsSupported());
+
+// Tests that the referrer on the prerendering navigation request is the
+// triggering page's URL by default.
+promise_test(async t => {
+  await referrer_test(window.location.href, token());
+}, 'default referrer');
+
+</script>
+</body>
diff --git a/speculation-rules/prerender/resources/echo-referrer.py b/speculation-rules/prerender/resources/echo-referrer.py
new file mode 100644
index 0000000..38b5429
--- /dev/null
+++ b/speculation-rules/prerender/resources/echo-referrer.py
@@ -0,0 +1,27 @@
+"""A page that echoes the Referrer header value via BroadcastChannel.
+"""
+
+
+def main(request, response):
+    referrer = request.headers.get(b"referer")
+    uid = request.GET.first(b"uid")
+
+    if referrer is None:
+        referrer = b"(none)"
+
+    html = u'''
+<html>
+<head>
+<title>Echo referrer</title>
+</head>
+<script src="/speculation-rules/prerender/resources/utils.js"></script>
+<body>
+<script>
+const bc = new PrerenderChannel('prerender-channel', '%s');
+bc.postMessage({referrer: '%s'});
+</script>
+</body>
+</html>
+'''
+    return (200, [("Content-Type", b"text/html")],
+            html % (uid.decode("utf-8"), referrer.decode("utf-8")))
diff --git a/speculation-rules/prerender/resources/referrer-test.js b/speculation-rules/prerender/resources/referrer-test.js
new file mode 100644
index 0000000..5091b64
--- /dev/null
+++ b/speculation-rules/prerender/resources/referrer-test.js
@@ -0,0 +1,15 @@
+async function referrer_test(expected, uid) {
+  const bc = new PrerenderChannel('prerender-channel', uid);
+
+  const gotMessage = new Promise(resolve => {
+    bc.addEventListener('message', e => {
+      resolve(e.data);
+    }, {once: true});
+  });
+
+  // Start prerendering a page that will echo its referrer.
+  startPrerendering(`resources/echo-referrer.py?uid=${uid}`);
+
+  const result = await gotMessage;
+  assert_equals(result.referrer, expected, 'referrer');
+}