2 <meta name=timeout content=long
>
3 <script src=
"/resources/testharness.js"></script>
4 <script src=
"/resources/testharnessreport.js"></script>
5 <script src=
"/common/get-host-info.sub.js"></script>
6 <script src=
"/common/utils.js"></script>
7 <script src=
"resources/test-helpers.sub.js"></script>
10 var worker
= 'resources/fetch-event-test-worker.js';
12 return new Promise(resolve
=> step_timeout(resolve
, ms
));
15 promise_test(async t
=> {
16 const scope
= 'resources/';
18 await
service_worker_unregister_and_register(t
, worker
, scope
);
19 await
wait_for_state(t
, registration
.installing
, 'activated');
21 return registration
.unregister();
22 }, 'restore global state');
26 const page_url
= 'resources/simple.html?headers';
27 return with_iframe(page_url
)
28 .then(function(frame
) {
29 t
.add_cleanup(() => { frame
.remove(); });
30 const headers
= JSON
.parse(frame
.contentDocument
.body
.textContent
);
31 const header_names
= {};
32 for (const [name
, value
] of headers
) {
33 header_names
[name
] = true;
37 header_names
.hasOwnProperty('accept'),
38 'request includes "Accept" header as inserted by Fetch'
41 }, 'Service Worker headers in the request of a fetch event');
44 const page_url
= 'resources/simple.html?string';
45 return with_iframe(page_url
)
46 .then(function(frame
) {
47 t
.add_cleanup(() => { frame
.remove(); });
49 frame
.contentDocument
.body
.textContent
,
51 'Service Worker should respond to fetch with a test string');
53 frame
.contentDocument
.contentType
,
55 'The content type of the response created with a string should be text/plain');
57 frame
.contentDocument
.characterSet
,
59 'The character set of the response created with a string should be UTF-8');
61 }, 'Service Worker responds to fetch event with string');
64 const page_url
= 'resources/simple.html?string';
66 return with_iframe(page_url
)
69 t
.add_cleanup(() => { frame
.remove(); });
70 return frame
.contentWindow
.fetch(page_url
+ "#foo")
72 .then(function(response
) { return response
.text() })
73 .then(function(text
) {
77 'Service Worker should respond to fetch with a test string');
79 }, 'Service Worker responds to fetch event using request fragment with string');
82 const page_url
= 'resources/simple.html?blob';
83 return with_iframe(page_url
)
85 t
.add_cleanup(() => { frame
.remove(); });
87 frame
.contentDocument
.body
.textContent
,
89 'Service Worker should respond to fetch with a test string');
91 }, 'Service Worker responds to fetch event with blob body');
94 const page_url
= 'resources/simple.html?referrer';
95 return with_iframe(page_url
)
97 t
.add_cleanup(() => { frame
.remove(); });
99 frame
.contentDocument
.body
.textContent
,
100 'Referrer: ' + document
.location
.href
,
101 'Service Worker should respond to fetch with the referrer URL');
103 }, 'Service Worker responds to fetch event with the referrer URL');
106 const page_url
= 'resources/simple.html?clientId';
108 return with_iframe(page_url
)
111 t
.add_cleanup(() => { frame
.remove(); });
113 frame
.contentDocument
.body
.textContent
,
114 'Client ID Not Found',
115 'Service Worker should respond to fetch with a client id');
116 return frame
.contentWindow
.fetch('resources/other.html?clientId');
118 .then(function(response
) { return response
.text(); })
119 .then(function(response_text
) {
121 response_text
.substr(0, 15),
123 'Service Worker should respond to fetch with an existing client id');
125 }, 'Service Worker responds to fetch event with an existing client id');
128 const page_url
= 'resources/simple.html?resultingClientId';
129 const expected_found
= 'Resulting Client ID Found';
130 const expected_not_found
= 'Resulting Client ID Not Found';
131 return with_iframe(page_url
)
132 .then(function(frame
) {
133 t
.add_cleanup(() => { frame
.remove(); });
135 frame
.contentDocument
.body
.textContent
.substr(0, expected_found
.length
),
137 'Service Worker should respond with an existing resulting client id for non-subresource requests');
138 return frame
.contentWindow
.fetch('resources/other.html?resultingClientId');
140 .then(function(response
) { return response
.text(); })
141 .then(function(response_text
) {
143 response_text
.substr(0),
145 'Service Worker should respond with an empty resulting client id for subresource requests');
147 }, 'Service Worker responds to fetch event with the correct resulting client id');
150 const page_url
= 'resources/simple.html?ignore';
151 return with_iframe(page_url
)
152 .then(function(frame
) {
153 t
.add_cleanup(() => { frame
.remove(); });
154 assert_equals(frame
.contentDocument
.body
.textContent
,
155 'Here\'s a simple html file.\n',
156 'Response should come from fallback to native fetch');
158 }, 'Service Worker does not respond to fetch event');
161 const page_url
= 'resources/simple.html?null';
162 return with_iframe(page_url
)
163 .then(function(frame
) {
164 t
.add_cleanup(() => { frame
.remove(); });
165 assert_equals(frame
.contentDocument
.body
.textContent
,
167 'Response should be the empty string');
169 }, 'Service Worker responds to fetch event with null response body');
172 const page_url
= 'resources/simple.html?fetch';
173 return with_iframe(page_url
)
174 .then(function(frame
) {
175 t
.add_cleanup(() => { frame
.remove(); });
176 assert_equals(frame
.contentDocument
.body
.textContent
,
177 'Here\'s an other html file.\n',
178 'Response should come from fetched other file');
180 }, 'Service Worker fetches other file in fetch event');
182 // Creates a form and an iframe and does a form submission that navigates the
183 // frame to |action_url|. Returns the frame after navigation.
184 function submit_form(action_url
) {
185 return new Promise(resolve
=> {
186 const frame
= document
.createElement('iframe');
187 frame
.name
= 'post-frame';
188 document
.body
.appendChild(frame
);
189 const form
= document
.createElement('form');
190 form
.target
= frame
.name
;
191 form
.action
= action_url
;
192 form
.method
= 'post';
193 const input1
= document
.createElement('input');
194 input1
.type
= 'text';
195 input1
.value
= 'testValue1';
196 input1
.name
= 'testName1'
197 form
.appendChild(input1
);
198 const input2
= document
.createElement('input');
199 input2
.type
= 'text';
200 input2
.value
= 'testValue2';
201 input2
.name
= 'testName2'
202 form
.appendChild(input2
);
203 document
.body
.appendChild(form
);
204 frame
.onload = function() {
213 const page_url
= 'resources/simple.html?form-post';
214 return submit_form(page_url
)
216 t
.add_cleanup(() => { frame
.remove(); });
217 assert_equals(frame
.contentDocument
.body
.textContent
,
218 'POST:application/x-www-form-urlencoded:' +
219 'testName1=testValue1&testName2=testValue2');
221 }, 'Service Worker responds to fetch event with POST form');
224 // Add '?ignore' so the service worker falls back to network.
225 const page_url
= 'resources/echo-content.py?ignore';
226 return submit_form(page_url
)
228 t
.add_cleanup(() => { frame
.remove(); });
229 assert_equals(frame
.contentDocument
.body
.textContent
,
230 'testName1=testValue1&testName2=testValue2');
232 }, 'Service Worker falls back to network in fetch event with POST form');
235 const page_url
= 'resources/simple.html?multiple-respond-with';
236 return with_iframe(page_url
)
238 t
.add_cleanup(() => { frame
.remove(); });
240 frame
.contentDocument
.body
.textContent
,
241 '(0)(1)[InvalidStateError](2)[InvalidStateError]',
242 'Multiple calls of respondWith must throw InvalidStateErrors.');
244 }, 'Multiple calls of respondWith must throw InvalidStateErrors');
247 const page_url
= 'resources/simple.html?used-check';
249 return with_iframe(page_url
)
250 .then(function(frame
) {
251 assert_equals(frame
.contentDocument
.body
.textContent
,
252 'Here\'s an other html file.\n',
253 'Response should come from fetched other file');
255 t
.add_cleanup(() => { first_frame
.remove(); });
256 return with_iframe(page_url
);
258 .then(function(frame
) {
259 t
.add_cleanup(() => { frame
.remove(); });
260 // When we access to the page_url in the second time, the content of the
261 // response is generated inside the ServiceWorker. The body contains
262 // the value of bodyUsed of the first response which is already
263 // consumed by FetchEvent.respondWith method.
265 frame
.contentDocument
.body
.textContent
,
267 'event.respondWith must set the used flag.');
269 }, 'Service Worker event.respondWith must set the used flag');
272 const page_url
= 'resources/simple.html?fragment-check';
273 var fragment
= '#/some/fragment';
275 return with_iframe(page_url
+ fragment
)
276 .then(function(frame
) {
277 t
.add_cleanup(() => { frame
.remove(); });
279 frame
.contentDocument
.body
.textContent
,
280 'Fragment Found :' + fragment
,
281 'Service worker should expose URL fragments in request.');
283 }, 'Service Worker should expose FetchEvent URL fragments.');
286 const page_url
= 'resources/simple.html?cache';
289 undefined, 'default', 'no-store', 'reload', 'no-cache', 'force-cache', 'only-if-cached'
291 return with_iframe(page_url
)
294 t
.add_cleanup(() => { frame
.remove(); });
295 assert_equals(frame
.contentWindow
.document
.body
.textContent
, 'default');
296 var tests
= cacheTypes
.map(function(type
) {
297 return new Promise(function(resolve
, reject
) {
298 var init
= {cache
: type
};
299 if (type
=== 'only-if-cached') {
300 // For privacy reasons, for the time being, only-if-cached
301 // requires the mode to be same-origin.
302 init
.mode
= 'same-origin';
304 return frame
.contentWindow
.fetch(page_url
+ '=' + type
, init
)
305 .then(function(response
) { return response
.text(); })
306 .then(function(response_text
) {
307 var expected
= (type
=== undefined) ? 'default' : type
;
308 assert_equals(response_text
, expected
,
309 'Service Worker should respond to fetch with the correct type');
315 return Promise
.all(tests
);
318 return new Promise(function(resolve
, reject
) {
319 frame
.addEventListener('load', function onLoad() {
320 frame
.removeEventListener('load', onLoad
);
322 assert_equals(frame
.contentWindow
.document
.body
.textContent
,
329 frame
.contentWindow
.location
.reload();
332 }, 'Service Worker responds to fetch event with the correct cache types');
335 const page_url
= 'resources/simple.html?eventsource';
338 function test_eventsource(opts
) {
339 return new Promise(function(resolve
, reject
) {
340 var eventSource
= new frame
.contentWindow
.EventSource(page_url
, opts
);
341 eventSource
.addEventListener('message', function(msg
) {
344 var data
= JSON
.parse(msg
.data
);
345 assert_equals(data
.mode
, 'cors',
346 'EventSource should make CORS requests.');
347 assert_equals(data
.cache
, 'no-store',
348 'EventSource should bypass the http cache.');
349 var expectedCredentials
= opts
.withCredentials
? 'include'
351 assert_equals(data
.credentials
, expectedCredentials
,
352 'EventSource should pass correct credentials mode.');
358 eventSource
.addEventListener('error', function(e
) {
360 reject('The EventSource fired an error event.');
365 return with_iframe(page_url
)
368 t
.add_cleanup(() => { frame
.remove(); });
369 return test_eventsource({ withCredentials
: false });
372 return test_eventsource({ withCredentials
: true });
374 }, 'Service Worker should intercept EventSource');
377 const page_url
= 'resources/simple.html?integrity';
379 var integrity_metadata
= 'gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU=';
381 return with_iframe(page_url
)
384 t
.add_cleanup(() => { frame
.remove(); });
385 // A request has associated integrity metadata (a string).
386 // Unless stated otherwise, it is the empty string.
388 frame
.contentDocument
.body
.textContent
, '');
390 return frame
.contentWindow
.fetch(page_url
, {'integrity': integrity_metadata
});
393 return response
.text();
395 .then(response_text
=> {
396 assert_equals(response_text
, integrity_metadata
, 'integrity');
398 }, 'Service Worker responds to fetch event with the correct integrity_metadata');
400 // Test that the service worker can read FetchEvent#body when it is a string.
401 // It responds with request body it read.
403 // Set page_url to "?ignore" so the service worker falls back to network
404 // for the main resource request, and add a suffix to avoid colliding
406 const page_url
= 'resources/simple.html?ignore-for-request-body-string';
409 return with_iframe(page_url
)
412 t
.add_cleanup(() => { frame
.remove(); });
413 return frame
.contentWindow
.fetch('simple.html?request-body', {
415 body
: 'i am the request body'
419 return response
.text();
421 .then(response_text
=> {
422 assert_equals(response_text
, 'i am the request body');
424 }, 'FetchEvent#body is a string');
426 // Test that the service worker can read FetchEvent#body when it is made from
427 // a ReadableStream. It responds with request body it read.
428 promise_test(async t
=> {
429 const rs
= new ReadableStream({start(c
) {
431 c
.enqueue('m the request');
432 step_timeout(t
.step_func(() => {
438 // Set page_url to "?ignore" so the service worker falls back to network
439 // for the main resource request, and add a suffix to avoid colliding
441 const page_url
= `resources/simple.html?ignore&id=${token()}`;
443 const frame
= await
with_iframe(page_url
);
444 t
.add_cleanup(() => { frame
.remove(); });
445 const res
= await frame
.contentWindow
.fetch('simple.html?request-body', {
447 body
: rs
.pipeThrough(new TextEncoderStream())
449 assert_equals(await res
.text(), 'i am the request body');
450 }, 'FetchEvent#body is a ReadableStream');
452 // Test that the request body is sent to network upon network fallback,
453 // for a string body.
455 // Set page_url to "?ignore" so the service worker falls back to network
456 // for the main resource request, and add a suffix to avoid colliding
458 const page_url
= 'resources/?ignore-for-request-body-fallback-string';
461 return with_iframe(page_url
)
464 t
.add_cleanup(() => { frame
.remove(); });
465 // Add "?ignore" so the service worker falls back to echo-content.py.
466 const echo_url
= '/fetch/api/resources/echo-content.py?ignore';
467 return frame
.contentWindow
.fetch(echo_url
, {
469 body
: 'i am the request body'
473 return response
.text();
475 .then(response_text
=> {
478 'i am the request body',
479 'the network fallback request should include the request body');
481 }, 'FetchEvent#body is a string and is passed to network fallback');
483 // Test that the service worker can read FetchEvent#body when it is a blob.
484 // It responds with request body it read.
486 // Set page_url to "?ignore" so the service worker falls back to network
487 // for the main resource request, and add a suffix to avoid colliding
489 const page_url
= 'resources/simple.html?ignore-for-request-body-blob';
492 return with_iframe(page_url
)
495 t
.add_cleanup(() => { frame
.remove(); });
496 const blob
= new Blob(['it\'s me the blob', ' ', 'and more blob!']);
497 return frame
.contentWindow
.fetch('simple.html?request-body', {
503 return response
.text();
505 .then(response_text
=> {
506 assert_equals(response_text
, 'it\'s me the blob and more blob!');
508 }, 'FetchEvent#body is a blob');
510 // Test that the request body is sent to network upon network fallback,
513 // Set page_url to "?ignore" so the service worker falls back to network
514 // for the main resource request, and add a suffix to avoid colliding
516 const page_url
= 'resources/simple.html?ignore-for-request-body-fallback-blob';
519 return with_iframe(page_url
)
522 t
.add_cleanup(() => { frame
.remove(); });
523 const blob
= new Blob(['it\'s me the blob', ' ', 'and more blob!']);
524 // Add "?ignore" so the service worker falls back to echo-content.py.
525 const echo_url
= '/fetch/api/resources/echo-content.py?ignore';
526 return frame
.contentWindow
.fetch(echo_url
, {
532 return response
.text();
534 .then(response_text
=> {
537 'it\'s me the blob and more blob!',
538 'the network fallback request should include the request body');
540 }, 'FetchEvent#body is a blob and is passed to network fallback');
542 promise_test(async (t
) => {
543 const page_url
= 'resources/simple.html?keepalive';
544 const frame
= await
with_iframe(page_url
);
545 t
.add_cleanup(() => { frame
.remove(); });
546 assert_equals(frame
.contentDocument
.body
.textContent
, 'false');
547 const response
= await frame
.contentWindow
.fetch(page_url
, {keepalive
: true});
548 const text
= await response
.text();
549 assert_equals(text
, 'true');
550 }, 'Service Worker responds to fetch event with the correct keepalive value');
552 promise_test(async (t
) => {
553 const page_url
= 'resources/simple.html?isReloadNavigation';
554 const frame
= await
with_iframe(page_url
);
555 t
.add_cleanup(() => { frame
.remove(); });
556 assert_equals(frame
.contentDocument
.body
.textContent
,
557 'method = GET, isReloadNavigation = false');
558 await
new Promise((resolve
) => {
559 frame
.addEventListener('load', resolve
);
560 frame
.contentWindow
.location
.reload();
562 assert_equals(frame
.contentDocument
.body
.textContent
,
563 'method = GET, isReloadNavigation = true');
564 }, 'FetchEvent#request.isReloadNavigation is true (location.reload())');
566 promise_test(async (t
) => {
567 const page_url
= 'resources/simple.html?isReloadNavigation';
568 const frame
= await
with_iframe(page_url
);
569 t
.add_cleanup(() => { frame
.remove(); });
570 assert_equals(frame
.contentDocument
.body
.textContent
,
571 'method = GET, isReloadNavigation = false');
572 await
new Promise((resolve
) => {
573 frame
.addEventListener('load', resolve
);
574 frame
.contentWindow
.history
.go(0);
576 assert_equals(frame
.contentDocument
.body
.textContent
,
577 'method = GET, isReloadNavigation = true');
578 }, 'FetchEvent#request.isReloadNavigation is true (history.go(0))');
580 promise_test(async (t
) => {
581 const page_url
= 'resources/simple.html?isReloadNavigation';
582 const frame
= await
with_iframe(page_url
);
583 t
.add_cleanup(() => { frame
.remove(); });
584 assert_equals(frame
.contentDocument
.body
.textContent
,
585 'method = GET, isReloadNavigation = false');
586 await
new Promise((resolve
) => {
587 frame
.addEventListener('load', resolve
);
588 const form
= frame
.contentDocument
.createElement('form');
589 form
.method
= 'POST';
591 form
.action
= new Request(page_url
).url
;
592 frame
.contentDocument
.body
.appendChild(form
);
595 assert_equals(frame
.contentDocument
.body
.textContent
,
596 'method = POST, isReloadNavigation = false');
597 await
new Promise((resolve
) => {
598 frame
.addEventListener('load', resolve
);
599 frame
.contentWindow
.location
.reload();
601 assert_equals(frame
.contentDocument
.body
.textContent
,
602 'method = POST, isReloadNavigation = true');
603 }, 'FetchEvent#request.isReloadNavigation is true (POST + location.reload())');
605 promise_test(async (t
) => {
606 const page_url
= 'resources/simple.html?isReloadNavigation';
607 const anotherUrl
= new Request('resources/simple.html').url
;
608 let frame
= await
with_iframe(page_url
);
609 t
.add_cleanup(() => { frame
.remove(); });
610 assert_equals(frame
.contentDocument
.body
.textContent
,
611 'method = GET, isReloadNavigation = false');
612 // Use step_timeout(0) to ensure the history entry is created for Blink
613 // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861.
615 await
new Promise((resolve
) => {
616 frame
.addEventListener('load', resolve
);
617 frame
.src
= anotherUrl
;
619 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
620 await
new Promise((resolve
) => {
621 frame
.addEventListener('load', resolve
);
622 frame
.contentWindow
.history
.go(-1);
624 assert_equals(frame
.contentDocument
.body
.textContent
,
625 'method = GET, isReloadNavigation = false');
626 await
new Promise((resolve
) => {
627 frame
.addEventListener('load', resolve
);
628 frame
.contentWindow
.history
.go(0);
630 assert_equals(frame
.contentDocument
.body
.textContent
,
631 'method = GET, isReloadNavigation = true');
632 await
new Promise((resolve
) => {
633 frame
.addEventListener('load', resolve
);
634 frame
.contentWindow
.history
.go(1);
636 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
637 }, 'FetchEvent#request.isReloadNavigation is true (with history traversal)');
639 promise_test(async (t
) => {
640 const page_url
= 'resources/simple.html?isHistoryNavigation';
641 const anotherUrl
= new Request('resources/simple.html?ignore').url
;
642 const frame
= await
with_iframe(page_url
);
643 t
.add_cleanup(() => { frame
.remove(); });
644 assert_equals(frame
.contentDocument
.body
.textContent
,
645 'method = GET, isHistoryNavigation = false');
646 // Use step_timeout(0) to ensure the history entry is created for Blink
647 // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861.
649 await
new Promise((resolve
) => {
650 frame
.addEventListener('load', resolve
);
651 frame
.src
= anotherUrl
;
653 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
654 await
new Promise((resolve
) => {
655 frame
.addEventListener('load', resolve
);
656 frame
.contentWindow
.history
.go(-1);
658 assert_equals(frame
.contentDocument
.body
.textContent
,
659 'method = GET, isHistoryNavigation = true');
660 }, 'FetchEvent#request.isHistoryNavigation is true (with history.go(-1))');
662 promise_test(async (t
) => {
663 const page_url
= 'resources/simple.html?isHistoryNavigation';
664 const anotherUrl
= new Request('resources/simple.html?ignore').url
;
665 const frame
= await
with_iframe(anotherUrl
);
666 t
.add_cleanup(() => { frame
.remove(); });
667 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
668 // Use step_timeout(0) to ensure the history entry is created for Blink
669 // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861.
671 await
new Promise((resolve
) => {
672 frame
.addEventListener('load', resolve
);
673 frame
.src
= page_url
;
675 assert_equals(frame
.contentDocument
.body
.textContent
,
676 'method = GET, isHistoryNavigation = false');
677 await
new Promise((resolve
) => {
678 frame
.addEventListener('load', resolve
);
679 frame
.contentWindow
.history
.go(-1);
681 await
new Promise((resolve
) => {
682 frame
.addEventListener('load', resolve
);
683 frame
.contentWindow
.history
.go(1);
685 assert_equals(frame
.contentDocument
.body
.textContent
,
686 'method = GET, isHistoryNavigation = true');
687 }, 'FetchEvent#request.isHistoryNavigation is true (with history.go(1))');
689 promise_test(async (t
) => {
690 const page_url
= 'resources/simple.html?isHistoryNavigation';
691 const anotherUrl
= new Request('resources/simple.html?ignore').url
;
692 const frame
= await
with_iframe(anotherUrl
);
693 t
.add_cleanup(() => { frame
.remove(); });
694 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
695 // Use step_timeout(0) to ensure the history entry is created for Blink
696 // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861.
698 await
new Promise((resolve
) => {
699 frame
.addEventListener('load', resolve
);
700 frame
.src
= page_url
;
702 assert_equals(frame
.contentDocument
.body
.textContent
,
703 'method = GET, isHistoryNavigation = false');
704 await
new Promise((resolve
) => {
705 frame
.addEventListener('load', resolve
);
706 frame
.contentWindow
.history
.go(-1);
708 await
new Promise((resolve
) => {
709 frame
.addEventListener('load', resolve
);
710 frame
.contentWindow
.history
.go(1);
712 assert_equals(frame
.contentDocument
.body
.textContent
,
713 'method = GET, isHistoryNavigation = true');
714 await
new Promise((resolve
) => {
715 frame
.addEventListener('load', resolve
);
716 frame
.contentWindow
.history
.go(0);
718 assert_equals(frame
.contentDocument
.body
.textContent
,
719 'method = GET, isHistoryNavigation = false');
720 }, 'FetchEvent#request.isHistoryNavigation is false (with history.go(0))');
722 promise_test(async (t
) => {
723 const page_url
= 'resources/simple.html?isHistoryNavigation';
724 const anotherUrl
= new Request('resources/simple.html?ignore').url
;
725 const frame
= await
with_iframe(anotherUrl
);
726 t
.add_cleanup(() => { frame
.remove(); });
727 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
728 // Use step_timeout(0) to ensure the history entry is created for Blink
729 // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861.
731 await
new Promise((resolve
) => {
732 frame
.addEventListener('load', resolve
);
733 frame
.src
= page_url
;
735 assert_equals(frame
.contentDocument
.body
.textContent
,
736 'method = GET, isHistoryNavigation = false');
737 await
new Promise((resolve
) => {
738 frame
.addEventListener('load', resolve
);
739 frame
.contentWindow
.history
.go(-1);
741 await
new Promise((resolve
) => {
742 frame
.addEventListener('load', resolve
);
743 frame
.contentWindow
.history
.go(1);
745 assert_equals(frame
.contentDocument
.body
.textContent
,
746 'method = GET, isHistoryNavigation = true');
747 await
new Promise((resolve
) => {
748 frame
.addEventListener('load', resolve
);
749 frame
.contentWindow
.location
.reload();
751 assert_equals(frame
.contentDocument
.body
.textContent
,
752 'method = GET, isHistoryNavigation = false');
753 }, 'FetchEvent#request.isHistoryNavigation is false (with location.reload)');
755 promise_test(async (t
) => {
756 const page_url
= 'resources/simple.html?isHistoryNavigation';
757 const anotherUrl
= new Request('resources/simple.html?ignore').url
;
758 const oneAnotherUrl
= new Request('resources/simple.html?ignore2').url
;
760 const frame
= await
with_iframe(page_url
);
761 t
.add_cleanup(() => { frame
.remove(); });
762 assert_equals(frame
.contentDocument
.body
.textContent
,
763 'method = GET, isHistoryNavigation = false');
764 // Use step_timeout(0) to ensure the history entry is created for Blink
765 // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861.
767 await
new Promise((resolve
) => {
768 frame
.addEventListener('load', resolve
);
769 frame
.src
= anotherUrl
;
771 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
773 await
new Promise((resolve
) => {
774 frame
.addEventListener('load', resolve
);
775 frame
.src
= oneAnotherUrl
;
777 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
778 await
new Promise((resolve
) => {
779 frame
.addEventListener('load', resolve
);
780 frame
.contentWindow
.history
.go(-2);
782 assert_equals(frame
.contentDocument
.body
.textContent
,
783 'method = GET, isHistoryNavigation = true');
784 }, 'FetchEvent#request.isHistoryNavigation is true (with history.go(-2))');
786 promise_test(async (t
) => {
787 const page_url
= 'resources/simple.html?isHistoryNavigation';
788 const anotherUrl
= new Request('resources/simple.html?ignore').url
;
789 const oneAnotherUrl
= new Request('resources/simple.html?ignore2').url
;
790 const frame
= await
with_iframe(anotherUrl
);
791 t
.add_cleanup(() => { frame
.remove(); });
792 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
793 // Use step_timeout(0) to ensure the history entry is created for Blink
794 // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861.
796 await
new Promise((resolve
) => {
797 frame
.addEventListener('load', resolve
);
798 frame
.src
= oneAnotherUrl
;
800 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
802 await
new Promise((resolve
) => {
803 frame
.addEventListener('load', resolve
);
804 frame
.src
= page_url
;
806 assert_equals(frame
.contentDocument
.body
.textContent
,
807 'method = GET, isHistoryNavigation = false');
808 await
new Promise((resolve
) => {
809 frame
.addEventListener('load', resolve
);
810 frame
.contentWindow
.history
.go(-2);
812 await
new Promise((resolve
) => {
813 frame
.addEventListener('load', resolve
);
814 frame
.contentWindow
.history
.go(2);
816 assert_equals(frame
.contentDocument
.body
.textContent
,
817 'method = GET, isHistoryNavigation = true');
818 }, 'FetchEvent#request.isHistoryNavigation is true (with history.go(2))');
820 promise_test(async (t
) => {
821 const page_url
= 'resources/simple.html?isHistoryNavigation';
822 const anotherUrl
= new Request('resources/simple.html?ignore').url
;
823 const frame
= await
with_iframe(page_url
);
824 t
.add_cleanup(() => { frame
.remove(); });
825 assert_equals(frame
.contentDocument
.body
.textContent
,
826 'method = GET, isHistoryNavigation = false');
827 await
new Promise((resolve
) => {
828 frame
.addEventListener('load', resolve
);
829 const form
= frame
.contentDocument
.createElement('form');
830 form
.method
= 'POST';
832 form
.action
= new Request(page_url
).url
;
833 frame
.contentDocument
.body
.appendChild(form
);
836 assert_equals(frame
.contentDocument
.body
.textContent
,
837 'method = POST, isHistoryNavigation = false');
838 // Use step_timeout(0) to ensure the history entry is created for Blink
839 // and WebKit. See https://bugs.webkit.org/show_bug.cgi?id=42861.
841 await
new Promise((resolve
) => {
842 frame
.addEventListener('load', resolve
);
843 frame
.src
= anotherUrl
;
845 assert_equals(frame
.contentDocument
.body
.textContent
, "Here's a simple html file.\n");
847 await
new Promise((resolve
) => {
848 frame
.addEventListener('load', resolve
);
849 frame
.contentWindow
.history
.go(-1);
851 assert_equals(frame
.contentDocument
.body
.textContent
,
852 'method = POST, isHistoryNavigation = true');
853 }, 'FetchEvent#request.isHistoryNavigation is true (POST + history.go(-1))');