Bug 1717224 [wpt PR 29434] - Make the Referrer-Policy tests allow further truncated...
[gecko.git] / testing / web-platform / tests / referrer-policy / generic / test-case.sub.js
blob717cd1a5e75b476a7580626246fb8f75eaae82f5
1 // https://w3c.github.io/webappsec-referrer-policy/#strip-url
2 function stripUrlForUseAsReferrer(url, originOnly) {
3   // Step 2. If url’s scheme is a local scheme, then return no referrer.
4   const parsedUrl = new URL(url);
6   if (["about:", "blob:", "data:"].includes(parsedUrl.protocol))
7     return undefined;
9   // Step 3. Set url’s username to the empty string.
10   parsedUrl.username = '';
12   // Step 4. Set url’s password to null.
13   parsedUrl.password = '';
15   // Step 5. Set url’s fragment to null.
16   parsedUrl.hash = '';
18   //  Step 6. If the origin-only flag is true, then:
19   if (originOnly) {
20     // Step 6.1. Set url’s path to null.
21     parsedUrl.pathname = '';
22     // Step 6.2. Set url’s query to null.
23     parsedUrl.search = '';
24   }
25   return parsedUrl.href;
28 function invokeScenario(scenario) {
29   const urls = getRequestURLs(
30     scenario.subresource,
31     scenario.origin,
32     scenario.redirection);
33   /** @type {Subresource} */
34   const subresource = {
35     subresourceType: scenario.subresource,
36     url: urls.testUrl,
37     policyDeliveries: scenario.subresource_policy_deliveries,
38   };
40   return invokeRequest(subresource, scenario.source_context_list);
43 const referrerUrlResolver = {
44   // The spec allows UAs to "enforce arbitrary policy considerations in the
45   // interests of minimizing data leakage"; to start to vaguely approximate
46   // this, we allow stronger policies to be used instead of what's specificed.
47   "omitted": function(sourceUrl) {
48     return [undefined];
49   },
50   "origin": function(sourceUrl) {
51     return [stripUrlForUseAsReferrer(sourceUrl, true),
52             undefined];
53   },
54   "stripped-referrer": function(sourceUrl) {
55     return [stripUrlForUseAsReferrer(sourceUrl, false),
56             stripUrlForUseAsReferrer(sourceUrl, true),
57             undefined];
58   }
61 function checkResult(scenario, expectation, result) {
62 // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
63   let referrerSource = result.sourceContextUrl;
64   const sentFromSrcdoc = scenario.source_context_list.length > 0 &&
65       scenario.source_context_list[scenario.source_context_list.length - 1]
66       .sourceContextType === 'srcdoc';
67   if (sentFromSrcdoc) {
68     // Step 3. While document is an iframe srcdoc document, let document be
69     // document's browsing context's browsing context container's node
70     // document. [spec text]
72     // Workaround for srcdoc cases. Currently we only test <iframe srcdoc>
73     // inside the top-level Document, so |document| in the spec here is
74     // the top-level Document.
75     // This doesn't work if e.g. we test <iframe srcdoc> inside another
76     // external <iframe>.
77     referrerSource = location.toString();
78   }
79   const possibleReferrerUrls =
80     referrerUrlResolver[expectation](referrerSource);
82   // Check the reported URL.
83   assert_in_array(result.referrer,
84                   possibleReferrerUrls,
85                   "document.referrer");
86   assert_in_array(result.headers.referer,
87                   possibleReferrerUrls,
88                   "HTTP Referer header");
91 function runLengthTest(scenario, urlLength, expectation, testDescription) {
92   // `Referer` headers with length over 4k are culled down to an origin, so,
93   // let's test around that boundary for tests that would otherwise return
94   // the complete URL.
95   history.pushState(null, null, "/");
96   history.replaceState(null, null,
97       "A".repeat(urlLength - location.href.length));
99   promise_test(t => {
100     assert_equals(scenario.expectation, "stripped-referrer");
101     // Only on top-level Window, due to navigations using `history`.
102     assert_equals(scenario.source_context_list.length, 0);
104     return invokeScenario(scenario)
105       .then(result => checkResult(scenario, expectation, result));
106   }, testDescription);
109 function TestCase(scenarios, sanityChecker) {
110   function runTest(scenario) {
111     // This check is A NOOP in release.
112     sanityChecker.checkScenario(scenario);
114     promise_test(_ => {
115       return invokeScenario(scenario)
116         .then(result => checkResult(scenario, scenario.expectation, result));
117     }, scenario.test_description);
118   }
120   function runTests() {
121     for (const scenario of scenarios) {
122       runTest(scenario);
123     }
124   }
126   return {start: runTests};