diff options
Diffstat (limited to 'tests/wpt/web-platform-tests/fetch/api')
15 files changed, 211 insertions, 53 deletions
diff --git a/tests/wpt/web-platform-tests/fetch/api/cors/cors-expose-star.js b/tests/wpt/web-platform-tests/fetch/api/cors/cors-expose-star.js index e37ddb4c3f2..edf4d424179 100644 --- a/tests/wpt/web-platform-tests/fetch/api/cors/cors-expose-star.js +++ b/tests/wpt/web-platform-tests/fetch/api/cors/cors-expose-star.js @@ -31,7 +31,7 @@ promise_test(() => { }, "* for credentialed fetches only matches literally") promise_test(() => { - const headers = "header(Access-Control-Allow-Origin,*)|header(Access-Control-Expose-Headers,set-cookie)" + const headers = "header(Access-Control-Allow-Origin,*)|header(Access-Control-Expose-Headers,set-cookie\\,*)" return fetch(url + sharedHeaders + headers).then(resp => { assert_equals(resp.status, 200) assert_equals(resp.type , "cors") diff --git a/tests/wpt/web-platform-tests/fetch/api/redirect/redirect-method.js b/tests/wpt/web-platform-tests/fetch/api/redirect/redirect-method.js index 13433a1bb39..0a7f2df2c2b 100644 --- a/tests/wpt/web-platform-tests/fetch/api/redirect/redirect-method.js +++ b/tests/wpt/web-platform-tests/fetch/api/redirect/redirect-method.js @@ -3,14 +3,22 @@ if (this.document === undefined) { importScripts("../resources/utils.js"); } -function redirectMethod(desc, redirectUrl, redirectLocation, redirectStatus, method, expectedMethod) { +// Creates a promise_test that fetches a URL that returns a redirect response. +// +// |opts| has additional options: +// |opts.body|: the request body as a string or blob (default is empty body) +// |opts.expectedBodyAsString|: the expected response body as a string. The +// server is expected to echo the request body. The default is the empty string +// if the request after redirection isn't POST; otherwise it's |opts.body|. +function redirectMethod(desc, redirectUrl, redirectLocation, redirectStatus, method, expectedMethod, opts) { var url = redirectUrl; var urlParameters = "?redirect_status=" + redirectStatus; urlParameters += "&location=" + encodeURIComponent(redirectLocation); var requestInit = {"method": method, "redirect": "follow"}; - if (method != "GET" && method != "HEAD") - requestInit.body = "this is my body"; + opts = opts || {}; + if (opts.body) + requestInit.body = opts.body; promise_test(function(test) { return fetch(url + urlParameters, requestInit).then(function(resp) { @@ -19,7 +27,10 @@ function redirectMethod(desc, redirectUrl, redirectLocation, redirectStatus, met assert_equals(resp.headers.get("x-request-method"), expectedMethod, "Request method after redirection is " + expectedMethod); assert_true(resp.redirected); return resp.text().then(function(text) { - assert_equals(text, expectedMethod == "POST" ? requestInit.body : ""); + let expectedBody = ""; + if (expectedMethod == "POST") + expectedBody = opts.expectedBodyAsString || requestInit.body; + assert_equals(text, expectedBody, "request body"); }); }); }, desc); @@ -36,20 +47,25 @@ promise_test(function(test) { var redirUrl = RESOURCES_DIR + "redirect.py"; var locationUrl = "method.py"; +const stringBody = "this is my body"; +const blobBody = new Blob(["it's me the blob!", " ", "and more blob!"]); +const blobBodyAsString = "it's me the blob! and more blob!"; + redirectMethod("Redirect 301 with GET", redirUrl, locationUrl, 301, "GET", "GET"); -redirectMethod("Redirect 301 with POST", redirUrl, locationUrl, 301, "POST", "GET"); +redirectMethod("Redirect 301 with POST", redirUrl, locationUrl, 301, "POST", "GET", { body: stringBody }); redirectMethod("Redirect 301 with HEAD", redirUrl, locationUrl, 301, "HEAD", "HEAD"); redirectMethod("Redirect 302 with GET", redirUrl, locationUrl, 302, "GET", "GET"); -redirectMethod("Redirect 302 with POST", redirUrl, locationUrl, 302, "POST", "GET"); +redirectMethod("Redirect 302 with POST", redirUrl, locationUrl, 302, "POST", "GET", { body: stringBody }); redirectMethod("Redirect 302 with HEAD", redirUrl, locationUrl, 302, "HEAD", "HEAD"); redirectMethod("Redirect 303 with GET", redirUrl, locationUrl, 303, "GET", "GET"); -redirectMethod("Redirect 303 with POST", redirUrl, locationUrl, 303, "POST", "GET"); +redirectMethod("Redirect 303 with POST", redirUrl, locationUrl, 303, "POST", "GET", { body: stringBody }); redirectMethod("Redirect 303 with HEAD", redirUrl, locationUrl, 303, "HEAD", "HEAD"); redirectMethod("Redirect 307 with GET", redirUrl, locationUrl, 307, "GET", "GET"); -redirectMethod("Redirect 307 with POST", redirUrl, locationUrl, 307, "POST", "POST"); +redirectMethod("Redirect 307 with POST (string body)", redirUrl, locationUrl, 307, "POST", "POST", { body: stringBody }); +redirectMethod("Redirect 307 with POST (blob body)", redirUrl, locationUrl, 307, "POST", "POST", { body: blobBody, expectedBodyAsString: blobBodyAsString }); redirectMethod("Redirect 307 with HEAD", redirUrl, locationUrl, 307, "HEAD", "HEAD"); done(); diff --git a/tests/wpt/web-platform-tests/fetch/api/request/destination/fetch-destination.https.html b/tests/wpt/web-platform-tests/fetch/api/request/destination/fetch-destination.https.html new file mode 100644 index 00000000000..b504bb9c238 --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/destination/fetch-destination.https.html @@ -0,0 +1,134 @@ +<!DOCTYPE html> +<title>Service Worker: the body of FetchEvent using XMLHttpRequest</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/common/media.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> +<script> +let frame; + +// Set up the service worker and the frame. +promise_test(t => { + const kScope = 'resources/empty.https.html'; + const kScript = 'resources/fetch-destination-worker.js'; + return service_worker_unregister_and_register(t, kScript, kScope) + .then(registration => { + add_completion_callback(() => { + registration.unregister(); + }); + + return wait_for_state(t, registration.installing, 'activated'); + }) + .then(() => { + return with_iframe(kScope); + }) + .then(f => { + frame = f; + add_completion_callback(() => { f.remove(); }); + }); + }, 'Initialize global state'); + +// Actual tests + +// HTMLImageElement - image destination +promise_test(async t => { + await new Promise((resolve, reject) => { + var node = frame.contentWindow.document.createElement("img"); + node.onload = resolve; + node.onerror = reject; + node.src = "dummy.png?dest=image"; + }).catch(() => { + assert_unreached("Fetch errored."); + }); +}, 'HTMLImageElement fetches with an "image" Request.destination'); + +// fetch() - empty string destination +promise_test(async t => { + let response = await frame.contentWindow.fetch("dummy?dest="); + assert_true(response.ok); +}, 'fetch() fetches with an empty string Request.destination'); + +// HTMLAudioElement - audio destination +promise_test(async t => { + await new Promise((resolve, reject) => { + var audioURL = getAudioURI("dummy_audio"); + var node = frame.contentWindow.document.createElement("audio"); + node.onloadeddata = resolve; + node.onerror = reject; + node.src = audioURL + "?dest=audio"; + }).catch(() => { + assert_unreached("Fetch errored."); + }); +}, 'HTMLAudioElement fetches with an "audio" Request.destination'); + +// HTMLVideoElement - video destination +promise_test(async t => { + await new Promise((resolve, reject) => { + var videoURL = getVideoURI("dummy_video"); + var node = frame.contentWindow.document.createElement("video"); + node.onloadeddata = resolve; + node.onerror = reject; + node.src = videoURL + "?dest=video"; + }).catch(() => { + assert_unreached("Fetch errored."); + }); +}, 'HTMLVideoElement fetches with a "video" Request.destination'); + +// HTMLScriptElement - script destination +promise_test(async t => { + await new Promise((resolve, reject) => { + var node = frame.contentWindow.document.createElement("script"); + node.onload = resolve; + node.onerror = reject; + node.src = "dummy?dest=script"; + frame.contentWindow.document.body.appendChild(node); + }).catch(() => { + assert_unreached("Fetch errored."); + }); +}, 'HTMLScriptElement fetches with a "script" Request.destination'); + +// HTMLLinkElement with rel=stylesheet - script destination +promise_test(async t => { + await new Promise((resolve, reject) => { + var node = frame.contentWindow.document.createElement("link"); + node.rel = "stylesheet"; + node.onload = resolve; + node.onerror = reject; + node.href = "dummy?dest=style"; + frame.contentWindow.document.body.appendChild(node); + }).catch(() => { + assert_unreached("Fetch errored."); + }); +}, 'HTMLLinkElement with rel=stylesheet fetches with a "style" Request.destination'); + +// HTMLLinkElement with rel=preload and as=fetch - empty string destination +promise_test(async t => { + await new Promise((resolve, reject) => { + var node = frame.contentWindow.document.createElement("link"); + node.rel = "preload"; + node.as = "fetch"; + node.onload = resolve; + node.onerror = reject; + node.href = "dummy?t=2&dest="; + frame.contentWindow.document.body.appendChild(node); + }).catch(() => { + assert_unreached("Fetch errored."); + }); +}, 'HTMLLinkElement with rel=preload and as=fetch fetches with an empty string Request.destination'); + +// HTMLLinkElement with rel=preload and as=style - style destination +promise_test(async t => { + await new Promise((resolve, reject) => { + var node = frame.contentWindow.document.createElement("link"); + node.rel = "preload"; + node.as = "style"; + node.onload = resolve; + node.onerror = reject; + node.href = "dummy?t=2&dest=style"; + frame.contentWindow.document.body.appendChild(node); + }).catch(() => { + assert_unreached("Fetch errored."); + }); +}, 'HTMLLinkElement with rel=preload and as=style fetches with a "style" Request.destination'); +</script> diff --git a/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy diff --git a/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy.png b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy.png Binary files differnew file mode 100644 index 00000000000..01c9666a8de --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy.png diff --git a/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_audio.mp3 b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_audio.mp3 Binary files differnew file mode 100644 index 00000000000..0091330f1ec --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_audio.mp3 diff --git a/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_audio.oga b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_audio.oga Binary files differnew file mode 100644 index 00000000000..239ad2bd08c --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_audio.oga diff --git a/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_video.mp4 b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_video.mp4 Binary files differnew file mode 100644 index 00000000000..7022e75c15e --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_video.mp4 diff --git a/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_video.ogv b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_video.ogv Binary files differnew file mode 100644 index 00000000000..de99616eceb --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/dummy_video.ogv diff --git a/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/empty.https.html b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/empty.https.html new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/empty.https.html diff --git a/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/fetch-destination-worker.js b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/fetch-destination-worker.js new file mode 100644 index 00000000000..f8e8e2669d0 --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/destination/resources/fetch-destination-worker.js @@ -0,0 +1,11 @@ +self.addEventListener('fetch', function(event) { + if (event.request.url.includes('dummy')) { + let destination = new URL(event.request.url).searchParams.get("dest"); + if (event.request.destination == destination) { + event.respondWith(fetch(event.request)); + } else { + event.respondWith(Response.error()); + } + } +}); + diff --git a/tests/wpt/web-platform-tests/fetch/api/request/request-idl.html b/tests/wpt/web-platform-tests/fetch/api/request/request-idl.html index f78f0ca894a..f7833779ce2 100644 --- a/tests/wpt/web-platform-tests/fetch/api/request/request-idl.html +++ b/tests/wpt/web-platform-tests/fetch/api/request/request-idl.html @@ -15,9 +15,7 @@ typedef any JSON; typedef (Blob or BufferSource or FormData or URLSearchParams or USVString) BodyInit; - [NoInterfaceObject, - Exposed=(Window,Worker)] - interface Body { + interface mixin Body { readonly attribute ReadableStream? body; readonly attribute boolean bodyUsed; [NewObject] Promise<ArrayBuffer> arrayBuffer(); @@ -48,7 +46,7 @@ [NewObject] Request clone(); }; - Request implements Body; + Request includes Body; dictionary RequestInit { ByteString method; diff --git a/tests/wpt/web-platform-tests/fetch/api/request/request-keepalive-quota.html b/tests/wpt/web-platform-tests/fetch/api/request/request-keepalive-quota.html index dacc6382667..19596cea2c8 100644 --- a/tests/wpt/web-platform-tests/fetch/api/request/request-keepalive-quota.html +++ b/tests/wpt/web-platform-tests/fetch/api/request/request-keepalive-quota.html @@ -12,81 +12,80 @@ </head> <body> <script> - "use strict"; + 'use strict'; // We want to ensure that our keepalive requests hang slightly before completing so we can validate // the effects of a rolling quota. To do this we will utilize trickle.py with a 1s delay. This should // prevent any of the Fetch's from finishing in this window. - var trickleURL = "../resources/trickle.py?count=1&ms="; - var standardDelay = 1000; + const trickleURL = '../resources/trickle.py?count=1&ms='; + const noDelay = 0; + const standardDelay = 1000; + function wait(ms) { + return new Promise(resolve => step_timeout(resolve, ms)); + } // We should expect 64KiB of rolling quota for any type of keep-alive request sent. - var expectedQuota = 65536; + const expectedQuota = 65536; - function CreateKeepAliveRequest(delay, bodySize) { + function fetchKeepAliveRequest(delay, bodySize) { // Create a body of the specified size that's filled with *'s - var requestBody = "*".repeat(bodySize); - return new Request(trickleURL+delay, {keepalive: true, body: requestBody, method: "POST"}); + const body = '*'.repeat(bodySize); + return fetch(trickleURL + delay, {keepalive: true, body, method: 'POST'}).then(res => { + return res.text(); + }).then(() => { + return wait(1); + }); } // Test 1 Byte promise_test(function(test) { - return fetch(CreateKeepAliveRequest(0 /* delay */, 1 /* bodySize */)); - }, "A Keep-Alive fetch() with a small body should succeed."); + return fetchKeepAliveRequest(noDelay, 1 /* bodySize */); + }, 'A Keep-Alive fetch() with a small body should succeed.'); // Test Quota full limit promise_test(function(test) { - return fetch(CreateKeepAliveRequest(0 /* delay */, expectedQuota)); - }, "A Keep-Alive fetch() with a body at the Quota Limit should succeed."); + return fetchKeepAliveRequest(noDelay, expectedQuota /* bodySize */); + }, 'A Keep-Alive fetch() with a body at the Quota Limit should succeed.'); // Test Quota + 1 Byte promise_test(function(test) { - return promise_rejects(test, new TypeError(), fetch(CreateKeepAliveRequest(0 /* delay */, expectedQuota + 1))); - }, "A Keep-Alive fetch() with a body over the Quota Limit should reject."); + return promise_rejects(test, TypeError(), fetchKeepAliveRequest(noDelay, expectedQuota + 1)); + }, 'A Keep-Alive fetch() with a body over the Quota Limit should reject.'); // Test the Quota becomes available upon promise completion. promise_test(function (test) { // Fill our Quota then try to send a second fetch. - var firstFetch = fetch(CreateKeepAliveRequest(standardDelay, expectedQuota)).then(function(response) { + return fetchKeepAliveRequest(standardDelay, expectedQuota).then(() => { // Now validate that we can send another Keep-Alive fetch for the full size of the quota. - return fetch(CreateKeepAliveRequest(0 /* delay */, expectedQuota)); + return fetchKeepAliveRequest(noDelay, expectedQuota); }); - - return firstFetch; - }, "A Keep-Alive fetch() should return it's allocated Quota upon promise resolution."); + }, 'A Keep-Alive fetch() should return its allocated Quota upon promise resolution.'); // Ensure only the correct amount of Quota becomes available when a fetch completes. promise_test(function(test) { - var lastFetchSucceeded = false; // Create a fetch that uses all but 1 Byte of the Quota and runs for 2x as long as the other requests. - var firstFetch = fetch(CreateKeepAliveRequest(standardDelay * 2, expectedQuota - 1)).then(function(response) { - // This should be our last completing fetch(). We need to validate that the last fetch we sent out actually - // completed. - assert_true(lastFetchSucceeded, "Out last fetch after gaining Quota back should have succeeded."); - }); + const first = fetchKeepAliveRequest(standardDelay * 2, expectedQuota - 1); // Now create a single Byte request that will complete quicker. - fetch(CreateKeepAliveRequest(standardDelay, 1 /* bodySize */)).then(function(response) { + const second = fetchKeepAliveRequest(standardDelay, 1 /* bodySize */).then(() => { // We shouldn't be able to create a 2 Byte request right now as only 1 Byte should have freed up. - assert_throws(new TypeError(), fetch(CreateKeepAliveRequest(0 /* delay */, 2 /* bodySize */)), "Only 1 Byte of Quota should be available right now."); - + return promise_rejects(test, TypeError(), fetchKeepAliveRequest(noDelay, 2 /* bodySize */)); + }).then(() => { // Now validate that we can send another Keep-Alive fetch for just 1 Byte. - fetch(CreateKeepAliveRequest(0 /* delay */, 1 /* bodySize */)).then(function(response) { - // Flag we got a response from this request. - lastFetchSucceeded = true; - }); + return fetchKeepAliveRequest(noDelay, 1 /* bodySize */); }); - return firstFetch; - }, "A Keep-Alive fetch() should return only it's allocated Quota upon promise resolution."); + return Promise.all([first, second]); + }, 'A Keep-Alive fetch() should return only its allocated Quota upon promise resolution.'); // Test rejecting a fetch() after the quota is used up. promise_test(function (test) { // Fill our Quota then try to send a second fetch. - fetch(CreateKeepAliveRequest(standardDelay, expectedQuota)); + const p = fetchKeepAliveRequest(standardDelay, expectedQuota); - return promise_rejects(test, new TypeError(), fetch(CreateKeepAliveRequest(0 /* delay */, 1 /* bodySize */))); - }, "A Keep-Alive fetch() should not be allowed if the Quota is used up."); + const q = promise_rejects(test, TypeError(), fetchKeepAliveRequest(noDelay, 1 /* bodySize */)); + return Promise.all([p, q]); + }, 'A Keep-Alive fetch() should not be allowed if the Quota is used up.'); </script> </body> diff --git a/tests/wpt/web-platform-tests/fetch/api/resources/trickle.py b/tests/wpt/web-platform-tests/fetch/api/resources/trickle.py index 0e709445c59..319ecd21f45 100644 --- a/tests/wpt/web-platform-tests/fetch/api/resources/trickle.py +++ b/tests/wpt/web-platform-tests/fetch/api/resources/trickle.py @@ -3,6 +3,8 @@ import time def main(request, response): delay = float(request.GET.first("ms", 500)) / 1E3 count = int(request.GET.first("count", 50)) + # Read request body + request.body time.sleep(delay) response.headers.set("Content-type", "text/plain") response.write_status_headers() diff --git a/tests/wpt/web-platform-tests/fetch/api/response/response-idl.html b/tests/wpt/web-platform-tests/fetch/api/response/response-idl.html index 3bbf54e6f3c..bd265fa203d 100644 --- a/tests/wpt/web-platform-tests/fetch/api/response/response-idl.html +++ b/tests/wpt/web-platform-tests/fetch/api/response/response-idl.html @@ -15,9 +15,7 @@ typedef any JSON; typedef (Blob or BufferSource or FormData or URLSearchParams or USVString) BodyInit; - [NoInterfaceObject, - Exposed=(Window,Worker)] - interface Body { + interface mixin Body { readonly attribute ReadableStream? body; readonly attribute boolean bodyUsed; [NewObject] Promise<ArrayBuffer> arrayBuffer(); @@ -45,7 +43,7 @@ [NewObject] Response clone(); }; - Response implements Body; + Response includes Body; dictionary ResponseInit { unsigned short status = 200; |