| // META: timeout=long | |
| // META: script=/common/utils.js | |
| // META: script=beacon-common.sub.js | |
| 'use strict'; | |
| // TODO(yhirano): Check the sec-fetch-mode request header once WebKit supports | |
| // the feature. | |
| parallelPromiseTest(async (t) => { | |
| const iframe = document.createElement('iframe'); | |
| document.body.appendChild(iframe); | |
| t.add_cleanup(() => iframe.remove()); | |
| const id = token(); | |
| const url = `/beacon/resources/beacon.py?cmd=store&id=${id}`; | |
| assert_true(iframe.contentWindow.navigator.sendBeacon(url)); | |
| iframe.remove(); | |
| const result = await waitForResult(id); | |
| assert_equals(result.type, '(missing)', 'content-type'); | |
| }, `simple case: with no payload`); | |
| parallelPromiseTest(async (t) => { | |
| const iframe = document.createElement('iframe'); | |
| document.body.appendChild(iframe); | |
| t.add_cleanup(() => iframe.remove()); | |
| const id = token(); | |
| const url = `/beacon/resources/beacon.py?cmd=store&id=${id}`; | |
| assert_true(iframe.contentWindow.navigator.sendBeacon(url, null)); | |
| iframe.remove(); | |
| const result = await waitForResult(id); | |
| assert_equals(result.type, '(missing)', 'content-type'); | |
| }, `simple case: with null payload`); | |
| for (const size of [EMPTY, SMALL, LARGE, MAX]) { | |
| for (const type of [STRING, ARRAYBUFFER, FORM, BLOB]) { | |
| if (size === MAX && type === FORM) { | |
| // It is difficult to estimate the size of a form accurately, so we cannot | |
| // test this case. | |
| continue; | |
| } | |
| parallelPromiseTest(async (t) => { | |
| const iframe = document.createElement('iframe'); | |
| document.body.appendChild(iframe); | |
| t.add_cleanup(() => iframe.remove()); | |
| const payload = makePayload(size, type); | |
| const id = token(); | |
| const url = `/beacon/resources/beacon.py?cmd=store&id=${id}`; | |
| assert_true(iframe.contentWindow.navigator.sendBeacon(url, payload)); | |
| iframe.remove(); | |
| const result = await waitForResult(id); | |
| if (getContentType(type) === null) { | |
| assert_equals(result.type, '(missing)', 'content-type'); | |
| } else { | |
| assert_true(result.type.includes(getContentType(type)), 'content-type'); | |
| } | |
| }, `simple case: type = ${type} and size = ${size}`); | |
| } | |
| } | |
| for (const type of [STRING, ARRAYBUFFER, FORM, BLOB]) { | |
| parallelPromiseTest(async (t) => { | |
| const iframe = document.createElement('iframe'); | |
| document.body.appendChild(iframe); | |
| t.add_cleanup(() => iframe.remove()); | |
| const payload = makePayload(TOOLARGE, type); | |
| const id = token(); | |
| const url = `/beacon/resources/beacon.py?cmd=store&id=${id}`; | |
| assert_false(iframe.contentWindow.navigator.sendBeacon(url, payload)); | |
| }, `Too large payload should be rejected: type = ${type}`); | |
| } | |
| for (const type of [STRING, ARRAYBUFFER, BLOB]) { | |
| parallelPromiseTest(async (t) => { | |
| const iframe = document.createElement('iframe'); | |
| document.body.appendChild(iframe); | |
| t.add_cleanup(() => iframe.remove()); | |
| assert_true(iframe.contentWindow.navigator.sendBeacon( | |
| `/beacon/resources/beacon.py?cmd=store&id=${token()}`, | |
| makePayload(MAX, type))); | |
| assert_true(iframe.contentWindow.navigator.sendBeacon( | |
| `/beacon/resources/beacon.py?cmd=store&id=${token()}`, '')); | |
| assert_false(iframe.contentWindow.navigator.sendBeacon( | |
| `/beacon/resources/beacon.py?cmd=store&id=${token()}`, 'x')); | |
| }, `Payload size restriction should be accumulated: type = ${type}`); | |
| } | |
| test(() => { | |
| assert_throws_js( | |
| TypeError, () => navigator.sendBeacon('...', new ReadableStream())); | |
| }, 'sendBeacon() with a stream does not work due to the keepalive flag being set'); |