1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
|
<!DOCTYPE html>
<title>Prefetched response including No-Vary-Search headers is used during navigation</title>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/utils.js"></script>
<script src="../../resources/utils.js"></script>
<script src="../resources/utils.sub.js"></script>
<script src="/common/subset-tests.js"></script>
<meta name="variant" content="?1-1">
<meta name="variant" content="?2-2">
<meta name="variant" content="?3-3">
<meta name="variant" content="?4-4">
<meta name="variant" content="?5-5">
<meta name="variant" content="?6-6">
<meta name="variant" content="?7-7">
<meta name="variant" content="?8-8">
<meta name="variant" content="?9-9">
<meta name="variant" content="?10-10">
<meta name="variant" content="?11-11">
<meta name="variant" content="?12-12">
<meta name="variant" content="?13-13">
<meta name="variant" content="?14-14">
<meta name="variant" content="?15-15">
<meta name="variant" content="?16-16">
<meta name="variant" content="?17-17">
<meta name="variant" content="?18-18">
<meta name="variant" content="?19-19">
<meta name="variant" content="?20-20">
<meta name="variant" content="?21-21">
<meta name="variant" content="?22-22">
<meta name="variant" content="?23-23">
<meta name="variant" content="?24-24">
<meta name="variant" content="?25-25">
<meta name="variant" content="?26-26">
<meta name="variant" content="?27-27">
<meta name="variant" content="?28-28">
<meta name="variant" content="?29-29">
<meta name="variant" content="?30-last">
<script>
setup(() => assertSpeculationRulesIsSupported());
function addNoVarySearchHeaderUsingPipe(url, value){
// Use server pipes https://web-platform-tests.org/writing-tests/server-pipes.html
// to populate No-Vary-Search response header.
// The "," and ")" characters need to be escaped by using backslash
// (see https://web-platform-tests.org/writing-tests/server-pipes.html).
// E.g. params=("a") becomes params=("a"\), params=("a"),key-order becomes
// params=("a"\)\,key-order etc.
url.searchParams.append("pipe",
`header(No-Vary-Search,${value.replaceAll(/[,)]/g, '\\$&')})`);
}
/*
remoteAgent: the RemoteContext instance used to communicate between the
test and the window where prefetch/navigation is happening
noVarySearchHeaderValue: the value of No-Vary-Search header to be populated
for the prefetched response
prefetchQuery: query params to be added to prefetchExecutor url and prefetched
navigateQuery: query params to be added to prefetchExecutor url and navigated to
*/
async function prefetchAndNavigate(remoteAgent, noVarySearchHeaderValue, prefetchQuery, navigateQuery){
const nextUrl = remoteAgent.getExecutorURL();
const navigateToUrl = new URL(nextUrl);
// Add query params to the url to be prefetched.
const additionalPrefetchedUrlSearchParams = new URLSearchParams(prefetchQuery);
addNoVarySearchHeaderUsingPipe(nextUrl, noVarySearchHeaderValue);
additionalPrefetchedUrlSearchParams.forEach((value, key) => {
nextUrl.searchParams.append(key, value);
});
await remoteAgent.forceSinglePrefetch(nextUrl);
// Add new query params to navigateToUrl to match No-Vary-Search test case.
const additionalNavigateToUrlSearchParams = new URLSearchParams(navigateQuery);
addNoVarySearchHeaderUsingPipe(navigateToUrl, noVarySearchHeaderValue);
additionalNavigateToUrlSearchParams.forEach((value, key) => {
navigateToUrl.searchParams.append(key, value);
});
await remoteAgent.navigate(navigateToUrl);
}
function prefetch_no_vary_search_test(description, noVarySearch, prefetchQuery, navigateQuery, shouldUsePrefetch){
promise_test(async t => {
const agent = await spawnWindow(t, {});
await prefetchAndNavigate(agent,
noVarySearch,
prefetchQuery,
navigateQuery);
if(shouldUsePrefetch){
assert_prefetched(await agent.getRequestHeaders(),
"Navigation didn't use the prefetched response!");
}
else{
assert_not_prefetched(await agent.getRequestHeaders(),
"Navigation used the prefetched response!");
}
}, description);
}
// Test inputs:
// - description: a description of the test.
// - no-vary-search: No-Vary-Search header value for the response.
// - prefetch-query: added to query part of prefetch-executor when prefetching
// - navigate-query: added to query part of prefetch-executor when navigating
// - shouldUsePrefetch: if the test case expects the prefetched entry to be
// used or not.
[{description:"Use prefetched response as query parameter b has the same value.",
noVarySearch: 'params=("a")',
prefetchQuery: "a=2&b=3",
navigateQuery: "b=3",
shouldUsePrefetch: true},
{description:"Don't use prefetched response as query parameter b has different value.",
noVarySearch: 'params("a")',
prefetchQuery: "a=2&b=3",
navigateQuery: "b=2",
shouldUsePrefetch: false},
{description:"Use prefetched response as the URLs do not vary by a and b.",
noVarySearch: 'params=("a" "b")',
prefetchQuery: "a=2&b=3",
navigateQuery: "b=2",
shouldUsePrefetch: true},
{description:"Use prefetched response as the URLs do not vary on any query parameters.",
noVarySearch: "params",
prefetchQuery: "a=2&b=3",
navigateQuery: "b=4&c=5",
shouldUsePrefetch: true},
{description:"Use prefetched response as the URLs do not vary on any query parameters.",
noVarySearch: "params",
prefetchQuery: "",
navigateQuery: "b=4&c=5",
shouldUsePrefetch: true},
{description:"Don't use prefetched response as the URLs have different value for c.",
noVarySearch: "key-order",
prefetchQuery: "c=4&b=3&a=2",
navigateQuery: "a=2&c=5&b=3",
shouldUsePrefetch: false},
{description:"Don't use prefetched response as the URLs have the values in different order for a.",
noVarySearch: "key-order",
prefetchQuery: "b=5&a=3&a=4&d=6&c=5&b=3",
navigateQuery: "d=6&a=4&b=5&b=3&c=5&a=3",
shouldUsePrefetch: false},
{description:"Use prefetched response as the URLs have the same values for a.",
noVarySearch: "key-order",
prefetchQuery: "b=5&a=3&a=4&d=6&c=5&b=3",
navigateQuery: "d=6&a=3&b=5&b=3&c=5&a=4",
shouldUsePrefetch: true},
{description:"Use prefetched response as the URLs have the same values for a.",
noVarySearch: "key-order=?1",
prefetchQuery: "b=5&a=3&a=4&d=6&c=5&b=3",
navigateQuery: "d=6&a=3&b=5&b=3&c=5&a=4",
shouldUsePrefetch: true},
{description:"Don't use prefetched response as key-order is set to false and the URLs are not identical.",
noVarySearch: "key-order=?0",
prefetchQuery: "b=5&a=3&a=4&d=6&c=5&b=3",
navigateQuery: "d=6&a=3&b=5&b=3&c=5&a=4",
shouldUsePrefetch: false},
{description:"Use prefetched response as query parameter c can be ignored.",
noVarySearch: 'params=("c")',
prefetchQuery: "a=2&b=2&c=5",
navigateQuery: "a=2&c=3&b=2",
shouldUsePrefetch: true},
{description:"Use prefetched response as query parameter a can be ignored.",
noVarySearch: 'params=("a")',
prefetchQuery: "a=2",
navigateQuery: "",
shouldUsePrefetch: true},
{description:"Use prefetched response as query parameter a can be ignored.",
noVarySearch: 'params=("a")',
prefetchQuery: "",
navigateQuery: "a=2",
shouldUsePrefetch: true},
{description:"Use prefetched response as all query parameters except c can be ignored.",
noVarySearch: 'params, except=("c")',
prefetchQuery: "b=5&a=3&d=6&c=3",
navigateQuery: "a=1&b=2&c=3",
shouldUsePrefetch: true},
{description:"Use prefetched response as all query parameters except c can be ignored." +
" Only the last except matters.",
noVarySearch: 'params, except=("b"), except=("c")',
prefetchQuery: "b=5&a=3&d=6&c=3",
navigateQuery: "a=1&b=2&c=3",
shouldUsePrefetch: true},
{description:"Don't use prefetched response as even though all query parameters" +
" except c can be ignored, c has different value.",
noVarySearch: 'params, except=("c")',
prefetchQuery: "b=5&a=3&d=6&c=3",
navigateQuery: "a=1&b=2&c=5",
shouldUsePrefetch: false},
{description:"Use prefetched response as even though all query parameters" +
" except c and d can be ignored, c value matches and d value matches.",
noVarySearch: 'params, except=("c" "d")',
prefetchQuery: "b=5&a=3&d=6&c=5",
navigateQuery: "d=6&a=1&b=2&c=5",
shouldUsePrefetch: true},
{description:"Use prefetched response as even though all query parameters except" +
" c and d can be ignored, c value matches and d value matches." +
" Some query parameters to be ignored appear multiple times in the query.",
noVarySearch: 'params, except=("c" "d")',
prefetchQuery: "b=5&a=3&a=4&d=6&c=5",
navigateQuery: "d=6&a=1&a=2&b=2&b=3&c=5",
shouldUsePrefetch: true},
{description:"Use prefetched response as all query parameters except c can be ignored." +
" Allow extension via parameters.",
noVarySearch: 'params, except=("c";unknown)',
prefetchQuery: "b=5&a=3&d=6&c=3",
navigateQuery: "a=1&b=2&c=3",
shouldUsePrefetch: true},
{description:"Use prefetched response as query parameter c can be ignored." +
" Allow extension via parameters.",
noVarySearch: 'params=("c";unknown)',
prefetchQuery: "a=2&b=2&c=5",
navigateQuery: "a=2&c=3&b=2",
shouldUsePrefetch: true},
{description:"Use prefetched response as the URLs have the values in different order for a." +
" Allow extension via parameters.",
noVarySearch: "key-order;unknown",
prefetchQuery: "b=5&a=3&a=4&d=6&c=5&b=3",
navigateQuery: "d=6&a=3&b=5&b=3&c=5&a=4",
shouldUsePrefetch: true},
{description:"Use prefetched response as the URLs do not vary on any query parameters." +
" Allow extension via parameters.",
noVarySearch: "params;unknown",
prefetchQuery: "",
navigateQuery: "b=4&c=5",
shouldUsePrefetch: true},
{description:"Use prefetched response as all query parameters except c can be ignored." +
" Allow extension via parameters.",
noVarySearch: 'params;unknown, except=("c");unknown',
prefetchQuery: "b=5&a=3&d=6&c=3",
navigateQuery: "a=1&b=2&c=3",
shouldUsePrefetch: true},
{description:"Don't use the prefetched URL. Empty No-Vary-Search means default URL variance." +
" The prefetched and the navigated URLs have to be the same.",
noVarySearch: "",
prefetchQuery: "b=5&a=3&d=6&c=3",
navigateQuery: "a=1&b=2&c=3",
shouldUsePrefetch: false},
{description:"Use the prefetched URL. Empty No-Vary-Search means default URL variance." +
" The prefetched and the navigated URLs have to be the same.",
noVarySearch: "",
prefetchQuery: "b=5&a=3&d=6&c=3",
navigateQuery: "b=5&a=3&d=6&c=3",
shouldUsePrefetch: true},
{description:"Use the prefetched URL. Empty No-Vary-Search means default URL variance." +
" The prefetched and the navigated URLs have to be the same.",
noVarySearch: "",
prefetchQuery: "",
navigateQuery: "",
shouldUsePrefetch: true},
{description:"Use the prefetched URL. Non-ASCII key - 2 UTF-8 code units." +
" Don't vary the response on the non-ASCII key.",
noVarySearch: 'params=("%C2%A2")',
prefetchQuery: "¢=3",
navigateQuery: "¢=4",
shouldUsePrefetch: true},
{description:"Use the prefetched URL. Non-ASCII key - 2 UTF-8 code units." +
" Don't vary the response on the non-ASCII key.",
noVarySearch: 'params=("%C2%A2")',
prefetchQuery: "a=2&¢=3",
navigateQuery: "¢=4&a=2",
shouldUsePrefetch: true},
{description:"Don't use the prefetched URL. Non-ASCII key - 2 UTF-8 code units." +
" Vary the response on the non-ASCII key.",
noVarySearch: 'params, except=("%C2%A2")',
prefetchQuery: "¢=3",
navigateQuery: "¢=4",
shouldUsePrefetch: false},
{description:"Use the prefetched URL. Non-ASCII key - 2 UTF-8 code units." +
" Vary the response on the non-ASCII key.",
noVarySearch: 'params, except=("%C2%A2")',
prefetchQuery: "¢=3&a=4",
navigateQuery: "a=5&¢=3",
shouldUsePrefetch: true},
].forEach(({description, noVarySearch, prefetchQuery, navigateQuery, shouldUsePrefetch}) => {
subsetTest(prefetch_no_vary_search_test,
description, noVarySearch, prefetchQuery, navigateQuery,
shouldUsePrefetch);
});
</script>
|