diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 6e2c6ea3431..da115865086 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -13583,6 +13583,10 @@ "path": "cssom-view/elementsFromPoint.html", "url": "/cssom-view/elementsFromPoint.html" }, + { + "path": "cssom-view/scrollingElement.html", + "url": "/cssom-view/scrollingElement.html" + }, { "path": "custom-elements/concepts/custom-elements-type-naming.html", "url": "/custom-elements/concepts/custom-elements-type-naming.html" @@ -15119,6 +15123,366 @@ "path": "ext-xhtml-pubid/the-xhtml-syntax/parsing-xhtml-documents/xhtml-pubid-1.html", "url": "/ext-xhtml-pubid/the-xhtml-syntax/parsing-xhtml-documents/xhtml-pubid-1.html" }, + { + "path": "fetch/api/basic/accept-header-worker.html", + "url": "/fetch/api/basic/accept-header-worker.html" + }, + { + "path": "fetch/api/basic/accept-header.html", + "url": "/fetch/api/basic/accept-header.html" + }, + { + "path": "fetch/api/basic/integrity-worker.html", + "url": "/fetch/api/basic/integrity-worker.html" + }, + { + "path": "fetch/api/basic/integrity.html", + "url": "/fetch/api/basic/integrity.html" + }, + { + "path": "fetch/api/basic/mode-no-cors-worker.html", + "url": "/fetch/api/basic/mode-no-cors-worker.html" + }, + { + "path": "fetch/api/basic/mode-no-cors.html", + "url": "/fetch/api/basic/mode-no-cors.html" + }, + { + "path": "fetch/api/basic/mode-same-origin-worker.html", + "url": "/fetch/api/basic/mode-same-origin-worker.html" + }, + { + "path": "fetch/api/basic/mode-same-origin.html", + "url": "/fetch/api/basic/mode-same-origin.html" + }, + { + "path": "fetch/api/basic/request-forbidden-headers-worker.html", + "url": "/fetch/api/basic/request-forbidden-headers-worker.html" + }, + { + "path": "fetch/api/basic/request-forbidden-headers.html", + "url": "/fetch/api/basic/request-forbidden-headers.html" + }, + { + "path": "fetch/api/basic/request-headers-worker.html", + "url": "/fetch/api/basic/request-headers-worker.html" + }, + { + "path": "fetch/api/basic/request-headers.html", + "url": "/fetch/api/basic/request-headers.html" + }, + { + "path": "fetch/api/basic/scheme-about-worker.html", + "url": "/fetch/api/basic/scheme-about-worker.html" + }, + { + "path": "fetch/api/basic/scheme-about.html", + "url": "/fetch/api/basic/scheme-about.html" + }, + { + "path": "fetch/api/basic/scheme-blob-worker.html", + "url": "/fetch/api/basic/scheme-blob-worker.html" + }, + { + "path": "fetch/api/basic/scheme-blob.html", + "url": "/fetch/api/basic/scheme-blob.html" + }, + { + "path": "fetch/api/basic/scheme-data-worker.html", + "url": "/fetch/api/basic/scheme-data-worker.html" + }, + { + "path": "fetch/api/basic/scheme-data.html", + "url": "/fetch/api/basic/scheme-data.html" + }, + { + "path": "fetch/api/basic/scheme-others-worker.html", + "url": "/fetch/api/basic/scheme-others-worker.html" + }, + { + "path": "fetch/api/basic/scheme-others.html", + "url": "/fetch/api/basic/scheme-others.html" + }, + { + "path": "fetch/api/basic/stream-response-worker.html", + "url": "/fetch/api/basic/stream-response-worker.html" + }, + { + "path": "fetch/api/basic/stream-response.html", + "url": "/fetch/api/basic/stream-response.html" + }, + { + "path": "fetch/api/cors/cors-basic-worker.html", + "url": "/fetch/api/cors/cors-basic-worker.html" + }, + { + "path": "fetch/api/cors/cors-basic.html", + "url": "/fetch/api/cors/cors-basic.html" + }, + { + "path": "fetch/api/cors/cors-cookies-worker.html", + "url": "/fetch/api/cors/cors-cookies-worker.html" + }, + { + "path": "fetch/api/cors/cors-cookies.html", + "url": "/fetch/api/cors/cors-cookies.html" + }, + { + "path": "fetch/api/cors/cors-filtering-worker.html", + "url": "/fetch/api/cors/cors-filtering-worker.html" + }, + { + "path": "fetch/api/cors/cors-filtering.html", + "url": "/fetch/api/cors/cors-filtering.html" + }, + { + "path": "fetch/api/cors/cors-multiple-origins-worker.html", + "url": "/fetch/api/cors/cors-multiple-origins-worker.html" + }, + { + "path": "fetch/api/cors/cors-multiple-origins.html", + "url": "/fetch/api/cors/cors-multiple-origins.html" + }, + { + "path": "fetch/api/cors/cors-no-preflight-worker.html", + "url": "/fetch/api/cors/cors-no-preflight-worker.html" + }, + { + "path": "fetch/api/cors/cors-no-preflight.html", + "url": "/fetch/api/cors/cors-no-preflight.html" + }, + { + "path": "fetch/api/cors/cors-origin-worker.html", + "url": "/fetch/api/cors/cors-origin-worker.html" + }, + { + "path": "fetch/api/cors/cors-origin.html", + "url": "/fetch/api/cors/cors-origin.html" + }, + { + "path": "fetch/api/cors/cors-preflight-redirect-worker.html", + "url": "/fetch/api/cors/cors-preflight-redirect-worker.html" + }, + { + "path": "fetch/api/cors/cors-preflight-redirect.html", + "url": "/fetch/api/cors/cors-preflight-redirect.html" + }, + { + "path": "fetch/api/cors/cors-preflight-referrer-worker.html", + "url": "/fetch/api/cors/cors-preflight-referrer-worker.html" + }, + { + "path": "fetch/api/cors/cors-preflight-referrer.html", + "url": "/fetch/api/cors/cors-preflight-referrer.html" + }, + { + "path": "fetch/api/cors/cors-preflight-status-worker.html", + "url": "/fetch/api/cors/cors-preflight-status-worker.html" + }, + { + "path": "fetch/api/cors/cors-preflight-status.html", + "url": "/fetch/api/cors/cors-preflight-status.html" + }, + { + "path": "fetch/api/cors/cors-preflight-worker.html", + "url": "/fetch/api/cors/cors-preflight-worker.html" + }, + { + "path": "fetch/api/cors/cors-preflight.html", + "url": "/fetch/api/cors/cors-preflight.html" + }, + { + "path": "fetch/api/cors/cors-redirect-credentials-worker.html", + "url": "/fetch/api/cors/cors-redirect-credentials-worker.html" + }, + { + "path": "fetch/api/cors/cors-redirect-credentials.html", + "url": "/fetch/api/cors/cors-redirect-credentials.html" + }, + { + "path": "fetch/api/cors/cors-redirect-worker.html", + "url": "/fetch/api/cors/cors-redirect-worker.html" + }, + { + "path": "fetch/api/cors/cors-redirect.html", + "url": "/fetch/api/cors/cors-redirect.html" + }, + { + "path": "fetch/api/credentials/authentication-basic-worker.html", + "url": "/fetch/api/credentials/authentication-basic-worker.html" + }, + { + "path": "fetch/api/credentials/authentication-basic.html", + "url": "/fetch/api/credentials/authentication-basic.html" + }, + { + "path": "fetch/api/credentials/cookies-worker.html", + "url": "/fetch/api/credentials/cookies-worker.html" + }, + { + "path": "fetch/api/credentials/cookies.html", + "url": "/fetch/api/credentials/cookies.html" + }, + { + "path": "fetch/api/headers/headers-basic.html", + "url": "/fetch/api/headers/headers-basic.html" + }, + { + "path": "fetch/api/headers/headers-casing.html", + "url": "/fetch/api/headers/headers-casing.html" + }, + { + "path": "fetch/api/headers/headers-combine.html", + "url": "/fetch/api/headers/headers-combine.html" + }, + { + "path": "fetch/api/headers/headers-errors.html", + "url": "/fetch/api/headers/headers-errors.html" + }, + { + "path": "fetch/api/headers/headers-idl.html", + "url": "/fetch/api/headers/headers-idl.html" + }, + { + "path": "fetch/api/headers/headers-normalize.html", + "url": "/fetch/api/headers/headers-normalize.html" + }, + { + "path": "fetch/api/headers/headers-structure.html", + "url": "/fetch/api/headers/headers-structure.html" + }, + { + "path": "fetch/api/policies/csp-blocked-worker.html", + "url": "/fetch/api/policies/csp-blocked-worker.html" + }, + { + "path": "fetch/api/policies/csp-blocked.html", + "url": "/fetch/api/policies/csp-blocked.html" + }, + { + "path": "fetch/api/policies/referrer-no-referrer-worker.html", + "url": "/fetch/api/policies/referrer-no-referrer-worker.html" + }, + { + "path": "fetch/api/policies/referrer-no-referrer.html", + "url": "/fetch/api/policies/referrer-no-referrer.html" + }, + { + "path": "fetch/api/policies/referrer-origin-worker.html", + "url": "/fetch/api/policies/referrer-origin-worker.html" + }, + { + "path": "fetch/api/policies/referrer-origin.html", + "url": "/fetch/api/policies/referrer-origin.html" + }, + { + "path": "fetch/api/policies/referrer-unsafe-url-worker.html", + "url": "/fetch/api/policies/referrer-unsafe-url-worker.html" + }, + { + "path": "fetch/api/policies/referrer-unsafe-url.html", + "url": "/fetch/api/policies/referrer-unsafe-url.html" + }, + { + "path": "fetch/api/redirect/redirect-count-worker.html", + "url": "/fetch/api/redirect/redirect-count-worker.html" + }, + { + "path": "fetch/api/redirect/redirect-count.html", + "url": "/fetch/api/redirect/redirect-count.html" + }, + { + "path": "fetch/api/redirect/redirect-location-worker.html", + "url": "/fetch/api/redirect/redirect-location-worker.html" + }, + { + "path": "fetch/api/redirect/redirect-location.html", + "url": "/fetch/api/redirect/redirect-location.html" + }, + { + "path": "fetch/api/redirect/redirect-method-worker.html", + "url": "/fetch/api/redirect/redirect-method-worker.html" + }, + { + "path": "fetch/api/redirect/redirect-method.html", + "url": "/fetch/api/redirect/redirect-method.html" + }, + { + "path": "fetch/api/redirect/redirect-mode-worker.html", + "url": "/fetch/api/redirect/redirect-mode-worker.html" + }, + { + "path": "fetch/api/redirect/redirect-mode.html", + "url": "/fetch/api/redirect/redirect-mode.html" + }, + { + "path": "fetch/api/request/request-clone.sub.html", + "url": "/fetch/api/request/request-clone.sub.html" + }, + { + "path": "fetch/api/request/request-consume.html", + "url": "/fetch/api/request/request-consume.html" + }, + { + "path": "fetch/api/request/request-disturbed.html", + "url": "/fetch/api/request/request-disturbed.html" + }, + { + "path": "fetch/api/request/request-error.html", + "url": "/fetch/api/request/request-error.html" + }, + { + "path": "fetch/api/request/request-idl.html", + "url": "/fetch/api/request/request-idl.html" + }, + { + "path": "fetch/api/request/request-init-001.sub.html", + "url": "/fetch/api/request/request-init-001.sub.html" + }, + { + "path": "fetch/api/request/request-init-002.html", + "url": "/fetch/api/request/request-init-002.html" + }, + { + "path": "fetch/api/request/request-init-003.sub.html", + "url": "/fetch/api/request/request-init-003.sub.html" + }, + { + "path": "fetch/api/request/request-structure.html", + "url": "/fetch/api/request/request-structure.html" + }, + { + "path": "fetch/api/response/response-clone.html", + "url": "/fetch/api/response/response-clone.html" + }, + { + "path": "fetch/api/response/response-consume.html", + "url": "/fetch/api/response/response-consume.html" + }, + { + "path": "fetch/api/response/response-error.html", + "url": "/fetch/api/response/response-error.html" + }, + { + "path": "fetch/api/response/response-idl.html", + "url": "/fetch/api/response/response-idl.html" + }, + { + "path": "fetch/api/response/response-init-001.html", + "url": "/fetch/api/response/response-init-001.html" + }, + { + "path": "fetch/api/response/response-init-002.html", + "url": "/fetch/api/response/response-init-002.html" + }, + { + "path": "fetch/api/response/response-static-error.html", + "url": "/fetch/api/response/response-static-error.html" + }, + { + "path": "fetch/api/response/response-static-redirect.html", + "url": "/fetch/api/response/response-static-redirect.html" + }, { "path": "fetch/nosniff/image.html", "url": "/fetch/nosniff/image.html" @@ -15691,6 +16055,10 @@ "path": "html/browsers/history/the-location-interface/location_href.html", "url": "/html/browsers/history/the-location-interface/location_href.html" }, + { + "path": "html/browsers/history/the-location-interface/location_origin.html", + "url": "/html/browsers/history/the-location-interface/location_origin.html" + }, { "path": "html/browsers/history/the-location-interface/location_pathname.html", "url": "/html/browsers/history/the-location-interface/location_pathname.html" @@ -18063,6 +18431,10 @@ "path": "html/semantics/embedded-content/the-embed-element/embed-dimension.html", "url": "/html/semantics/embedded-content/the-embed-element/embed-dimension.html" }, + { + "path": "html/semantics/embedded-content/the-embed-element/embed-document.html", + "url": "/html/semantics/embedded-content/the-embed-element/embed-document.html" + }, { "path": "html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm", "url": "/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm" @@ -20867,10 +21239,6 @@ "path": "old-tests/submission/Microsoft/sandbox/sandbox_001.htm", "url": "/old-tests/submission/Microsoft/sandbox/sandbox_001.htm" }, - { - "path": "old-tests/submission/Microsoft/sandbox/sandbox_002.htm", - "url": "/old-tests/submission/Microsoft/sandbox/sandbox_002.htm" - }, { "path": "old-tests/submission/Microsoft/sandbox/sandbox_005.htm", "url": "/old-tests/submission/Microsoft/sandbox/sandbox_005.htm" @@ -30287,6 +30655,10 @@ "path": "websockets/Create-Secure-verify-url-set-non-default-port.htm", "url": "/websockets/Create-Secure-verify-url-set-non-default-port.htm" }, + { + "path": "websockets/Create-asciiSep-protocol-string.htm", + "url": "/websockets/Create-asciiSep-protocol-string.htm" + }, { "path": "websockets/Create-invalid-urls.htm", "url": "/websockets/Create-invalid-urls.htm" @@ -30303,6 +30675,10 @@ "path": "websockets/Create-protocol-with-space.htm", "url": "/websockets/Create-protocol-with-space.htm" }, + { + "path": "websockets/Create-protocols-repeated-case-insensitive.htm", + "url": "/websockets/Create-protocols-repeated-case-insensitive.htm" + }, { "path": "websockets/Create-protocols-repeated.htm", "url": "/websockets/Create-protocols-repeated.htm" @@ -33017,6 +33393,11 @@ "timeout": "long", "url": "/media-source/mediasource-redundant-seek.html" }, + { + "path": "old-tests/submission/Microsoft/sandbox/sandbox_002.htm", + "timeout": "long", + "url": "/old-tests/submission/Microsoft/sandbox/sandbox_002.htm" + }, { "path": "quirks-mode/hashless-hex-color.html", "timeout": "long", @@ -33332,22 +33713,7 @@ }, "local_changes": { "deleted": [], - "items": { - "testharness": { - "cssom-view/scrollingElement.html": [ - { - "path": "cssom-view/scrollingElement.html", - "url": "/cssom-view/scrollingElement.html" - } - ], - "html/semantics/embedded-content/the-embed-element/embed-document.html": [ - { - "path": "html/semantics/embedded-content/the-embed-element/embed-document.html", - "url": "/html/semantics/embedded-content/the-embed-element/embed-document.html" - } - ] - } - }, + "items": {}, "reftest_nodes": {} }, "reftest_nodes": { @@ -39460,7 +39826,7 @@ } ] }, - "rev": "c41adf030ec80a62ef9e1988d3c4be460f2a0012", + "rev": "f3f87e1a2cc3845819038a8a6fe435bb6092e213", "url_base": "/", "version": 2 } diff --git a/testing/web-platform/meta/mozilla-sync b/testing/web-platform/meta/mozilla-sync index aa790901d5a..269ca479cd1 100644 --- a/testing/web-platform/meta/mozilla-sync +++ b/testing/web-platform/meta/mozilla-sync @@ -1 +1 @@ -82103213aaab9f39b722547a39be0de377dd9242 \ No newline at end of file +a035c3724da7e8235c26a3b6ea567365efda3b15 \ No newline at end of file diff --git a/testing/web-platform/tests/battery-status/OWNERS b/testing/web-platform/tests/battery-status/OWNERS new file mode 100644 index 00000000000..eb86aa06933 --- /dev/null +++ b/testing/web-platform/tests/battery-status/OWNERS @@ -0,0 +1,3 @@ +@anssiko +@dontcallmedom +@zqzhang diff --git a/testing/web-platform/tests/dom/nodes/attributes.html b/testing/web-platform/tests/dom/nodes/attributes.html index e331389ff85..76a501c37ca 100644 --- a/testing/web-platform/tests/dom/nodes/attributes.html +++ b/testing/web-platform/tests/dom/nodes/attributes.html @@ -446,6 +446,26 @@ test(function() { assert_equals(el2.getAttributeNS("x", "foo"), "bar"); }, "Basic functionality of setAttributeNodeNS") +test(function() { + var el = document.createElement("div"); + var other = document.createElement("div"); + attr = document.createAttribute("foo"); + assert_equals(el.setAttributeNode(attr), null); + assert_equals(attr.ownerElement, el); + assert_throws("INUSE_ATTRIBUTE_ERR", + function() { other.setAttributeNode(attr) }, + "Attribute already associated with el") +}, "If attr’s element is neither null nor element, throw an InUseAttributeError."); + +test(function() { + var el = document.createElement("div"); + attr = document.createAttribute("foo"); + assert_equals(el.setAttributeNode(attr), null); + el.setAttribute("bar", "qux"); + assert_equals(el.setAttributeNode(attr), attr); + assert_equals(el.attributes[0], attr); +}, "Replacing an attr by itself"); + test(function() { var el = document.createElement("div") el.setAttribute("foo", "bar") diff --git a/testing/web-platform/tests/fetch/api/basic/accept-header-worker.html b/testing/web-platform/tests/fetch/api/basic/accept-header-worker.html new file mode 100644 index 00000000000..4d5b3220580 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/accept-header-worker.html @@ -0,0 +1,16 @@ + + + + + Fetch in worker: accept header + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/accept-header.html b/testing/web-platform/tests/fetch/api/basic/accept-header.html new file mode 100644 index 00000000000..cd9550fb2cc --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/accept-header.html @@ -0,0 +1,15 @@ + + + + + Fetch: accept header + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/accept-header.js b/testing/web-platform/tests/fetch/api/basic/accept-header.js new file mode 100644 index 00000000000..33226e8562a --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/accept-header.js @@ -0,0 +1,14 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +promise_test(function() { + return fetch(RESOURCES_DIR + "inspect-headers.py?headers=Accept").then(function(response) { + assert_equals(response.status, 200, "HTTP status is 200"); + assert_equals(response.type , "basic", "Response's type is basic"); + assert_equals(response.headers.get("x-request-accept"), "*/*", "Request has accept header with value '*/*'"); + }); +}, "Request through fetch should have 'accept' header with value '*/*'"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/basic/integrity-worker.html b/testing/web-platform/tests/fetch/api/basic/integrity-worker.html new file mode 100644 index 00000000000..9240bc6325a --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/integrity-worker.html @@ -0,0 +1,16 @@ + + + + + Fetch in worker: integrity handling + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/integrity.html b/testing/web-platform/tests/fetch/api/basic/integrity.html new file mode 100644 index 00000000000..150c9b71d54 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/integrity.html @@ -0,0 +1,15 @@ + + + + + Fetch: integrity handling + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/integrity.js b/testing/web-platform/tests/fetch/api/basic/integrity.js new file mode 100644 index 00000000000..4e849f564e1 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/integrity.js @@ -0,0 +1,45 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function integrity(desc, url, integrity, shouldPass) { + if (shouldPass) { + promise_test(function(test) { + return fetch(url, {'integrity': integrity}).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + }); + }, desc); + } else { + promise_test(function(test) { + return promise_rejects(test, new TypeError(), fetch(url, {'integrity': integrity})); + }, desc); + } +} + +var topSha256 = "sha256-KHIDZcXnR2oBHk9DrAA+5fFiR6JjudYjqoXtMR1zvzk="; +var topSha384 = "sha384-MgZYnnAzPM/MjhqfOIMfQK5qcFvGZsGLzx4Phd7/A8fHTqqLqXqKo8cNzY3xEPTL"; +var topSha512 = "sha512-D6yns0qxG0E7+TwkevZ4Jt5t7Iy3ugmAajG/dlf6Pado1JqTyneKXICDiqFIkLMRExgtvg8PlxbKTkYfRejSOg=="; +var invalidSha256 = "sha256-dKUcPOn/AlUjWIwcHeHNqYXPlvyGiq+2dWOdFcE+24I="; +var invalidSha512 = "sha512-oUceBRNxPxnY60g/VtPCj2syT4wo4EZh2CgYdWy9veW8+OsReTXoh7dizMGZafvx9+QhMS39L/gIkxnPIn41Zg=="; + +var url = "../resources/top.txt"; +var corsUrl = "http://www1.{{host}}:{{ports[http][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "top.txt"; +/* Enable CORS*/ +corsUrl += "?pipe=header(Access-Control-Allow-Origin,*)"; + +integrity("Empty string integrity", url, "", true); +integrity("SHA-256 integrity", url, topSha256, true); +integrity("SHA-384 integrity", url, topSha384, true); +integrity("SHA-512 integrity", url, topSha512, true); +integrity("Invalid integrity", url, invalidSha256, false); +integrity("Multiple integrities: valid stronger than invalid", url, invalidSha256 + " " + topSha384, true); +integrity("Multiple integrities: invalid stronger than valid", url, invalidSha512 + " " + topSha384, false); +integrity("Multiple integrities: invalid as strong as valid", url, invalidSha512 + " " + topSha512, true); +integrity("Multiple integrities: both are valid", url, topSha384 + " " + topSha512, true); +integrity("Multiple integrities: both are invalid", url, invalidSha256 + " " + invalidSha512, false); +integrity("CORS empty integrity", corsUrl, "", true); +integrity("CORS SHA-512 integrity", corsUrl, topSha512, true); +integrity("CORS invalid integrity", corsUrl, invalidSha512, false); + +done(); diff --git a/testing/web-platform/tests/fetch/api/basic/mode-no-cors-worker.html b/testing/web-platform/tests/fetch/api/basic/mode-no-cors-worker.html new file mode 100644 index 00000000000..87376a130f8 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/mode-no-cors-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: no-cors mode and opaque filtering + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/mode-no-cors.html b/testing/web-platform/tests/fetch/api/basic/mode-no-cors.html new file mode 100644 index 00000000000..7aee3790933 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/mode-no-cors.html @@ -0,0 +1,16 @@ + + + + + Fetch: no-cors mode and opaque filtering + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/mode-no-cors.js b/testing/web-platform/tests/fetch/api/basic/mode-no-cors.js new file mode 100644 index 00000000000..27483654f74 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/mode-no-cors.js @@ -0,0 +1,31 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function fetchNoCors(url, isOpaqueFiltered) { + var urlQuery = "?pipe=header(x-is-filtered,value)" + promise_test(function(test) { + if (isOpaqueFiltered) + return fetch(url + urlQuery, {"mode": "no-cors"}).then(function(resp) { + assert_equals(resp.status, 0, "Opaque filter: status is 0"); + assert_equals(resp.statusText, "", "Opaque filter: statusText is \"\""); + assert_equals(resp.type , "opaque", "Opaque filter: response's type is opaque"); + assert_equals(resp.headers.get("x-is-filtered"), null, "Header x-is-filtered is filtered"); + }); + else + return fetch(url + urlQuery, {"mode": "no-cors"}).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type , "basic", "Response's type is basic"); + assert_equals(resp.headers.get("x-is-filtered"), "value", "Header x-is-filtered is not filtered"); + }); + }, "Fetch "+ url + " with no-cors mode"); +} + +fetchNoCors(RESOURCES_DIR + "top.txt", false); +fetchNoCors("http://{{host}}:{{ports[http][0]}}/fetch/api/resources/top.txt", false); +fetchNoCors("https://{{host}}:{{ports[https][0]}}/fetch/api/resources/top.txt", true); +fetchNoCors("http://{{domains[www]}}:{{ports[http][0]}}/fetch/api/resources/top.txt", true); + +done(); + diff --git a/testing/web-platform/tests/fetch/api/basic/mode-same-origin-worker.html b/testing/web-platform/tests/fetch/api/basic/mode-same-origin-worker.html new file mode 100644 index 00000000000..0c62472aaf1 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/mode-same-origin-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: same-origin mode + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/mode-same-origin.html b/testing/web-platform/tests/fetch/api/basic/mode-same-origin.html new file mode 100644 index 00000000000..d94832a2aa0 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/mode-same-origin.html @@ -0,0 +1,16 @@ + + + + + Fetch: same-origin mode + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/mode-same-origin.js b/testing/web-platform/tests/fetch/api/basic/mode-same-origin.js new file mode 100644 index 00000000000..c00d96fad32 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/mode-same-origin.js @@ -0,0 +1,24 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function fetchSameOrigin(url, shouldPass) { + promise_test(function(test) { + if (shouldPass) + return fetch(url , {"mode": "same-origin"}).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type, "basic", "response type is basic"); + }); + else + return promise_rejects(test, new TypeError, fetch(url, {mode: "same-origin"})); + }, "Fetch "+ url + " with same-origin mode"); +} + +fetchSameOrigin(RESOURCES_DIR + "top.txt", true); +fetchSameOrigin("http://{{host}}:{{ports[http][0]}}/fetch/api/resources/top.txt", true); +fetchSameOrigin("https://{{host}}:{{ports[https][0]}}/fetch/api/resources/top.txt", false); +fetchSameOrigin("http://{{domains[www]}}:{{ports[http][0]}}/fetch/api/resources/top.txt", false); + +done(); + diff --git a/testing/web-platform/tests/fetch/api/basic/request-forbidden-headers-worker.html b/testing/web-platform/tests/fetch/api/basic/request-forbidden-headers-worker.html new file mode 100644 index 00000000000..12e87f9e4c6 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/request-forbidden-headers-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: forbidden request header management + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/request-forbidden-headers.html b/testing/web-platform/tests/fetch/api/basic/request-forbidden-headers.html new file mode 100644 index 00000000000..56ce2a65b11 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/request-forbidden-headers.html @@ -0,0 +1,16 @@ + + + + + Fetch: forbidden request header management + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/request-forbidden-headers.js b/testing/web-platform/tests/fetch/api/basic/request-forbidden-headers.js new file mode 100644 index 00000000000..72a8392a54f --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/request-forbidden-headers.js @@ -0,0 +1,48 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function requestForbiddenHeaders(desc, forbiddenHeaders) { + var url = RESOURCES_DIR + "inspect-headers.py"; + var requestInit = {"headers": forbiddenHeaders} + var urlParameters = "?headers=" + Object.keys(forbiddenHeaders).join("|"); + + promise_test(function(test){ + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type , "basic", "Response's type is basic"); + for (var header in forbiddenHeaders) + assert_not_equals(resp.headers.get("x-request-" + header), forbiddenHeaders[header], header + " does not have the value we defined"); + }); + }, desc); +} + +requestForbiddenHeaders("Accept-Charset is a forbidden request header", {"Accept-Charset": "utf-8"}); +requestForbiddenHeaders("Accept-Encoding is a forbidden request header", {"Accept-Encoding": ""}); + +requestForbiddenHeaders("Access-Control-Request-Headers is a forbidden request header", {"Access-Control-Request-Headers": ""}); +requestForbiddenHeaders("Access-Control-Request-Method is a forbidden request header", {"Access-Control-Request-Method": ""}); +requestForbiddenHeaders("Connection is a forbidden request header", {"Connection": "close"}); +requestForbiddenHeaders("Content-Length is a forbidden request header", {"Content-Length": "42"}); +requestForbiddenHeaders("Cookie is a forbidden request header", {"Cookie": "cookie=none"}); +requestForbiddenHeaders("Cookie2 is a forbidden request header", {"Cookie2": "cookie2=none"}); +requestForbiddenHeaders("Date is a forbidden request header", {"Date": "Wed, 04 May 1988 22:22:22 GMT"}); +requestForbiddenHeaders("DNT is a forbidden request header", {"DNT": "4"}); +requestForbiddenHeaders("Expect is a forbidden request header", {"Expect": "100-continue"}); +requestForbiddenHeaders("Host is a forbidden request header", {"Host": "http://wrong-host.com"}); +requestForbiddenHeaders("Keep-Alive is a forbidden request header", {"Keep-Alive": "timeout=15"}); +requestForbiddenHeaders("Origin is a forbidden request header", {"Origin": "http://wrong-origin.com"}); +requestForbiddenHeaders("Referer is a forbidden request header", {"Referer": "http://wrong-referer.com"}); +requestForbiddenHeaders("TE is a forbidden request header", {"TE": "trailers"}); +requestForbiddenHeaders("Trailer is a forbidden request header", {"Trailer": "Accept"}); +requestForbiddenHeaders("Transfer-Encoding is a forbidden request header", {"Transfer-Encoding": "chunked"}); +requestForbiddenHeaders("Upgrade is a forbidden request header", {"Upgrade": "HTTP/2.0"}); +requestForbiddenHeaders("Via is a forbidden request header", {"Via": "1.1 nowhere.com"}); +requestForbiddenHeaders("Proxy- is a forbidden request header", {"Proxy-": "value"}); +requestForbiddenHeaders("Proxy-Test is a forbidden request header", {"Proxy-Test": "value"}); +requestForbiddenHeaders("Sec- is a forbidden request header", {"Sec-": "value"}); +requestForbiddenHeaders("Sec-Test is a forbidden request header", {"Sec-Test": "value"}); + +done(); + diff --git a/testing/web-platform/tests/fetch/api/basic/request-headers-worker.html b/testing/web-platform/tests/fetch/api/basic/request-headers-worker.html new file mode 100644 index 00000000000..85b4c4c7084 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/request-headers-worker.html @@ -0,0 +1,16 @@ + + + + + Fetch in worker: User agent add headers to request + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/request-headers.html b/testing/web-platform/tests/fetch/api/basic/request-headers.html new file mode 100644 index 00000000000..5236d29b107 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/request-headers.html @@ -0,0 +1,15 @@ + + + + + Fetch: User agent add headers to request + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/request-headers.js b/testing/web-platform/tests/fetch/api/basic/request-headers.js new file mode 100644 index 00000000000..ec14385b606 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/request-headers.js @@ -0,0 +1,35 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function requestHeaders(desc, url, method, body, expectedOrigin, expectedContentLength) { + var urlParameters = "?headers=origin|user-agent|accept-charset|content-length"; + var requestInit = {"method": method} + if (body) + requestInit["body"] = body; + promise_test(function(test){ + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type , "basic", "Response's type is basic"); + assert_equals(resp.headers.get("x-request-origin") , expectedOrigin, "Request has header origin: " + expectedOrigin); + assert_equals(resp.headers.get("x-request-content-length") , expectedContentLength, "Request has header content-length: " + expectedContentLength); + assert_true(resp.headers.has("x-request-user-agent"), "Request has header user-agent"); + assert_false(resp.headers.has("accept-charset"), "Request has header accept-charset"); + }); + }, desc); +} + +var url = RESOURCES_DIR + "inspect-headers.py" + +requestHeaders("Fetch with GET", url, "GET", null, location.origin, null); +requestHeaders("Fetch with HEAD", url, "HEAD", null, location.origin, "0"); +requestHeaders("Fetch with HEAD with body", url, "HEAD", "Request's body", location.origin, "14"); +requestHeaders("Fetch with PUT without body", url, "POST", null, location.origin, "0"); +requestHeaders("Fetch with PUT with body", url, "PUT", "Request's body", location.origin, "14"); +requestHeaders("Fetch with POST without body", url, "POST", null, location.origin, "0"); +requestHeaders("Fetch with POST with body", url, "POST", "Request's body", location.origin, "14"); +requestHeaders("Fetch with Chicken", url, "Chicken", null, location.origin, null); +requestHeaders("Fetch with Chicken with body", url, "Chicken", "Request's body", location.origin, "14"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-about-worker.html b/testing/web-platform/tests/fetch/api/basic/scheme-about-worker.html new file mode 100644 index 00000000000..9c9d9a038a9 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-about-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: about scheme + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-about.html b/testing/web-platform/tests/fetch/api/basic/scheme-about.html new file mode 100644 index 00000000000..8b6df24682f --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-about.html @@ -0,0 +1,16 @@ + + + + + Fetch: about scheme + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-about.js b/testing/web-platform/tests/fetch/api/basic/scheme-about.js new file mode 100644 index 00000000000..5f3e7cfd5c5 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-about.js @@ -0,0 +1,40 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +var unicorn = ''; + +function checkFetchResponse(url, data, mime, desc) { + if (!desc) { + var cut = (url.length >= 45) ? "[...]" : ""; + desc = "Fetching " + url.substring(0, 45) + cut + " is OK" + } + promise_test(function(test) { + return fetch(url).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type, "basic", "response type is basic"); + assert_equals(resp.headers.get("Content-Type"), mime, "Content-Type is " + resp.headers.get("Content-Type")); + return resp.text(); + }).then(function(bodyAsText) { + assert_equals(bodyAsText, data, "Response's body is " + data); + }) + }, desc); +} + +checkFetchResponse("about:blank", "", "text/html;charset=utf-8"); +checkFetchResponse("about:unicorn", unicorn, "image/svg+xml"); + +function checkKoUrl(url, desc) { + if (!desc) + desc = "Fetching " + url.substring(0, 45) + " is KO" + promise_test(function(test) { + var promise = fetch(url); + return promise_rejects(test, new TypeError(), promise); + }, desc); +} + +checkKoUrl("about:invalid.com"); +checkKoUrl("about:config"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-blob-worker.html b/testing/web-platform/tests/fetch/api/basic/scheme-blob-worker.html new file mode 100644 index 00000000000..961ecbd525b --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-blob-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: blob scheme + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-blob.html b/testing/web-platform/tests/fetch/api/basic/scheme-blob.html new file mode 100644 index 00000000000..7787c3710f6 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-blob.html @@ -0,0 +1,16 @@ + + + + + Fetch: blob scheme + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-blob.js b/testing/web-platform/tests/fetch/api/basic/scheme-blob.js new file mode 100644 index 00000000000..d9b804d4e58 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-blob.js @@ -0,0 +1,41 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function checkFetchResponse(url, data, mime, size, desc) { + if (!desc) + var cut = (url.length >= 45) ? "[...]" : ""; + desc = "Fetching " + url.substring(0, 45) + cut + " is OK" + promise_test(function(test) { + size = size.toString(); + return fetch(url).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type, "basic", "response type is basic"); + assert_equals(resp.headers.get("Content-Type"), mime, "Content-Type is " + resp.headers.get("Content-Type")); + assert_equals(resp.headers.get("Content-Length"), size, "Content-Length is " + resp.headers.get("Content-Length")); + return resp.text(); + }).then(function(bodyAsText) { + assert_equals(bodyAsText, data, "Response's body is " + data); + }) + }, desc); +} + +var blob = new Blob(["Blob's data"], { "type" : "text/plain" }); +checkFetchResponse(URL.createObjectURL(blob), "Blob's data", "text/plain", blob.size); + +function checkKoUrl(url, method, desc) { + if (!desc) + var cut = (url.length >= 45) ? "[...]" : ""; + desc = "Fetching [" + method + "] " + url.substring(0, 45) + cut + " is KO" + promise_test(function(test) { + var promise = fetch(url, {"method": method}); + return promise_rejects(test, new TypeError(), promise); + }, desc); +} + +var blob2 = new Blob(["Blob's data"], { "type" : "text/plain" }); +checkKoUrl("blob:http://{{domains[www]}}:{{ports[http][0]}}/", "GET"); +checkKoUrl(URL.createObjectURL(blob2), "POST"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-data-worker.html b/testing/web-platform/tests/fetch/api/basic/scheme-data-worker.html new file mode 100644 index 00000000000..42fc3f4a9c0 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-data-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: data scheme + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-data.html b/testing/web-platform/tests/fetch/api/basic/scheme-data.html new file mode 100644 index 00000000000..0b41991c9fc --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-data.html @@ -0,0 +1,16 @@ + + + + + Fetch: data scheme + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-data.js b/testing/web-platform/tests/fetch/api/basic/scheme-data.js new file mode 100644 index 00000000000..775466799cd --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-data.js @@ -0,0 +1,39 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function checkFetchResponse(url, data, mime) { + var cut = (url.length >= 40) ? "[...]" : ""; + desc = "Fetching " + url.substring(0, 40) + cut + " is OK" + promise_test(function(test) { + return fetch(url).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type, "basic", "response type is basic"); + assert_equals(resp.headers.get("Content-Type"), mime, "Content-Type is " + resp.headers.get("Content-Type")); + return resp.text(); + }).then(function(body) { + assert_equals(body, data, "Response's body is correct"); + }); + }, desc); +} + +checkFetchResponse("data:,response%27s%20body", "response's body", "text/plain;charset=US-ASCII"); +checkFetchResponse("data:text/plain;base64,cmVzcG9uc2UncyBib2R5", "response's body", "text/plain"); +checkFetchResponse("data:image/png;base64,cmVzcG9uc2UncyBib2R5", + "response's body", + "image/png"); + +function checkKoUrl(url, method, desc) { + var cut = (url.length >= 40) ? "[...]" : ""; + desc = "Fetching [" + method + "] " + url.substring(0, 45) + cut + " is KO" + promise_test(function(test) { + return promise_rejects(test, new TypeError(), fetch(url, {"method": method})); + }, desc); +} + +checkKoUrl("data:notAdataUrl.com", "GET"); +checkKoUrl("data:,response%27s%20body", "POST"); +checkKoUrl("data:,response%27s%20body", "HEAD"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-others-worker.html b/testing/web-platform/tests/fetch/api/basic/scheme-others-worker.html new file mode 100644 index 00000000000..397d9257b1b --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-others-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: urls with unsupported schemes + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-others.html b/testing/web-platform/tests/fetch/api/basic/scheme-others.html new file mode 100644 index 00000000000..dd37143b0f1 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-others.html @@ -0,0 +1,16 @@ + + + + + Fetch: urls with unsupported schemes + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/scheme-others.js b/testing/web-platform/tests/fetch/api/basic/scheme-others.js new file mode 100644 index 00000000000..ce02ec1340a --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/scheme-others.js @@ -0,0 +1,33 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function checkKoUrl(url, desc) { + if (!desc) + desc = "Fetching " + url.substring(0, 45) + " is KO" + promise_test(function(test) { + var promise = fetch(url); + return promise_rejects(test, new TypeError(), promise); + }, desc); +} + +var urlWithoutScheme = "://{{host}}:{{ports[http][0]}}/"; +checkKoUrl("aaa" + urlWithoutScheme); +checkKoUrl("cap" + urlWithoutScheme); +checkKoUrl("cid" + urlWithoutScheme); +checkKoUrl("dav" + urlWithoutScheme); +checkKoUrl("dict" + urlWithoutScheme); +checkKoUrl("dns" + urlWithoutScheme); +checkKoUrl("geo" + urlWithoutScheme); +checkKoUrl("im" + urlWithoutScheme); +checkKoUrl("imap" + urlWithoutScheme); +checkKoUrl("ipp" + urlWithoutScheme); +checkKoUrl("ldap" + urlWithoutScheme); +checkKoUrl("mailto" + urlWithoutScheme); +checkKoUrl("nfs" + urlWithoutScheme); +checkKoUrl("pop" + urlWithoutScheme); +checkKoUrl("rtsp" + urlWithoutScheme); +checkKoUrl("snmp" + urlWithoutScheme); + +done(); diff --git a/testing/web-platform/tests/fetch/api/basic/stream-response-worker.html b/testing/web-platform/tests/fetch/api/basic/stream-response-worker.html new file mode 100644 index 00000000000..0be1c0d13f1 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/stream-response-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: retrieve response's body progressively + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/stream-response.html b/testing/web-platform/tests/fetch/api/basic/stream-response.html new file mode 100644 index 00000000000..eb6b1415a1f --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/stream-response.html @@ -0,0 +1,16 @@ + + + + + Fetch: retrieve response's body progressively + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/basic/stream-response.js b/testing/web-platform/tests/fetch/api/basic/stream-response.js new file mode 100644 index 00000000000..ea370bc7cdf --- /dev/null +++ b/testing/web-platform/tests/fetch/api/basic/stream-response.js @@ -0,0 +1,37 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function streamBody(reader, test, count) { + return reader.read().then(function(data) { + if (!data.done && count < 2) { + count += 1; + return streamBody(reader, test, count); + } else { + test.step(function() { + assert_true(count >= 2, "Retrieve body progressively"); + test.done(); + return; + }); + } + }); +} + +//simulate streaming: +//count is large enough to let the UA deliver the body before it is completely retrieved +async_test(function(test) { + fetch(RESOURCES_DIR + "trickle.py?ms=30&count=100").then(function(resp) { + var count = 0; + if (resp.body) + return streamBody(resp.body.getReader(), test, count); + else + test.step(function() { + assert_unreached( "Body does not exist in response"); + test.done(); + return; + }); + }); +}, "Stream response's body"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-basic-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-basic-worker.html new file mode 100644 index 00000000000..97e173c1522 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-basic-worker.html @@ -0,0 +1,19 @@ + + + + + Fetch in worker: basic CORS + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-basic.html b/testing/web-platform/tests/fetch/api/cors/cors-basic.html new file mode 100644 index 00000000000..4aa38f75b85 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-basic.html @@ -0,0 +1,18 @@ + + + + + Fetch: basic CORS + + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-basic.js b/testing/web-platform/tests/fetch/api/cors/cors-basic.js new file mode 100644 index 00000000000..3fe4644db14 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-basic.js @@ -0,0 +1,45 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function cors(desc, scheme, subdomain, port) { + if (!port) + port = location.port; + if (subdomain) + subdomain = subdomain + "."; + else + subdomain = ""; + + var url = scheme + "://" + subdomain + "{{host}}" + ":" + port + dirname(location.pathname); + var urlParameters = "?pipe=header(Access-Control-Allow-Origin,*)"; + + promise_test(function(test) { + return fetch(url + RESOURCES_DIR + "top.txt" + urlParameters, {"mode": "no-cors"} ).then(function(resp) { + assert_equals(resp.status, 0, "Opaque filter: status is 0"); + assert_equals(resp.statusText, "", "Opaque filter: statusText is \"\""); + assert_equals(resp.type , "opaque", "Opaque filter: response's type is opaque"); + }); + }, desc + " [no-cors mode]"); + + promise_test(function(test) { + var testedPromise = fetch(url + RESOURCES_DIR + "top.txt", {"mode": "cors"} ).then(function(resp) { + return promise_rejects(test, new TypeError(), testedPromise); + }); + }, desc + " [server forbid CORS]"); + + promise_test(function(test) { + return fetch(url + RESOURCES_DIR + "top.txt" + urlParameters, {"mode": "cors"} ).then(function(resp) { + assert_equals(resp.status, 200, "Fetch's response's status is 200"); + assert_equals(resp.type , "cors", "CORS response's type is cors"); + }); + }, desc + " [cors mode]"); +} + +cors("Cross domain basic usage", "http", "www1"); +cors("Same domain different port", "http", undefined, "{{ports[http][1]}}"); +cors("Cross domain different port", "http", "www1", "{{ports[http][1]}}"); +cors("Cross domain different protocol", "https", "www1", "{{ports[https][0]}}"); +cors("Same domain different protocol different port", "https", undefined, "{{ports[https][0]}}"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-cookies-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-cookies-worker.html new file mode 100644 index 00000000000..fd79aad8f05 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-cookies-worker.html @@ -0,0 +1,18 @@ + + + + + Fetch in worker: cookies management for cors requests + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-cookies.html b/testing/web-platform/tests/fetch/api/cors/cors-cookies.html new file mode 100644 index 00000000000..8fb6a7c0cd7 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-cookies.html @@ -0,0 +1,17 @@ + + + + + Fetch: cookies management for cors requests + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-cookies.js b/testing/web-platform/tests/fetch/api/cors/cors-cookies.js new file mode 100644 index 00000000000..d79dc84860d --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-cookies.js @@ -0,0 +1,58 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function corsCookies(desc, domain1, domain2, credentialsMode, cookies) { + var urlSetCookie = "http://" + domain1 + ":{{ports[http][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "top.txt"; + var urlCheckCookies = "http://" + domain2 + ":{{ports[http][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "inspect-headers.py?cors&headers=cookie"; + //enable cors with credentials + var urlParameters = "?pipe=header(Access-Control-Allow-Origin," + location.origin + ")"; + urlParameters += "|header(Access-Control-Allow-Credentials,true)"; + + var urlCleanParameters = "?pipe=header(Access-Control-Allow-Origin," + location.origin + ")"; + urlCleanParameters += "|header(Access-Control-Allow-Credentials,true)"; + if (cookies) { + urlParameters += "|header(Set-Cookie,"; + urlParameters += cookies.join(",True)|header(Set-Cookie,") + ",True)"; + urlCleanParameters += "|header(Set-Cookie,"; + urlCleanParameters += cookies.join("%3B%20max-age=0,True)|header(Set-Cookie,") + "%3B%20max-age=0,True)"; + } + + var requestInit = {"credentials": credentialsMode, "mode": "cors"}; + + promise_test(function(test){ + return fetch(urlSetCookie + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + //check cookies sent + return fetch(urlCheckCookies, requestInit); + }).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_false(resp.headers.has("Cookie") , "Cookie header is not exposed in response"); + if (credentialsMode === "include" && domain1 === domain2) { + assert_equals(resp.headers.get("x-request-cookie") , cookies.join("; "), "Request includes cookie(s)"); + } + else { + assert_false(resp.headers.has("x-request-cookie") , "Request should have no cookie"); + } + //clean cookies + return fetch(urlSetCookie + urlCleanParameters, {"credentials": "include"}); + }).catch(function(e) { + fetch(urlSetCookie + urlCleanParameters, {"credentials": "include"}); + throw e; + }); + }, desc); +} + +var local = "{{host}}"; +var remote = "www.{{host}}"; +var remote1 = "www1.{{host}}"; + +corsCookies("Include mode: 1 cookie", remote, remote, "include", ["a=1"]); +corsCookies("Include mode: local cookies are not sent with remote request", local, remote, "include", ["c=3"]); +corsCookies("Include mode: remote cookies are not sent with local request", remote, local, "include", ["d=4"]); +corsCookies("Include mode: remote cookies are not sent with other remote request", remote, remote1, "include", ["e=5"]); +corsCookies("Same-origin mode: cookies are discarded in cors request", remote, remote, "same-origin", ["f=6"]); +corsCookies("Omit mode: no cookie sent", local, local, "omit", ["g=7"]); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-filtering-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-filtering-worker.html new file mode 100644 index 00000000000..f15566fc509 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-filtering-worker.html @@ -0,0 +1,18 @@ + + + + + Fetch in worker: filtered headers in CORS response + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-filtering.html b/testing/web-platform/tests/fetch/api/cors/cors-filtering.html new file mode 100644 index 00000000000..b7500ad16d4 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-filtering.html @@ -0,0 +1,17 @@ + + + + + Fetch: filtered headers in CORS response + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-filtering.js b/testing/web-platform/tests/fetch/api/cors/cors-filtering.js new file mode 100644 index 00000000000..aa21070f394 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-filtering.js @@ -0,0 +1,66 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function corsFilter(corsUrl, headerName, headerValue, isFiltered) { + var url = corsUrl + "?pipe=header(" + headerName + "," + encodeURIComponent(headerValue) +")|header(Access-Control-Allow-Origin,*)"; + promise_test(function(test) { + return fetch(url).then(function(resp) { + assert_equals(resp.status, 200, "Fetch success with code 200"); + assert_equals(resp.type , "cors", "CORS fetch's response has cors type"); + if (!isFiltered) { + assert_equals(resp.headers.get(headerName), headerValue, + headerName + " header should be included in response with value: " + headerValue); + } else { + assert_false(resp.headers.has(headerName), "UA should exclude " + headerName + " header from response"); + } + test.done(); + }); + }, "CORS filter on " + headerName + " header"); +} + +function corsExposeFilter(corsUrl, headerName, headerValue, isForbidden) { + var url = corsUrl + "?pipe=header(" + headerName + "," + encodeURIComponent(headerValue) +")|" + + "header(Access-Control-Allow-Origin,*)" + + "header(Access-Control-Expose-Headers," + headerName + ")"; + + promise_test(function(test) { + return fetch(url).then(function(resp) { + assert_equals(resp.status, 200, "Fetch success with code 200"); + assert_equals(resp.type , "cors", "CORS fetch's response has cors type"); + if (!isForbidden) { + assert_equals(resp.headers.get(headerName), headerValue, + headerName + " header should be included in response with value: " + headerValue); + } else { + assert_false(resp.headers.has(headerName), "UA should exclude " + headerName + " header from response"); + } + test.done(); + }); + }, "CORS filter on " + headerName + " header, header is exposed"); +} + +var url = "http://www1.{{host}}:{{ports[http][1]}}" + dirname(location.pathname) + RESOURCES_DIR + "top.txt"; + +corsFilter(url, "Cache-Control", "no-cache", false); +corsFilter(url, "Content-Language", "fr", false); +corsFilter(url, "Content-Type", "text/html", false); +corsFilter(url, "Expires","04 May 1988 22:22:22 GMT" , false); +corsFilter(url, "Last-Modified", "04 May 1988 22:22:22 GMT", false); +corsFilter(url, "Pragma", "no-cache", false); + +corsFilter(url, "Age", "27", true); +corsFilter(url, "Server", "wptServe" , true); +corsFilter(url, "Warning", "Mind the gap" , true); +corsFilter(url, "Content-Length", "0" , true); +corsFilter(url, "Set-Cookie", "name=value" , true); +corsFilter(url, "Set-Cookie2", "name=value" , true); + +corsExposeFilter(url, "Age", "27", false); +corsExposeFilter(url, "Server", "wptServe" , false); +corsExposeFilter(url, "Warning", "Mind the gap" , false); +corsExposeFilter(url, "Content-Length", "0" , false); +corsExposeFilter(url, "Set-Cookie", "name=value" , true); +corsExposeFilter(url, "Set-Cookie2", "name=value" , true); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-multiple-origins-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-multiple-origins-worker.html new file mode 100644 index 00000000000..a8e50573278 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-multiple-origins-worker.html @@ -0,0 +1,19 @@ + + + + + Fetch in worker: check multiple Access-Control-Allow-Origin header management + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-multiple-origins.html b/testing/web-platform/tests/fetch/api/cors/cors-multiple-origins.html new file mode 100644 index 00000000000..9b12b05064b --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-multiple-origins.html @@ -0,0 +1,18 @@ + + + + + Fetch: check multiple Access-Control-Allow-Origin header management + + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-multiple-origins.js b/testing/web-platform/tests/fetch/api/cors/cors-multiple-origins.js new file mode 100644 index 00000000000..35c404b7770 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-multiple-origins.js @@ -0,0 +1,32 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function corsMultipleOrigins(desc, originList, shouldPass) { + var urlParameters = "?origin=" + encodeURIComponent(originList.join(", ")); + var url = "http://www1.{{host}}:{{ports[http][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "preflight.py"; + + if (shouldPass) { + promise_test(function(test) { + return fetch(url + urlParameters).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + }); + }, desc); + } else { + promise_test(function(test) { + return promise_rejects(test, new TypeError(), fetch(url + urlParameters)); + }, desc); + } +} +/* Actual origin */ +var origin = "http://{{host}}:{{ports[http][0]}}"; + +corsMultipleOrigins("3 origins allowed, match the 3rd (" + origin + ")", ["\"\"", "http://example.com", origin], true); +corsMultipleOrigins("3 origins allowed, match the 3rd (\"*\")", ["\"\"", "http://example.com", "*"], true); +corsMultipleOrigins("3 origins allowed, match twice (" + origin + ")", ["\"\"", origin, origin], true); +corsMultipleOrigins("3 origins allowed, match twice (\"*\")", ["*", "http://example.com", "*"], true); +corsMultipleOrigins("3 origins allowed, match twice (\"*\" and " + origin + ")", ["*", "http://example.com", origin], true); +corsMultipleOrigins("3 origins allowed, no match", ["", "http://example.com", "https://example2.com"], false); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-no-preflight-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-no-preflight-worker.html new file mode 100644 index 00000000000..c6402ada093 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-no-preflight-worker.html @@ -0,0 +1,20 @@ + + + + + Fetch in worker: CORS request with simple methods and headers + + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-no-preflight.html b/testing/web-platform/tests/fetch/api/cors/cors-no-preflight.html new file mode 100644 index 00000000000..3ff5c97eac6 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-no-preflight.html @@ -0,0 +1,20 @@ + + + + + Fetch: CORS request with simple methods and headers + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-no-preflight.js b/testing/web-platform/tests/fetch/api/cors/cors-no-preflight.js new file mode 100644 index 00000000000..8d932cc38bc --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-no-preflight.js @@ -0,0 +1,50 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("/common/utils.js"); + importScripts("../resources/utils.js"); +} + +function corsNoPreflight(desc, scheme, subdomain, port, method, headerName, headerValue) { + if (!port) + port = location.port; + if (subdomain) + subdomain = subdomain + "."; + else + subdomain = ""; + + var uuid_token = token(); + var url = scheme + "://" + subdomain + "{{host}}" + ":" + port + dirname(location.pathname) + RESOURCES_DIR + "preflight.py"; + var urlParameters = "?token=" + uuid_token + "&max_age=0"; + var requestInit = {"mode": "cors", "method": method, "headers":{}}; + if (headerName) + requestInit["headers"][headerName] = headerValue; + + promise_test(function(test) { + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(resp) { + assert_equals(resp.status, 200, "Clean stash response's status is 200"); + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + assert_equals(resp.headers.get("x-did-preflight"), "0", "No preflight request has been made"); + }); + }); + }, desc); +} +var port2 = "{{ports[http][1]}}"; +var httpsPort = "{{ports[https][0]}}"; + +corsNoPreflight("Cross domain basic usage [GET]", "http", "www1", undefined, "GET"); +corsNoPreflight("Same domain different port [GET]", "http", undefined, port2, "GET"); +corsNoPreflight("Cross domain different port [GET]", "http", "www1", port2, "GET"); +corsNoPreflight("Cross domain different protocol [GET]", "https", "www1", httpsPort, "GET"); +corsNoPreflight("Same domain different protocol different port [GET]", "https", undefined, httpsPort, "GET"); +corsNoPreflight("Cross domain [POST]", "http", "www1", undefined, "POST"); +corsNoPreflight("Cross domain [HEAD]", "http", "www1", undefined, "HEAD"); +corsNoPreflight("Cross domain [GET] [Accept: */*]", "http", "www1", undefined, "GET" , "Accept", "*/*"); +corsNoPreflight("Cross domain [GET] [Accept-Language: fr]", "http", "www1", undefined, "GET" , "Accept-Language", "fr"); +corsNoPreflight("Cross domain [GET] [Content-Language: fr]", "http", "www1", undefined, "GET" , "Content-Language", "fr"); +corsNoPreflight("Cross domain [GET] [Content-Type: application/x-www-form-urlencoded]", "http", "www1", undefined, "GET" , "Content-Type", "application/x-www-form-urlencoded"); +corsNoPreflight("Cross domain [GET] [Content-Type: multipart/form-data]", "http", "www1", undefined, "GET" , "Content-Type", "multipart/form-data"); +corsNoPreflight("Cross domain [GET] [Content-Type: text/plain]", "http", "www1", undefined, "GET" , "Content-Type", "text/plain"); +corsNoPreflight("Cross domain [GET] [Content-Type: text/plain;charset=utf-8]", "http", "www1", undefined, "GET" , "Content-Type", "text/plain;charset=utf-8"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-origin-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-origin-worker.html new file mode 100644 index 00000000000..f6145e6e3e1 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-origin-worker.html @@ -0,0 +1,19 @@ + + + + + Fetch in worker: check Access-Control-Allow-Origin header management + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-origin.html b/testing/web-platform/tests/fetch/api/cors/cors-origin.html new file mode 100644 index 00000000000..de7a0552acc --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-origin.html @@ -0,0 +1,19 @@ + + + + + Fetch: check Access-Control-Allow-Origin header management + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-origin.js b/testing/web-platform/tests/fetch/api/cors/cors-origin.js new file mode 100644 index 00000000000..36052742a5f --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-origin.js @@ -0,0 +1,61 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); + importScripts("/common/utils.js"); +} + +/* If origin is undefined, it is set to fetched url's origin*/ +function corsOrigin(desc, scheme, subdomain, port, method, origin, shouldPass) { + if (!port) + port = location.port; + if (subdomain) + subdomain = subdomain + "."; + else + subdomain = ""; + if (!origin) + origin = scheme + "://" + subdomain + "{{host}}" + ":" + port; + + var uuid_token = token(); + var urlParameters = "?token=" + uuid_token + "&max_age=0&origin=" + encodeURIComponent(origin) + "&allow_methods=" + method; + var url = scheme + "://" + subdomain + "{{host}}" + ":" + port + dirname(location.pathname) + RESOURCES_DIR + "preflight.py"; + var requestInit = {"mode": "cors", "method": method}; + + promise_test(function(test) { + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(resp) { + assert_equals(resp.status, 200, "Clean stash response's status is 200"); + if (shouldPass) { + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + }); + } else { + return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)); + } + }); + }, desc); + +} +var port = "{{ports[http][0]}}"; +var port2 = "{{ports[http][1]}}"; +var httpsPort = "{{ports[https][0]}}"; +/* Actual origin */ +var origin = "http://{{host}}:{{ports[http][0]}}"; + +corsOrigin("Cross domain different subdomain [origin OK]", "http", "www1", undefined, "GET", origin, true); +corsOrigin("Cross domain different subdomain [origin KO]", "http", "www1", undefined, "GET", undefined, false); +corsOrigin("Same domain different port [origin OK]", "http", undefined, port2, "GET", origin, true); +corsOrigin("Same domain different port [origin KO]", "http", undefined, port2, "GET", undefined, false); +corsOrigin("Cross domain different port [origin OK]", "http", "www1", port2, "GET", origin, true); +corsOrigin("Cross domain different port [origin KO]", "http", "www1", port2, "GET", undefined, false); +corsOrigin("Cross domain different protocol [origin OK]", "https", "www1", httpsPort, "GET", origin, true); +corsOrigin("Cross domain different protocol [origin KO]", "https", "www1", httpsPort, "GET", undefined, false); +corsOrigin("Same domain different protocol different port [origin OK]", "https", undefined, httpsPort, "GET", origin, true); +corsOrigin("Same domain different protocol different port [origin KO]", "https", undefined, httpsPort, "GET", undefined, false); +corsOrigin("Cross domain [POST] [origin OK]", "http", "www1", undefined, "POST", origin, true); +corsOrigin("Cross domain [POST] [origin KO]", "http", "www1", undefined, "POST", undefined, false); +corsOrigin("Cross domain [HEAD] [origin OK]", "http", "www1", undefined, "HEAD", origin, true); +corsOrigin("Cross domain [HEAD] [origin KO]", "http", "www1", undefined, "HEAD", undefined, false); +corsOrigin("CORS preflight [PUT] [origin OK]", "http", "www1", undefined, "PUT", origin, true); +corsOrigin("CORS preflight [PUT] [origin KO]", "http", "www1", undefined, "PUT", undefined, false); +corsOrigin("Allowed origin: \"\" [origin KO]", "http", "www1", undefined, "GET", "" , false); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-redirect-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-preflight-redirect-worker.html new file mode 100644 index 00000000000..663f5d655c1 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-redirect-worker.html @@ -0,0 +1,18 @@ + + + + + Fetch in worker: redirection handling for cors with preflight + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-redirect.html b/testing/web-platform/tests/fetch/api/cors/cors-preflight-redirect.html new file mode 100644 index 00000000000..6f136af76be --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-redirect.html @@ -0,0 +1,18 @@ + + + + + Fetch: redirection handling for cors with preflight + + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-redirect.js b/testing/web-platform/tests/fetch/api/cors/cors-preflight-redirect.js new file mode 100644 index 00000000000..52a7bca3cd7 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-redirect.js @@ -0,0 +1,40 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); + importScripts("/common/utils.js"); +} + +function corsPreflightRedirect(desc, redirectUrl, redirectLocation, redirectStatus, redirectPreflight) { + var uuid_token = token(); + var url = redirectUrl; + var urlParameters = "?token=" + uuid_token + "&max_age=0"; + urlParameters += "&redirect_status=" + redirectStatus; + urlParameters += "&location=" + encodeURIComponent(redirectLocation); + + if (redirectPreflight) + urlParameters += "&redirect_preflight"; + var requestInit = {"mode": "cors", "redirect": "follow"}; + + /* Force preflight */ + requestInit["headers"] = {"x-force-preflight": ""}; + urlParameters += "&allow_headers=x-force-preflight"; + + promise_test(function(test) { + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(resp) { + assert_equals(resp.status, 200, "Clean stash response's status is 200"); + return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)); + }); + }, desc); +} + +var redirectUrl = "http://www1.{{host}}:{{ports[http][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "redirect.py"; +var locationUrl = "http://www1.{{host}}:{{ports[http][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "preflight.py"; + +for (var code of [301, 302, 303, 307, 308]) { + /* preflight should not follow the redirection */ + corsPreflightRedirect("Redirection " + code + " on preflight failed", redirectUrl, locationUrl, code, true); + /* preflight is done before redirection: preflight force redirect to error */ + corsPreflightRedirect("Redirection " + code + " after preflight failed", redirectUrl, locationUrl, code, false); +} + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-referrer-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-preflight-referrer-worker.html new file mode 100644 index 00000000000..4ed9072fb51 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-referrer-worker.html @@ -0,0 +1,18 @@ + + + + + Fetch in worker: Referer header management in CORS request with preflight + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-referrer.html b/testing/web-platform/tests/fetch/api/cors/cors-preflight-referrer.html new file mode 100644 index 00000000000..a399a051cb1 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-referrer.html @@ -0,0 +1,18 @@ + + + + + Fetch: Referer header management in CORS request with preflight + + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-referrer.js b/testing/web-platform/tests/fetch/api/cors/cors-preflight-referrer.js new file mode 100644 index 00000000000..5cc3a084436 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-referrer.js @@ -0,0 +1,39 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("/common/utils.js"); + importScripts("../resources/utils.js"); +} + +function corsPreflightReferrer(desc, corsUrl, referrerPolicy, expectedReferrer) { + var uuid_token = token(); + var url = corsUrl; + var urlParameters = "?token=" + uuid_token + "&max_age=0"; + var requestInit = {"mode": "cors", "referrerPolicy": referrerPolicy}; + + /* Force preflight */ + requestInit["headers"] = {"x-force-preflight": ""}; + urlParameters += "&allow_headers=x-force-preflight"; + + promise_test(function(test) { + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(resp) { + assert_equals(resp.status, 200, "Clean stash response's status is 200"); + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + assert_equals(resp.headers.get("x-did-preflight"), "1", "Preflight request has been made"); + assert_equals(resp.headers.get("x-preflight-referrer"), expectedReferrer, "Preflight's referrer is correct"); + assert_equals(resp.headers.get("x-referrer"), expectedReferrer, "Request's refferer is correct"); + }); + }); + }, desc); +} + +var corsUrl = "http://www1.{{host}}:{{ports[http][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "preflight.py"; +var origin = "http://{{host}}:{{ports[http][0]}}"; + +corsPreflightReferrer("Referrer policy: no-referrer", corsUrl, "no-referrer", ""); +corsPreflightReferrer("Referrer policy: \"\"", corsUrl, "", ""); +corsPreflightReferrer("Referrer policy: origin-only", corsUrl, "origin-only", origin); +corsPreflightReferrer("Referrer policy: origin-when-cross-origin", corsUrl, "origin-when-cross-origin", origin); +corsPreflightReferrer("Referrer policy: unsafe-url", corsUrl, "unsafe-url", location.toString()); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-status-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-preflight-status-worker.html new file mode 100644 index 00000000000..7650c37d1ea --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-status-worker.html @@ -0,0 +1,18 @@ + + + + + Fetch in worker: preflight status code handling + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-status.html b/testing/web-platform/tests/fetch/api/cors/cors-preflight-status.html new file mode 100644 index 00000000000..bc11fb755e6 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-status.html @@ -0,0 +1,17 @@ + + + + + Fetch: preflight status code handling + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-status.js b/testing/web-platform/tests/fetch/api/cors/cors-preflight-status.js new file mode 100644 index 00000000000..07bd23c9003 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-status.js @@ -0,0 +1,41 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); + importScripts("/common/utils.js"); +} + +/* Check preflight is ok if status is ok status (200 to 299)*/ +function corsPreflightStatus(desc, corsUrl, preflightStatus) { + var uuid_token = token(); + var url = corsUrl; + var requestInit = {"mode": "cors"}; + /* Force preflight */ + requestInit["headers"] = {"x-force-preflight": ""}; + + var urlParameters = "?token=" + uuid_token + "&max_age=0"; + urlParameters += "&allow_headers=x-force-preflight"; + urlParameters += "&preflight_status=" + preflightStatus; + + promise_test(function(test) { + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(resp) { + assert_equals(resp.status, 200, "Clean stash response's status is 200"); + if (200 <= preflightStatus && 299 >= preflightStatus) { + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + assert_equals(resp.headers.get("x-did-preflight"), "1", "Preflight request has been made"); + }); + } else { + return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)); + } + }); + }, desc); +} + +var corsUrl = "http://www1.{{host}}:{{ports[http][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "preflight.py"; +for (status of [200, 201, 202, 203, 204, 205, 206, + 300, 301, 302, 303, 304, 305, 306, 307, 308, + 400, 401, 402, 403, 404, 405, + 501, 502, 503, 504, 505]) + corsPreflightStatus("Preflight answered with status " + status, corsUrl, status); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-preflight-worker.html new file mode 100644 index 00000000000..bedef5d7751 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight-worker.html @@ -0,0 +1,20 @@ + + + + + Fetch in worker: Check cors fetches requiring prefligh + + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight.html b/testing/web-platform/tests/fetch/api/cors/cors-preflight.html new file mode 100644 index 00000000000..c4a581a55c5 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight.html @@ -0,0 +1,20 @@ + + + + + Fetch: Check cors fetches requiring preflight + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-preflight.js b/testing/web-platform/tests/fetch/api/cors/cors-preflight.js new file mode 100644 index 00000000000..60ecd186df1 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-preflight.js @@ -0,0 +1,82 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); + importScripts("/common/utils.js"); +} + +/* + Check preflight is done + Control if server allows method and headers and check accordingly + Check control access headers added by UA (for method and headers) +*/ +function corsPreflight(desc, corsUrl, method, allowed, headers) { + var uuid_token = token(); + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(response) { + + var url = corsUrl; + var urlParameters = "?token=" + uuid_token + "&max_age=0"; + var requestInit = {"mode": "cors", "method": method}; + if (headers) + requestInit["headers"] = headers; + + if (allowed) { + urlParameters += "&allow_methods=" + method; + if (headers) { + //Let's check prefligh request. + //Server will send back headers from Access-Control-Request-Headers in x-control-request-headers + urlParameters += "&control_request_headers" + //Make the server allow the headers + urlParameters += "&allow_headers=" + urlParameters += headers.join("%2C%20"); + } + promise_test(function(test) { + test.add_cleanup(function() { + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token); + }); + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + assert_equals(resp.headers.get("x-did-preflight"), "1", "Preflight request has been made"); + if (headers) { + var actualHeaders = resp.headers.get("x-control-request-headers").split(","); + for (var i in actualHeaders) + actualHeaders[i] = actualHeaders[i].trim(); + for (var header in headers) + assert_in_array(header, actualHeaders, "Preflight asked permission for header: " + header); + } + }); + }, desc); + } else { + promise_test(function(test) { + test.add_cleanup(function() { + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token); + }); + return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)); + }, desc); + } + }); +} + +var corsUrl = "http://www1.{{host}}:{{ports[http][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "preflight.py"; + +corsPreflight("CORS [DELETE], server allows", corsUrl, "DELETE", true); +corsPreflight("CORS [DELETE], server refuses", corsUrl, "DELETE", false); +corsPreflight("CORS [PUT], server allows", corsUrl, "PUT", true); +corsPreflight("CORS [PUT], server refuses", corsUrl, "PUT", false); +corsPreflight("CORS [PATCH], server allows", corsUrl, "PATCH", true); +corsPreflight("CORS [PATCH], server refuses", corsUrl, "PATCH", false); +corsPreflight("CORS [NEW], server allows", corsUrl, "NEW", true); +corsPreflight("CORS [NEW], server refuses", corsUrl, "NEW", false); + +corsPreflight("CORS [GET] [x-test-header: allowed], server allows", corsUrl, "GET", true, {"x-test-header1": "allowed"}); +corsPreflight("CORS [GET] [x-test-header: refused], server refuses", corsUrl, "GET", false, {"x-test-header1": "refused"}); + +var headers = {"x-test-header1": "allowedOrRefused", + "x-test-header2": "allowedOrRefused", + "x-test-header3": "allowedOrRefused", +}; +corsPreflight("CORS [GET] [several headers], server allows", corsUrl, "GET", true, headers); +corsPreflight("CORS [GET] [several headers], server refuses", corsUrl, "GET", false, headers); +corsPreflight("CORS [PUT] [several headers], server allows", corsUrl, "PUT", true, headers); +corsPreflight("CORS [PUT] [several headers], server refuses", corsUrl, "PUT", false, headers); + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-redirect-credentials-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-redirect-credentials-worker.html new file mode 100644 index 00000000000..38e3e78ac51 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-redirect-credentials-worker.html @@ -0,0 +1,16 @@ + + + + + Fetch in worker: redirection url has credentials + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-redirect-credentials.html b/testing/web-platform/tests/fetch/api/cors/cors-redirect-credentials.html new file mode 100644 index 00000000000..2491f692d10 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-redirect-credentials.html @@ -0,0 +1,15 @@ + + + + + Fetch: redirection url has credentials + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-redirect-credentials.js b/testing/web-platform/tests/fetch/api/cors/cors-redirect-credentials.js new file mode 100644 index 00000000000..ce0ef2d0b26 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-redirect-credentials.js @@ -0,0 +1,47 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function corsRedirectCredentials(desc, redirectUrl, redirectLocation, redirectStatus, locationCredentials) { + + var url = redirectUrl + var urlParameters = "?redirect_status=" + redirectStatus; + urlParameters += "&location=" + encodeURIComponent(redirectLocation.replace("://", "://" + locationCredentials + "@")); + + var requestInit = {"mode": "cors", "redirect": "follow", "credentials":"include"}; + + promise_test(function(test) { + return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)); + }, desc); +} + +var redirPath = dirname(location.pathname) + RESOURCES_DIR + "redirect.py"; +var preflightPath = dirname(location.pathname) + RESOURCES_DIR + "preflight.py"; + +var localRedirect = "http://{{host}}:{{ports[http][0]}}" + redirPath; +var remoteRedirect = "http://www1.{{host}}:{{ports[http][0]}}" + redirPath; + +var localLocation = "http://{{host}}:{{ports[http][0]}}" + preflightPath; +var remoteLocation = "http://www1.{{host}}:{{ports[http][0]}}" + preflightPath; +var remoteLocation2 = "http://www.{{host}}:{{ports[http][0]}}" + preflightPath; + +for (var code of [301, 302, 303, 307, 308]) { + corsRedirectCredentials("Redirect " + code + " from same origin to remote with user and password", localRedirect, remoteLocation, code, "user:password"); + corsRedirectCredentials("Redirect " + code + " from same origin to remote with user", localRedirect, remoteLocation, code, "user:"); + corsRedirectCredentials("Redirect " + code + " from same origin to remote with password", localRedirect, remoteLocation, code, ":password"); + + corsRedirectCredentials("Redirect " + code + " from remote to same origin with user and password", remoteRedirect, localLocation, code, "user:password"); + corsRedirectCredentials("Redirect " + code + " from remote to same origin with user", remoteRedirect, localLocation, code, "user:"); + corsRedirectCredentials("Redirect " + code + " from remote to same origin with password", remoteRedirect, localLocation, code, ":password"); + + corsRedirectCredentials("Redirect " + code + " from remote to another remote with user and password", remoteRedirect, remoteLocation2, code, "user:password"); + corsRedirectCredentials("Redirect " + code + " from remote to another remote with user", remoteRedirect, remoteLocation2, code, "user:"); + corsRedirectCredentials("Redirect " + code + " from remote to another remote with password", remoteRedirect, remoteLocation2, code, ":password"); + + corsRedirectCredentials("Redirect " + code + " from remote to same remote with user and password", remoteRedirect, remoteLocation, code, "user:password"); + corsRedirectCredentials("Redirect " + code + " from remote to same remote with user", remoteRedirect, remoteLocation, code, "user:"); + corsRedirectCredentials("Redirect " + code + " from remote to same remote with password", remoteRedirect, remoteLocation, code, ":password"); +} + +done(); diff --git a/testing/web-platform/tests/fetch/api/cors/cors-redirect-worker.html b/testing/web-platform/tests/fetch/api/cors/cors-redirect-worker.html new file mode 100644 index 00000000000..bf7bd965272 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-redirect-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: CORS Redirection with several origins + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-redirect.html b/testing/web-platform/tests/fetch/api/cors/cors-redirect.html new file mode 100644 index 00000000000..f88eacf7bc5 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-redirect.html @@ -0,0 +1,17 @@ + + + + + Fetch: CORS Redirection with several origins + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/cors/cors-redirect.js b/testing/web-platform/tests/fetch/api/cors/cors-redirect.js new file mode 100644 index 00000000000..a818054ab10 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/cors/cors-redirect.js @@ -0,0 +1,44 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("/common/utils.js"); + importScripts("../resources/utils.js"); +} + +function corsRedirect(desc, redirectUrl, redirectLocation, redirectStatus, expectedOrigin) { + var uuid_token = token(); + var url = redirectUrl; + var urlParameters = "?token=" + uuid_token + "&max_age=0"; + urlParameters += "&redirect_status=" + redirectStatus; + urlParameters += "&location=" + encodeURIComponent(redirectLocation); + + var requestInit = {"mode": "cors", "redirect": "follow"}; + + promise_test(function(test) { + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(resp) { + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + assert_equals(resp.headers.get("x-did-preflight"), "0", "No preflight request has been made"); + assert_equals(resp.headers.get("x-origin"), expectedOrigin, "Origin is correctly set after redirect"); + }); + }); + }, desc); +} + +var redirPath = dirname(location.pathname) + RESOURCES_DIR + "redirect.py"; +var preflightPath = dirname(location.pathname) + RESOURCES_DIR + "preflight.py"; + +var localRedirect = "http://{{host}}:{{ports[http][0]}}" + redirPath; +var remoteRedirect = "http://www1.{{host}}:{{ports[http][0]}}" + redirPath; + +var localLocation = "http://{{host}}:{{ports[http][0]}}" + preflightPath; +var remoteLocation = "http://www1.{{host}}:{{ports[http][0]}}" + preflightPath; +var remoteLocation2 = "http://www.{{host}}:{{ports[http][0]}}" + preflightPath; + +for (var code of [301, 302, 303, 307, 308]) { + corsRedirect("Redirect " + code + ": cors to same cors", remoteRedirect, remoteLocation, code, location.origin); + corsRedirect("Redirect " + code + ": cors to another cors", remoteRedirect, remoteLocation2, code, "null"); + corsRedirect("Redirect " + code + ": same origin to cors", localRedirect, remoteLocation, code, location.origin); + corsRedirect("Redirect " + code + ": cors to same origin", remoteRedirect, localLocation, code, "null"); +} + +done(); diff --git a/testing/web-platform/tests/fetch/api/credentials/authentication-basic-worker.html b/testing/web-platform/tests/fetch/api/credentials/authentication-basic-worker.html new file mode 100644 index 00000000000..e9ced4f10af --- /dev/null +++ b/testing/web-platform/tests/fetch/api/credentials/authentication-basic-worker.html @@ -0,0 +1,16 @@ + + + + + Fetch in worker: Authorisation header management for basic authentication + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/credentials/authentication-basic.html b/testing/web-platform/tests/fetch/api/credentials/authentication-basic.html new file mode 100644 index 00000000000..cba1ecd4acc --- /dev/null +++ b/testing/web-platform/tests/fetch/api/credentials/authentication-basic.html @@ -0,0 +1,15 @@ + + + + + Fetch: Authorisation header management for basic authentication + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/credentials/authentication-basic.js b/testing/web-platform/tests/fetch/api/credentials/authentication-basic.js new file mode 100644 index 00000000000..ce93e9d7b93 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/credentials/authentication-basic.js @@ -0,0 +1,21 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function basicAuth(desc, user, pass, mode, status) { + promise_test(function(test) { + var headers = { "Authorization": "Basic " + btoa(user + ":" + pass)}; + var requestInit = {"credentials": mode, "headers": headers}; + return fetch(RESOURCES_DIR + "authentication.py?realm=test", requestInit).then(function(resp) { + assert_equals(resp.status, status, "HTTP status is " + status); + assert_equals(resp.type , "basic", "Response's type is basic"); + }); + }, desc); +} + +basicAuth("User-added Authorization header with include mode", "user", "password", "include", 200); +basicAuth("User-added Authorization header with same-origin mode", "user", "password", "same-origin", 200); +basicAuth("User-added Authorization header with omit mode", "user", "password", "omit", 200); + +done(); diff --git a/testing/web-platform/tests/fetch/api/credentials/cookies-worker.html b/testing/web-platform/tests/fetch/api/credentials/cookies-worker.html new file mode 100644 index 00000000000..86febf10bef --- /dev/null +++ b/testing/web-platform/tests/fetch/api/credentials/cookies-worker.html @@ -0,0 +1,18 @@ + + + + + Fetch in worker: cookies management + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/credentials/cookies.html b/testing/web-platform/tests/fetch/api/credentials/cookies.html new file mode 100644 index 00000000000..72913029a2f --- /dev/null +++ b/testing/web-platform/tests/fetch/api/credentials/cookies.html @@ -0,0 +1,17 @@ + + + + + Fetch: cookies management + + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/credentials/cookies.js b/testing/web-platform/tests/fetch/api/credentials/cookies.js new file mode 100644 index 00000000000..9c394d6fb38 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/credentials/cookies.js @@ -0,0 +1,51 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function cookies(desc, credentials1, credentials2 ,cookies) { + var url = RESOURCES_DIR + "top.txt" + var urlParameters = ""; + var urlCleanParameters = ""; + if (cookies) { + urlParameters +="?pipe=header(Set-Cookie,"; + urlParameters += cookies.join(",True)|header(Set-Cookie,") + ",True)"; + urlCleanParameters +="?pipe=header(Set-Cookie,"; + urlCleanParameters += cookies.join("%3B%20max-age=0,True)|header(Set-Cookie,") + "%3B%20max-age=0,True)"; + } + + var requestInit = {"credentials": credentials1} + promise_test(function(test){ + var requestInit = {"credentials": credentials1} + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type , "basic", "Response's type is basic"); + //check cookies sent + return fetch(RESOURCES_DIR + "inspect-headers.py?headers=cookie" , {"credentials": credentials2}); + }).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type , "basic", "Response's type is basic"); + assert_false(resp.headers.has("Cookie") , "Cookie header is not exposed in response"); + if (credentials1 != "omit" && credentials2 != "omit") { + assert_equals(resp.headers.get("x-request-cookie") , cookies.join("; "), "Request include cookie(s)"); + } + else { + assert_false(resp.headers.has("x-request-cookie") , "Request does not have cookie(s)"); + } + //clean cookies + return fetch(url + urlCleanParameters, {"credentials": "include"}); + }).catch(function() { + fetch(url + urlCleanParameters, {"credentials": "include"}); + }); + }, desc); +} + +cookies("Include mode: 1 cookie", "include", "include", ["a=1"]); +cookies("Include mode: 2 cookies", "include", "include", ["b=2", "c=3"]); +cookies("Omit mode: discard cookies", "omit", "omit", ["d=4"]); +cookies("Omit mode: no cookie is stored", "omit", "include", ["e=5"]); +cookies("Omit mode: no cookie is sent", "include", "omit", ["f=6"]); +cookies("Same-origin mode: 1 cookie", "same-origin", "same-origin", ["a=1"]); +cookies("Same-origin mode: 2 cookies", "same-origin", "same-origin", ["b=2", "c=3"]); + +done(); diff --git a/testing/web-platform/tests/fetch/api/headers/headers-basic.html b/testing/web-platform/tests/fetch/api/headers/headers-basic.html new file mode 100644 index 00000000000..a5b8b6cfa9c --- /dev/null +++ b/testing/web-platform/tests/fetch/api/headers/headers-basic.html @@ -0,0 +1,111 @@ + + + + + Headers structure + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/headers/headers-casing.html b/testing/web-platform/tests/fetch/api/headers/headers-casing.html new file mode 100644 index 00000000000..1e505d81cda --- /dev/null +++ b/testing/web-platform/tests/fetch/api/headers/headers-casing.html @@ -0,0 +1,64 @@ + + + + + Headers case management + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/headers/headers-combine.html b/testing/web-platform/tests/fetch/api/headers/headers-combine.html new file mode 100644 index 00000000000..ddcfdbee6eb --- /dev/null +++ b/testing/web-platform/tests/fetch/api/headers/headers-combine.html @@ -0,0 +1,60 @@ + + + + + Headers nameshake + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/headers/headers-errors.html b/testing/web-platform/tests/fetch/api/headers/headers-errors.html new file mode 100644 index 00000000000..be2d1a518dc --- /dev/null +++ b/testing/web-platform/tests/fetch/api/headers/headers-errors.html @@ -0,0 +1,66 @@ + + + + + Headers errors + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/headers/headers-idl.html b/testing/web-platform/tests/fetch/api/headers/headers-idl.html new file mode 100644 index 00000000000..2aaa1ceeaee --- /dev/null +++ b/testing/web-platform/tests/fetch/api/headers/headers-idl.html @@ -0,0 +1,36 @@ + + + + + Headers idl interface + + + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/headers/headers-normalize.html b/testing/web-platform/tests/fetch/api/headers/headers-normalize.html new file mode 100644 index 00000000000..384c4f4c26f --- /dev/null +++ b/testing/web-platform/tests/fetch/api/headers/headers-normalize.html @@ -0,0 +1,47 @@ + + + + + Headers normalize values + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/headers/headers-structure.html b/testing/web-platform/tests/fetch/api/headers/headers-structure.html new file mode 100644 index 00000000000..9448e450c9b --- /dev/null +++ b/testing/web-platform/tests/fetch/api/headers/headers-structure.html @@ -0,0 +1,31 @@ + + + + + Headers basic + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/policies/csp-blocked-worker.html b/testing/web-platform/tests/fetch/api/policies/csp-blocked-worker.html new file mode 100644 index 00000000000..e8660dffa94 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/csp-blocked-worker.html @@ -0,0 +1,16 @@ + + + + + Fetch in worker: blocked by CSP + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/csp-blocked.html b/testing/web-platform/tests/fetch/api/policies/csp-blocked.html new file mode 100644 index 00000000000..99e90dfcd8f --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/csp-blocked.html @@ -0,0 +1,15 @@ + + + + + Fetch: blocked by CSP + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/csp-blocked.html.headers b/testing/web-platform/tests/fetch/api/policies/csp-blocked.html.headers new file mode 100644 index 00000000000..c8c1e9ffbd9 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/csp-blocked.html.headers @@ -0,0 +1 @@ +Content-Security-Policy: connect-src 'none'; \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/csp-blocked.js b/testing/web-platform/tests/fetch/api/policies/csp-blocked.js new file mode 100644 index 00000000000..0395304b816 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/csp-blocked.js @@ -0,0 +1,13 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +//Content-Security-Policy: connect-src 'none'; cf .headers file +cspViolationUrl = RESOURCES_DIR + "top.txt"; + +promise_test(function(test) { + return promise_rejects(test, new TypeError(), fetch(cspViolationUrl)); +}, "Fetch is blocked by CSP, got a TypeError"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/policies/csp-blocked.js.headers b/testing/web-platform/tests/fetch/api/policies/csp-blocked.js.headers new file mode 100644 index 00000000000..c8c1e9ffbd9 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/csp-blocked.js.headers @@ -0,0 +1 @@ +Content-Security-Policy: connect-src 'none'; \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer-worker.html b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer-worker.html new file mode 100644 index 00000000000..dbef9bb658f --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: referrer with no-referrer policy + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.html b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.html new file mode 100644 index 00000000000..22a6f34c525 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.html @@ -0,0 +1,15 @@ + + + + + Fetch: referrer with no-referrer policy + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.html.headers b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.html.headers new file mode 100644 index 00000000000..6954766b475 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.html.headers @@ -0,0 +1 @@ +Content-Security-Policy: referrer no-referrer; \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.js b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.js new file mode 100644 index 00000000000..60600bf081c --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.js @@ -0,0 +1,19 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +var fetchedUrl = RESOURCES_DIR + "inspect-headers.py?headers=origin"; + +promise_test(function(test) { + return fetch(fetchedUrl).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type , "basic", "Response's type is basic"); + var referrer = resp.headers.get("x-request-referer"); + //Either no referrer header is sent or it is empty + if (referrer) + assert_equals(referrer, "", "request's referrer is empty"); + }); +}, "Request's referrer is empty"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.js.headers b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.js.headers new file mode 100644 index 00000000000..6954766b475 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-no-referrer.js.headers @@ -0,0 +1 @@ +Content-Security-Policy: referrer no-referrer; \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-origin-worker.html b/testing/web-platform/tests/fetch/api/policies/referrer-origin-worker.html new file mode 100644 index 00000000000..bb80dd54fbf --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: referrer with origin policy + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-origin.html b/testing/web-platform/tests/fetch/api/policies/referrer-origin.html new file mode 100644 index 00000000000..92baed79be7 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin.html @@ -0,0 +1,16 @@ + + + + + Fetch: referrer with origin policy + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-origin.html.headers b/testing/web-platform/tests/fetch/api/policies/referrer-origin.html.headers new file mode 100644 index 00000000000..9bb592a867d --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin.html.headers @@ -0,0 +1 @@ +Content-Security-Policy: referrer origin; \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-origin.js b/testing/web-platform/tests/fetch/api/policies/referrer-origin.js new file mode 100644 index 00000000000..3eb414b2fe4 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin.js @@ -0,0 +1,22 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +var origin = "http://{{host}}:{{ports[http][0]}}"; +var fetchedUrl = RESOURCES_DIR + "inspect-headers.py?headers=referer"; + +promise_test(function(test) { + return fetch(fetchedUrl).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type , "basic", "Response's type is basic"); + assert_equals(resp.headers.get("x-request-referer"), origin, "request's referrer is " + origin); + }); +}, "Request's referrer is origin"); + +promise_test(function(test) { + var referrerUrl = "http://{{domains[www]}}:{{ports[http][0]}}/"; + return promise_rejects(test, new TypeError(), fetch(fetchedUrl, { "referrer": referrerUrl})); +}, "Throw a TypeError referrer is not same-origin with origin"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-origin.js.headers b/testing/web-platform/tests/fetch/api/policies/referrer-origin.js.headers new file mode 100644 index 00000000000..9bb592a867d --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin.js.headers @@ -0,0 +1 @@ +Content-Security-Policy: referrer origin; \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url-worker.html b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url-worker.html new file mode 100644 index 00000000000..42045776b12 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: referrer with unsafe-url policy + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.html b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.html new file mode 100644 index 00000000000..10dd79e3d35 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.html @@ -0,0 +1,16 @@ + + + + + Fetch: referrer with unsafe-url policy + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.html.headers b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.html.headers new file mode 100644 index 00000000000..8efcca15fe0 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.html.headers @@ -0,0 +1 @@ +Content-Security-Policy: referrer unsafe-url; \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.js b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.js new file mode 100644 index 00000000000..b593fad5aa2 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.js @@ -0,0 +1,17 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +var referrerUrl = location.href; +var fetchedUrl = RESOURCES_DIR + "inspect-headers.py?headers=referer"; + +promise_test(function(test) { + return fetch(fetchedUrl).then(function(resp) { + assert_equals(resp.status, 200, "HTTP status is 200"); + assert_equals(resp.type , "basic", "Response's type is basic"); + assert_equals(resp.headers.get("x-request-referer"), referrerUrl, "request's referrer is " + referrerUrl); + }); +}, "Request's referrer is the full url of current document/worker"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.js.headers b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.js.headers new file mode 100644 index 00000000000..8efcca15fe0 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/policies/referrer-unsafe-url.js.headers @@ -0,0 +1 @@ +Content-Security-Policy: referrer unsafe-url; \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-count-worker.html b/testing/web-platform/tests/fetch/api/redirect/redirect-count-worker.html new file mode 100644 index 00000000000..1ce33b7c403 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-count-worker.html @@ -0,0 +1,16 @@ + + + + + Fetch in worker: rediraction loop + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-count.html b/testing/web-platform/tests/fetch/api/redirect/redirect-count.html new file mode 100644 index 00000000000..61deb9f528d --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-count.html @@ -0,0 +1,16 @@ + + + + + Fetch: redirection loop + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-count.js b/testing/web-platform/tests/fetch/api/redirect/redirect-count.js new file mode 100644 index 00000000000..ffa521a5c0f --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-count.js @@ -0,0 +1,42 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); + importScripts("/common/utils.js"); +} + +function redirectCount(desc, redirectUrl, redirectLocation, redirectStatus, maxCount, shouldPass) { + var uuid_token = token(); + + var urlParameters = "?token=" + uuid_token + "&max_age=0"; + urlParameters += "&redirect_status=" + redirectStatus; + urlParameters += "&max_count=" + maxCount; + if (redirectLocation) + urlParameters += "&location=" + encodeURIComponent(redirectLocation); + + var url = redirectUrl; + var requestInit = {"redirect": "follow"}; + + promise_test(function(test) { + fetch(RESOURCES_DIR + "clean-stash.py?token=" + uuid_token).then(function(resp) { + assert_equals(resp.status, 200, "Clean stash response's status is 200"); + + if (!shouldPass) + return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)); + + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + }); + }).then(function(body) { + assert_equals(body, maxCount.toString(), "Redirected " + maxCount + "times"); + }); + }, desc); +} + +var redirUrl = RESOURCES_DIR + "redirect.py"; + +for (var statusCode of [301, 302, 303, 307, 308]) { + redirectCount("Redirect " + statusCode + " 20 times", redirUrl, redirUrl, statusCode, 20, true); + redirectCount("Redirect " + statusCode + " 21 times", redirUrl, redirUrl, statusCode, 21, false); +} + +done(); diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-location-worker.html b/testing/web-platform/tests/fetch/api/redirect/redirect-location-worker.html new file mode 100644 index 00000000000..e2970811c07 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-location-worker.html @@ -0,0 +1,16 @@ + + + + + Fetch in worker: handling Location header during redirection + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-location.html b/testing/web-platform/tests/fetch/api/redirect/redirect-location.html new file mode 100644 index 00000000000..ac35dea54c4 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-location.html @@ -0,0 +1,15 @@ + + + + + Fetch: handling Location header during redirection + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-location.js b/testing/web-platform/tests/fetch/api/redirect/redirect-location.js new file mode 100644 index 00000000000..5b081a75408 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-location.js @@ -0,0 +1,50 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function redirectLocation(desc, redirectUrl, redirectLocation, redirectStatus, redirectMode, shouldPass) { + var url = redirectUrl; + var urlParameters = "?redirect_status=" + redirectStatus; + if (redirectLocation) + urlParameters += "&location=" + encodeURIComponent(redirectLocation); + + var requestInit = {"redirect": redirectMode}; + + promise_test(function(test) { + if (redirectMode === "error" || !shouldPass) + return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)); + if (redirectLocation && redirectMode === "manual") + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 0, "Response's status is 0"); + assert_equals(resp.type, "opaqueredirect", "Response's type is opaqueredirect"); + assert_equals(resp.statusText, "", "Response's statusText is \"\""); + assert_true(resp.headers.entries().next().done, "Headers should be empty"); + }); + + if (redirectMode === "manual" || redirectMode === "follow") + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, redirectStatus, "Response's status is " + redirectStatus); + }); + assert_unreached(redirectMode + " is not a valid redirect mode"); + }, desc); +} + +var redirUrl = RESOURCES_DIR + "redirect.py"; +var locationUrl = "top.txt"; +var invalidLocationUrl = "#invalidurl:"; +var dataLocationUrl = "data:,data%20url"; +// FIXME: We may want to mix redirect-mode and cors-mode. +// FIXME: Add tests for "error" redirect-mode. +for (var statusCode of [301, 302, 303, 307, 308]) { + redirectLocation("Redirect " + statusCode + " in \"follow\" mode without location", redirUrl, undefined, statusCode, "follow", true); + redirectLocation("Redirect " + statusCode + " in \"manual\" mode without location", redirUrl, undefined, statusCode, "manual", true); + + redirectLocation("Redirect " + statusCode + " in \"follow\" mode with invalid location", redirUrl, invalidLocationUrl, statusCode, "follow", false); + redirectLocation("Redirect " + statusCode + " in \"manual\" mode with invalid location", redirUrl, invalidLocationUrl, statusCode, "manual", false); + + redirectLocation("Redirect " + statusCode + " in \"follow\" mode with data location", redirUrl, dataLocationUrl, statusCode, "follow", false); + redirectLocation("Redirect " + statusCode + " in \"manual\" mode with data location", redirUrl, dataLocationUrl, statusCode, "manual", true); +} + +done(); diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-method-worker.html b/testing/web-platform/tests/fetch/api/redirect/redirect-method-worker.html new file mode 100644 index 00000000000..fc0bc5e529d --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-method-worker.html @@ -0,0 +1,16 @@ + + + + + Fetch in worker: request method handling when redirected + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-method.html b/testing/web-platform/tests/fetch/api/redirect/redirect-method.html new file mode 100644 index 00000000000..028842dbe07 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-method.html @@ -0,0 +1,15 @@ + + + + + Fetch: request method handling when redirected + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-method.js b/testing/web-platform/tests/fetch/api/redirect/redirect-method.js new file mode 100644 index 00000000000..a7e1b0b69c5 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-method.js @@ -0,0 +1,46 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function redirectMethod(desc, redirectUrl, redirectLocation, redirectStatus, method, expectedMethod) { + 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"; + + promise_test(function(test) { + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 200, "Response's status is 200"); + assert_equals(resp.type, "basic", "Response's type basic"); + assert_equals(resp.headers.get("x-request-method"), expectedMethod, "Request method after redirection is " + expectedMethod); + return resp.text().then(function(text) { + assert_equals(text, expectedMethod == "POST" ? requestInit.body : ""); + }); + }); + }, desc); +} + +var redirUrl = RESOURCES_DIR + "redirect.py"; +var locationUrl = "method.py"; + +redirectMethod("Redirect 301 with GET", redirUrl, locationUrl, 301, "GET", "GET"); +redirectMethod("Redirect 301 with POST", redirUrl, locationUrl, 301, "POST", "GET"); +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 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 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 HEAD", redirUrl, locationUrl, 307, "HEAD", "HEAD"); + +done(); diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-mode-worker.html b/testing/web-platform/tests/fetch/api/redirect/redirect-mode-worker.html new file mode 100644 index 00000000000..32d219f7678 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-mode-worker.html @@ -0,0 +1,17 @@ + + + + + Fetch in worker: redirect mode handling + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-mode.html b/testing/web-platform/tests/fetch/api/redirect/redirect-mode.html new file mode 100644 index 00000000000..2f68d2b70a0 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-mode.html @@ -0,0 +1,16 @@ + + + + + Fetch: redirect mode handling + + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/redirect/redirect-mode.js b/testing/web-platform/tests/fetch/api/redirect/redirect-mode.js new file mode 100644 index 00000000000..f6832c49276 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/redirect/redirect-mode.js @@ -0,0 +1,40 @@ +if (this.document === undefined) { + importScripts("/resources/testharness.js"); + importScripts("../resources/utils.js"); +} + +function redirectMode(desc, redirectUrl, redirectLocation, redirectStatus, redirectMode) { + var url = redirectUrl; + var urlParameters = "?redirect_status=" + redirectStatus; + urlParameters += "&location=" + encodeURIComponent(redirectLocation); + + var requestInit = {"redirect": redirectMode}; + + promise_test(function(test) { + if (redirectMode === "error") + return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)); + if (redirectMode === "manual") + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_equals(resp.status, 0, "Response's status is 0"); + assert_equals(resp.type, "opaqueredirect", "Response's type is opaqueredirect"); + assert_equals(resp.statusText, "", "Response's statusText is \"\""); + }); + if (redirectMode === "follow") + return fetch(url + urlParameters, requestInit).then(function(resp) { + assert_true(new URL(resp.url).pathname.endsWith(locationUrl), "Response's url should be the redirected one"); + assert_equals(resp.status, 200, "Response's status is 200"); + }); + assert_unreached(redirectMode + " is no a valid redirect mode"); + }, desc); +} + +var redirUrl = RESOURCES_DIR + "redirect.py"; +var locationUrl = "top.txt"; + +for (var statusCode of [301, 302, 303, 307, 308]) { + redirectMode("Redirect " + statusCode + " in \"error\" mode ", redirUrl, locationUrl, statusCode, "error"); + redirectMode("Redirect " + statusCode + " in \"follow\" mode ", redirUrl, locationUrl, statusCode, "follow"); + redirectMode("Redirect " + statusCode + " in \"manual\" mode ", redirUrl, locationUrl, statusCode, "manual"); +} + +done(); diff --git a/testing/web-platform/tests/fetch/api/request/request-clone.sub.html b/testing/web-platform/tests/fetch/api/request/request-clone.sub.html new file mode 100644 index 00000000000..ae784564d70 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/request/request-clone.sub.html @@ -0,0 +1,48 @@ + + + + + Request clone + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/request/request-consume.html b/testing/web-platform/tests/fetch/api/request/request-consume.html new file mode 100644 index 00000000000..d0f756dc402 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/request/request-consume.html @@ -0,0 +1,89 @@ + + + + + Request consume + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/request/request-disturbed.html b/testing/web-platform/tests/fetch/api/request/request-disturbed.html new file mode 100644 index 00000000000..958def41768 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/request/request-disturbed.html @@ -0,0 +1,55 @@ + + + + + Request disturbed + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/request/request-error.html b/testing/web-platform/tests/fetch/api/request/request-error.html new file mode 100644 index 00000000000..51db7378e92 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/request/request-error.html @@ -0,0 +1,104 @@ + + + + + Request error + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/request/request-idl.html b/testing/web-platform/tests/fetch/api/request/request-idl.html new file mode 100644 index 00000000000..0faefee3aa4 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/request/request-idl.html @@ -0,0 +1,85 @@ + + + + + Request idl interface + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/request/request-init-001.sub.html b/testing/web-platform/tests/fetch/api/request/request-init-001.sub.html new file mode 100644 index 00000000000..92206b45128 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/request/request-init-001.sub.html @@ -0,0 +1,92 @@ + + + + + Request init: simple cases + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/request/request-init-002.html b/testing/web-platform/tests/fetch/api/request/request-init-002.html new file mode 100644 index 00000000000..46246c11eaf --- /dev/null +++ b/testing/web-platform/tests/fetch/api/request/request-init-002.html @@ -0,0 +1,62 @@ + + + + + Request init: headers and body + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/request/request-init-003.sub.html b/testing/web-platform/tests/fetch/api/request/request-init-003.sub.html new file mode 100644 index 00000000000..41bafebb18d --- /dev/null +++ b/testing/web-platform/tests/fetch/api/request/request-init-003.sub.html @@ -0,0 +1,84 @@ + + + + + Request: init with request or url + + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/request/request-structure.html b/testing/web-platform/tests/fetch/api/request/request-structure.html new file mode 100644 index 00000000000..2d7d4dba7bf --- /dev/null +++ b/testing/web-platform/tests/fetch/api/request/request-structure.html @@ -0,0 +1,132 @@ + + + + + Request structure + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/resources/authentication.py b/testing/web-platform/tests/fetch/api/resources/authentication.py new file mode 100644 index 00000000000..a06d179e58e --- /dev/null +++ b/testing/web-platform/tests/fetch/api/resources/authentication.py @@ -0,0 +1,15 @@ +def main(request, response): + user = request.auth.username + password = request.auth.password + + if user == "user" and password == "password": + return "Authentication done" + + realm = "test" + if "realm" in request.GET: + realm = request.GET.first("realm") + + return ((401, "Unauthorized"), + [("WWW-Authenticate", 'Basic realm="' + realm + '"')], + "Please login with credentials 'user' and 'password'") + diff --git a/testing/web-platform/tests/fetch/api/resources/clean-stash.py b/testing/web-platform/tests/fetch/api/resources/clean-stash.py new file mode 100644 index 00000000000..3ae73105269 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/resources/clean-stash.py @@ -0,0 +1,6 @@ +def main(request, response): + token = request.GET.first("token") + if request.server.stash.take(token) is not None: + return "1" + else: + return "0" diff --git a/testing/web-platform/tests/fetch/api/resources/inspect-headers.py b/testing/web-platform/tests/fetch/api/resources/inspect-headers.py new file mode 100644 index 00000000000..c4ace18ab64 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/resources/inspect-headers.py @@ -0,0 +1,22 @@ +def main(request, response): + headers = [] + request_headers = [] + if "headers" in request.GET: + checked_headers = request.GET.first("headers").split("|") + for header in checked_headers: + if header in request.headers: + headers.append(("x-request-" + header, request.headers.get(header, "") )) + + if "cors" in request.GET: + if "Origin" in request.headers: + headers.append(("Access-Control-Allow-Origin", request.headers.get("Origin", ""))) + else: + headers.append(("Access-Control-Allow-Origin", "*")) + headers.append(("Access-Control-Allow-Credentials", "true")) + headers.append(("Access-Control-Allow-Methods", "GET, POST, HEAD")) + exposed_headers = ["x-request-" + header for header in checked_headers] + headers.append(("Access-Control-Expose-Headers", ", ".join(exposed_headers))) + headers.append(("Access-Control-Allow-Headers", ", ".join(request.headers))) + + headers.append(("content-type", "text/plain")) + return headers, "" diff --git a/testing/web-platform/tests/fetch/api/resources/method.py b/testing/web-platform/tests/fetch/api/resources/method.py new file mode 100644 index 00000000000..db234f9d123 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/resources/method.py @@ -0,0 +1,11 @@ +def main(request, response): + headers = [] + if "cors" in request.GET: + headers.append(("Access-Control-Allow-Origin", "*")) + headers.append(("Access-Control-Allow-Credentials", "true")) + headers.append(("Access-Control-Allow-Methods", "GET, POST, PUT, FOO")) + headers.append(("Access-Control-Allow-Headers", "x-test, x-foo")) + headers.append(("Access-Control-Expose-Headers", "x-request-method")) + + headers.append(("x-request-method", request.method)) + return headers, request.body diff --git a/testing/web-platform/tests/fetch/api/resources/preflight.py b/testing/web-platform/tests/fetch/api/resources/preflight.py new file mode 100644 index 00000000000..72dceba683d --- /dev/null +++ b/testing/web-platform/tests/fetch/api/resources/preflight.py @@ -0,0 +1,56 @@ +def main(request, response): + headers = [("Content-Type", "text/plain")] + stashed_data = {'control_request_headers': "", 'preflight': "0", 'preflight_referrer': ""} + + if "origin" in request.GET: + for origin in request.GET['origin'].split(", "): + headers.append(("Access-Control-Allow-Origin", origin)) + else: + headers.append(("Access-Control-Allow-Origin", "*")) + + if request.method == "OPTIONS": + if not "Access-Control-Request-Method" in request.headers: + response.set_error(400, "No Access-Control-Request-Method header") + return "ERROR: No access-control-request-method in preflight!" + + if "control_request_headers" in request.GET: + stashed_data['control_request_headers'] = request.headers.get("Access-Control-Request-Headers", "") + + if "max_age" in request.GET: + headers.append(("Access-Control-Max-Age", request.GET['max_age'])) + + if "allow_headers" in request.GET: + headers.append(("Access-Control-Allow-Headers", request.GET['allow_headers'])) + + if "allow_methods" in request.GET: + headers.append(("Access-Control-Allow-Methods", request.GET['allow_methods'])) + + preflight_status = 200 + if "preflight_status" in request.GET: + preflight_status = int(request.GET.first("preflight_status")) + + stashed_data['preflight'] = "1" + stashed_data['preflight_referrer'] = request.headers.get("Referer", "") + request.server.stash.put(request.GET.first("token"), stashed_data) + + return preflight_status, headers, "" + + token = None + if "token" in request.GET: + token = request.GET.first("token") + data = request.server.stash.take(token) + if data: + stashed_data = data + + #use x-* headers for returning value to bodyless responses + headers.append(("Access-Control-Expose-Headers", "x-did-preflight, x-control-request-headers, x-referrer, x-preflight-referrer, x-origin")) + headers.append(("x-did-preflight", stashed_data['preflight'])) + headers.append(("x-control-request-headers", stashed_data['control_request_headers'])) + headers.append(("x-preflight-referrer", stashed_data['preflight_referrer'])) + headers.append(("x-referrer", request.headers.get("Referer", "") )) + headers.append(("x-origin", request.headers.get("Origin", "") )) + + if token: + request.server.stash.put(token, stashed_data) + + return headers, "" diff --git a/testing/web-platform/tests/fetch/api/resources/redirect.py b/testing/web-platform/tests/fetch/api/resources/redirect.py new file mode 100644 index 00000000000..3767b223aac --- /dev/null +++ b/testing/web-platform/tests/fetch/api/resources/redirect.py @@ -0,0 +1,48 @@ +def main(request, response): + stashed_data = {'count': 0, 'preflight': "0"} + status = 302 + headers = [("Content-Type", "text/plain"), + ("Cache-Control", "no-cache"), + ("Pragma", "no-cache"), + ("Access-Control-Allow-Origin", "*")] + token = None + + if "token" in request.GET: + token = request.GET.first("token") + data = request.server.stash.take(token) + if data: + stashed_data = data + + if request.method == "OPTIONS": + if "allow_headers" in request.GET: + headers.append(("Access-Control-Allow-Headers", request.GET['allow_headers'])) + stashed_data['preflight'] = "1" + #Preflight is not redirected: return 200 + if not "redirect_preflight" in request.GET: + if token: + request.server.stash.put(request.GET.first("token"), stashed_data) + return 200, headers, "" + + if "redirect_status" in request.GET: + status = int(request.GET['redirect_status']) + + stashed_data['count'] += 1 + + #keep url parameters in location + url_parameters = "?" + "&".join(map(lambda x: x[0][0] + "=" + x[1][0], request.GET.items())) + #make sure location changes during redirection loop + url_parameters += "&count=" + str(stashed_data['count']) + + if "location" in request.GET: + headers.append(("Location", request.GET['location'] + url_parameters)) + + if token: + request.server.stash.put(request.GET.first("token"), stashed_data) + if "max_count" in request.GET: + max_count = int(request.GET['max_count']) + #stop redirecting and return count + if stashed_data['count'] > max_count: + # -1 because the last is not a redirection + return str(stashed_data['count'] - 1) + + return status, headers, "" diff --git a/testing/web-platform/tests/fetch/api/resources/top.txt b/testing/web-platform/tests/fetch/api/resources/top.txt new file mode 100644 index 00000000000..83a3157d14d --- /dev/null +++ b/testing/web-platform/tests/fetch/api/resources/top.txt @@ -0,0 +1 @@ +top \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/resources/trickle.py b/testing/web-platform/tests/fetch/api/resources/trickle.py new file mode 100644 index 00000000000..0e709445c59 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/resources/trickle.py @@ -0,0 +1,12 @@ +import time + +def main(request, response): + delay = float(request.GET.first("ms", 500)) / 1E3 + count = int(request.GET.first("count", 50)) + time.sleep(delay) + response.headers.set("Content-type", "text/plain") + response.write_status_headers() + time.sleep(delay); + for i in xrange(count): + response.writer.write_content("TEST_TRICKLE\n") + time.sleep(delay) diff --git a/testing/web-platform/tests/fetch/api/resources/utils.js b/testing/web-platform/tests/fetch/api/resources/utils.js new file mode 100644 index 00000000000..a090e1eebd5 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/resources/utils.js @@ -0,0 +1,68 @@ +var inWorker = false; +var RESOURCES_DIR = "../resources/"; + +try { + inWorker = !(self instanceof Window); +} catch (e) { + inWorker = true; +} + +function dirname(path) { + return path.replace(/\/[^\/]*$/, '/') +} + +function checkRequest(request, ExpectedValuesDict) { + for (var attribute in ExpectedValuesDict) { + switch(attribute) { + case "headers": + for (var key of ExpectedValuesDict["headers"].keys()) { + assert_equals(request["headers"].get(key), ExpectedValuesDict["headers"].get(key), + "Check headers attribute has " + key + ":" + ExpectedValuesDict["headers"].get(key)); + } + break; + + case "body": + //for checking body's content, a dedicated asyncronous/promise test should be used + assert_true(request["headers"].has("Content-Type") , "Check request has body using Content-Type header") + break; + + case "method": + case "referrer": + case "referrerPolicy": + case "credentials": + case "cache": + case "redirect": + case "integrity": + case "url": + case "destination": + assert_equals(request[attribute], ExpectedValuesDict[attribute], "Check " + attribute + " attribute") + break; + + default: + break; + } + } +} + +//check reader's text content in an asyncronous test +function readTextStream(reader, asyncTest, expectedValue, retrievedText) { + if (!retrievedText) + retrievedText = ""; + reader.read().then(function(data) { + if (!data.done) { + var decoder = new TextDecoder(); + retrievedText += decoder.decode(data.value); + readTextStream(reader, asyncTest, expectedValue, retrievedText); + return; + } + asyncTest.step(function() { + assert_equals(retrievedText, expectedValue, "Retrieve and verify stream"); + asyncTest.done(); + }); + }).catch(function(e) { + asyncTest.step(function() { + assert_unreached("Cannot read stream " + e); + asyncTest.done(); + }); + }); +} diff --git a/testing/web-platform/tests/fetch/api/response/response-clone.html b/testing/web-platform/tests/fetch/api/response/response-clone.html new file mode 100644 index 00000000000..8afcf36d831 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/response/response-clone.html @@ -0,0 +1,66 @@ + + + + + Response clone + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/response/response-consume.html b/testing/web-platform/tests/fetch/api/response/response-consume.html new file mode 100644 index 00000000000..14dcad795c2 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/response/response-consume.html @@ -0,0 +1,81 @@ + + + + + Response consume + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/response/response-error.html b/testing/web-platform/tests/fetch/api/response/response-error.html new file mode 100644 index 00000000000..1e68f6d01c6 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/response/response-error.html @@ -0,0 +1,39 @@ + + + + + Response error + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/response/response-idl.html b/testing/web-platform/tests/fetch/api/response/response-idl.html new file mode 100644 index 00000000000..e849856cee3 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/response/response-idl.html @@ -0,0 +1,69 @@ + + + + + Response idl interface + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/response/response-init-001.html b/testing/web-platform/tests/fetch/api/response/response-init-001.html new file mode 100644 index 00000000000..e36f90e4c82 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/response/response-init-001.html @@ -0,0 +1,63 @@ + + + + + Response init: simple cases + + + + + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/fetch/api/response/response-init-002.html b/testing/web-platform/tests/fetch/api/response/response-init-002.html new file mode 100644 index 00000000000..29008584a85 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/response/response-init-002.html @@ -0,0 +1,62 @@ + + + + + Response init: body and headers + + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/response/response-static-error.html b/testing/web-platform/tests/fetch/api/response/response-static-error.html new file mode 100644 index 00000000000..6e927a8bf62 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/response/response-static-error.html @@ -0,0 +1,25 @@ + + + + + Response: error static method + + + + + + + + + + diff --git a/testing/web-platform/tests/fetch/api/response/response-static-redirect.html b/testing/web-platform/tests/fetch/api/response/response-static-redirect.html new file mode 100644 index 00000000000..6a50440de36 --- /dev/null +++ b/testing/web-platform/tests/fetch/api/response/response-static-redirect.html @@ -0,0 +1,45 @@ + + + + + Response: redirect static method + + + + + + + + + + diff --git a/testing/web-platform/tests/html/OWNERS b/testing/web-platform/tests/html/OWNERS new file mode 100644 index 00000000000..210a621c919 --- /dev/null +++ b/testing/web-platform/tests/html/OWNERS @@ -0,0 +1,7 @@ +@Ms2ger +@gsnedders +@jgraham +@plehegar +@sideshowbarker +@zcorpan +@zqzhang diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_origin.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_origin.html new file mode 100644 index 00000000000..2325f4018aa --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_origin.html @@ -0,0 +1,14 @@ + + + + + + diff --git a/testing/web-platform/tests/html/dom/interfaces.html b/testing/web-platform/tests/html/dom/interfaces.html index f76d0ce38a7..8eb7df805fb 100644 --- a/testing/web-platform/tests/html/dom/interfaces.html +++ b/testing/web-platform/tests/html/dom/interfaces.html @@ -1591,7 +1591,7 @@ interface HTMLFormElement : HTMLElement { attribute DOMString target; readonly attribute HTMLFormControlsCollection elements; - readonly attribute long length; + readonly attribute unsigned long length; getter Element (unsigned long index); getter (RadioNodeList or Element) (DOMString name); diff --git a/testing/web-platform/tests/url/urltestdata.json b/testing/web-platform/tests/url/urltestdata.json index 1f787d795ef..1e8c68fc46b 100644 --- a/testing/web-platform/tests/url/urltestdata.json +++ b/testing/web-platform/tests/url/urltestdata.json @@ -1760,7 +1760,7 @@ { "input": "http://example.com/foo/%2e%2", "base": "about:blank", - "href": "http://example.com/foo/%2e%2", + "href": "http://example.com/foo/.%2", "origin": "http://example.com", "protocol": "http:", "username": "", @@ -1768,14 +1768,14 @@ "host": "example.com", "hostname": "example.com", "port": "", - "pathname": "/foo/%2e%2", + "pathname": "/foo/.%2", "search": "", "hash": "" }, { "input": "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar", "base": "about:blank", - "href": "http://example.com/%2e.bar", + "href": "http://example.com/..bar", "origin": "http://example.com", "protocol": "http:", "username": "", @@ -1783,7 +1783,7 @@ "host": "example.com", "hostname": "example.com", "port": "", - "pathname": "/%2e.bar", + "pathname": "/..bar", "search": "", "hash": "" }, diff --git a/testing/web-platform/tests/webgl/OWNERS b/testing/web-platform/tests/webgl/OWNERS new file mode 100644 index 00000000000..fd31fb27543 --- /dev/null +++ b/testing/web-platform/tests/webgl/OWNERS @@ -0,0 +1 @@ +@Ms2ger diff --git a/testing/web-platform/tests/websockets/Create-asciiSep-protocol-string.htm b/testing/web-platform/tests/websockets/Create-asciiSep-protocol-string.htm new file mode 100644 index 00000000000..7309009d052 --- /dev/null +++ b/testing/web-platform/tests/websockets/Create-asciiSep-protocol-string.htm @@ -0,0 +1,21 @@ + + + + W3C WebSocket API - Create WebSocket - ascii protocol string with separator + + + + + +
+ + + diff --git a/testing/web-platform/tests/websockets/Create-protocols-repeated-case-insensitive.htm b/testing/web-platform/tests/websockets/Create-protocols-repeated-case-insensitive.htm new file mode 100644 index 00000000000..f32ce5bfd58 --- /dev/null +++ b/testing/web-platform/tests/websockets/Create-protocols-repeated-case-insensitive.htm @@ -0,0 +1,18 @@ + + + + W3C WebSocket API - Create WebSocket - repeated protocols with different case + + + + + +
+ + + diff --git a/testing/web-platform/tests/websockets/websocket.js b/testing/web-platform/tests/websockets/websocket.js index 2d2697a1170..79b7bd59c58 100644 --- a/testing/web-platform/tests/websockets/websocket.js +++ b/testing/web-platform/tests/websockets/websocket.js @@ -8,6 +8,7 @@ var __CONTROLPATH = "control"; var __PROTOCOL = "echo"; var __PROTOCOLS = ["echo", "chat"]; var __REPEATED__PROTOCOLS = ["echo", "echo"]; +var __REPEATED__PROTOCOLS_CASE_INSENSITIVE = ["echo", "eCho"]; var __URL; var __IS__WEBSOCKET; var __PASS = "Pass"; @@ -47,6 +48,12 @@ function CreateWebSocketNonAsciiProtocol(nonAsciiProtocol) { wsocket = new WebSocket(__URL, nonAsciiProtocol); } +function CreateWebSocketWithAsciiSep(asciiWithSep) { + IsWebSocket(); + __URL = "ws://" + __SERVER__NAME + ":" + __PORT + "/" + __PATH; + wsocket = new WebSocket(__URL, asciiWithSep); +} + function CreateWebSocketWithBlockedPort(blockedPort) { IsWebSocket(); __URL = "wss://" + __SERVER__NAME + ":" + blockedPort + "/" + __PATH; @@ -71,6 +78,12 @@ function CreateWebSocketWithRepeatedProtocols() { wsocket = new WebSocket(__URL, __REPEATED__PROTOCOLS); } +function CreateWebSocketWithRepeatedProtocolsCaseInsensitive() { + IsWebSocket(); + __URL = "ws://" + __SERVER__NAME + ":" + __PORT + "/" + __PATH; + wsocket = new WebSocket(__URL, __REPEATED__PROTOCOLS_CASE_INSENSITIVE); +} + function CreateWebSocket(isSecure, isProtocol, isProtocols) { IsWebSocket(); if (isSecure) { diff --git a/testing/web-platform/tests/webvtt/OWNERS b/testing/web-platform/tests/webvtt/OWNERS new file mode 100644 index 00000000000..dd2b7600f63 --- /dev/null +++ b/testing/web-platform/tests/webvtt/OWNERS @@ -0,0 +1,4 @@ +@foolip +@r12a +@silviapfeiffer +@zcorpan