summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/XMLHttpRequest
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /testing/web-platform/tests/XMLHttpRequest
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'testing/web-platform/tests/XMLHttpRequest')
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/FormData-append.html99
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/OWNERS12
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/XMLHttpRequest-withCredentials.any.js40
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-after-receive.htm42
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-after-send.htm46
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-after-stop.htm32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-after-timeout.htm58
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-during-done.htm32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-during-open.htm14
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-during-open.js14
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-during-open.worker.js3
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-during-unsent.htm26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-during-upload.htm30
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-event-abort.htm45
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-event-listeners.htm25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-event-loadend.htm44
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-event-order.htm52
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-upload-event-abort.htm47
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/abort-upload-event-loadend.htm47
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/anonymous-mode-unsupported.htm40
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/data-uri.htm53
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-abort.htm29
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-error-order.sub.html35
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-error.sub.html25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-load.htm32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-loadend.htm35
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-loadstart.htm31
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-progress.htm29
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-readystate-sync-open.htm33
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-readystatechange-loaded.htm38
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-timeout-order.htm37
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-timeout.htm34
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-upload-progress-crossorigin.sub.htm27
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/event-upload-progress.htm26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/folder.txt1
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/formdata-blob.htm46
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/formdata-delete.htm65
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/formdata-foreach.html59
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/formdata-get.htm60
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/formdata-has.htm42
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/formdata-set.htm98
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/formdata.htm43
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/getallresponseheaders-cookies.htm38
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/getallresponseheaders-status.htm38
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/getresponseheader-case-insensitive.htm34
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/getresponseheader-chunked-trailer.htm32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/getresponseheader-cookies-and-more.htm36
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/getresponseheader-error-state.htm36
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/getresponseheader-server-date.htm29
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/getresponseheader-special-characters.htm34
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/getresponseheader-unsent-opened-state.htm32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/headers-normalize-response.htm42
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/interfaces.html171
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-after-abort.htm35
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-after-setrequestheader.htm33
-rwxr-xr-xtesting/web-platform/tests/XMLHttpRequest/open-during-abort.htm32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-method-bogus.htm28
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-method-case-insensitive.htm29
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-method-case-sensitive.htm31
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-method-insecure.htm29
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-method-responsetype-set-sync.htm32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-open-send.htm33
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-open-sync-send.htm31
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-referer.htm20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-send-open.htm33
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-sync-open-send.htm41
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-about-blank-window.htm23
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-base-inserted-after-open.htm24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-base-inserted.htm24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-base.htm22
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-bogus.htm25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-encoding.htm27
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-fragment.htm38
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-javascript-window-2.htm19
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-javascript-window.htm28
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-2.htm24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-3.htm24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-4.htm50
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-5.htm30
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-6.htm41
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-multi-window.htm31
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-worker-origin.htm43
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-url-worker-simple.htm25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/open-user-password-non-same-origin.htm25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/overridemimetype-done-state.htm26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/overridemimetype-headers-received-state-force-shiftjis.htm34
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/overridemimetype-invalid-mime-type.htm25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/overridemimetype-loading-state.htm32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/overridemimetype-open-state-force-utf-8.htm27
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/overridemimetype-open-state-force-xml.htm34
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/overridemimetype-unsent-state-force-shiftjis.htm27
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/preserve-ua-header-on-redirect.htm43
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/progress-events-response-data-gzip.htm83
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/readme.txt31
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/accept-language.py4
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/accept.py3
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth1/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth2/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth2/corsenabled.py20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth3/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth4/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth5/auth.py13
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth6/auth.py13
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth7/corsenabled.py20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth8/corsenabled-no-authorize.py20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/auth9/auth.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/authentication.py32
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/chunked.py18
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/conditional.py17
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/content.py18
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/corsenabled.py20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/delay.py6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/echo-method.py6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/empty-div-utf8-html.py5
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/folder.txt1
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/form.py2
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/gzip.py23
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/headers.py12
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/image.gifbin0 -> 167145 bytes
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/img-utf8-html.py5
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/img.jpgbin0 -> 108761 bytes
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/infinite-redirects.py24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/init.htm20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/inspect-headers.py22
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/invalid-utf8-html.py5
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/last-modified.py7
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/nocors/folder.txt1
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/parse-headers.py10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/redirect.py8
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/requri.py6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-1.htm23
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-2.htm20
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-helper.js29
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/shift-jis-html.py6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/status.py9
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/trickle.py15
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/upload.py15
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/utf16.txtbin0 -> 18 bytes
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/well-formed.xml4
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/win-1252-xml.py5
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-origin-referrer.js34
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-simple.js10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js83
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-aborted.js15
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-abortedonmain.js8
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overrides.js11
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overridesexpires.js12
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-runner.js21
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-simple.js6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconmain.js2
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconworker.js11
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-twice.js6
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout.js325
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/resources/zlib.py19
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/response-data-arraybuffer.htm54
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/response-data-blob.htm55
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/response-data-deflate.htm42
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/response-data-gzip.htm42
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/response-data-progress.htm51
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/response-invalid-responsetype.htm38
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/response-json.htm61
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/response-method.htm21
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responseText-status.html33
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responsetext-decoding.htm52
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responsetype.html96
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responseurl.html37
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responsexml-basic.htm33
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responsexml-document-properties.htm74
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responsexml-get-twice.htm66
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responsexml-media-type.htm41
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responsexml-non-document-types.htm45
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/responsexml-non-well-formed.htm30
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/security-consideration.sub.html36
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-accept-language.htm27
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-accept.htm24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-after-setting-document-domain.htm39
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-cors-not-enabled.htm28
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-cors.htm35
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-repeat-no-args.htm33
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader-and-arguments.htm36
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader-existing-session.htm53
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader.htm36
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-basic.htm27
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-competing-names-passwords.htm54
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-cors-basic-setrequestheader.htm38
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-cors-setrequestheader-no-cred.htm61
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-existing-session-manual.htm33
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-prompt-2-manual.htm25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-authentication-prompt-manual.htm25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-blob-with-no-mime-type.html51
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-conditional.htm34
-rwxr-xr-xtesting/web-platform/tests/XMLHttpRequest/send-content-type-charset.htm83
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-content-type-string.htm26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-data-arraybuffer.htm48
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-data-blob.htm62
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-data-es-object.htm61
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-data-formdata.htm43
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-data-unexpected-tostring.htm57
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-entity-body-basic.htm28
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-entity-body-document-bogus.htm26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-entity-body-document.htm61
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-entity-body-empty.htm26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-entity-body-get-head-async.htm39
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-entity-body-get-head.htm36
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-entity-body-none.htm40
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-network-error-async-events.sub.htm58
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-network-error-sync-events.sub.htm39
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-no-response-event-loadend.htm48
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-no-response-event-loadstart.htm48
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-no-response-event-order.htm45
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-non-same-origin.sub.htm33
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-receive-utf16.htm37
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-redirect-bogus-sync.htm26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-redirect-bogus.htm36
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-redirect-infinite-sync.htm24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-redirect-infinite.htm35
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-redirect-no-location.htm40
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-redirect-post-upload.htm124
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-redirect-to-cors.htm68
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-redirect-to-non-cors.htm37
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-redirect.htm36
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-response-event-order.htm40
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-loadend.htm40
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-loadstart.htm39
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-progress.htm39
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-send.htm13
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-send.js7
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-send.worker.js3
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-sync-blocks-async.htm66
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-load.htm38
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-loadend.htm38
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-order.htm51
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-sync-response-event-order.htm35
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-sync-timeout.htm30
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-timeout-events.htm76
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-usp.html10
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-usp.js48
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/send-usp.worker.js4
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-after-send.htm27
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-allow-empty-value.htm26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-allow-whitespace-in-value.htm27
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-before-open.htm18
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-bogus-name.htm59
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-bogus-value.htm37
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-case-insensitive.htm23
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-content-type.htm237
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-header-allowed.htm33
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-header-forbidden.htm42
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/setrequestheader-open-setrequestheader.htm60
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/status-async.htm62
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/status-basic.htm51
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/status-error.htm60
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/timeout-cors-async.htm43
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/timeout-sync.htm25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-basic.htm45
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-eventtarget.htm48
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-network-error-sync.htm34
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-network-error.htm39
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-defer-scripts-subframe.html17
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-defer-scripts.html15
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-scripts.html22
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader-subframe.html17
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader.html16
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-aborted.html26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-abortedonmain.html23
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-overrides.html23
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-overridesexpires.html23
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-simple.html24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-synconmain.html21
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-twice.html25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-aborted.html28
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-overrides.html24
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-overridesexpires.html25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-simple.html26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-synconworker.html25
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-twice.html26
-rw-r--r--testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-unsent.htm36
277 files changed, 9491 insertions, 0 deletions
diff --git a/testing/web-platform/tests/XMLHttpRequest/FormData-append.html b/testing/web-platform/tests/XMLHttpRequest/FormData-append.html
new file mode 100644
index 000000000..bf6c66d0f
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/FormData-append.html
@@ -0,0 +1,99 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>FormData.append</title>
+<link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-append">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form id="form" />
+<script>
+ function test_formdata(creator, verifier, description) {
+ async_test(description).step(function() {
+ var fd = creator();
+ var xhr = new XMLHttpRequest();
+ xhr.onload = this.step_func(function() {
+ verifier(xhr.responseText);
+ this.done();
+ });
+ xhr.open("POST", "resources/upload.py");
+ xhr.send(fd);
+ });
+ }
+
+ test_formdata(function() {
+ var fd = new FormData();
+ fd.append("name", new String("value"));
+ return fd;
+ }, function(data) {
+ assert_equals(data, "name=value,\n");
+ }, "Passing a String object to FormData.append should work.");
+
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataAppend1');
+ test(function() {
+ assert_equals(create_formdata(['key', 'value2'], ['key', 'value1']).get('key'), "value2");
+ }, 'testFormDataAppend2');
+ test(function() {
+ assert_equals(create_formdata(['key', undefined]).get('key'), "undefined");
+ }, 'testFormDataAppendUndefined1');
+ test(function() {
+ assert_equals(create_formdata(['key', undefined], ['key', 'value1']).get('key'), "undefined");
+ }, 'testFormDataAppendUndefined2');
+ test(function() {
+ assert_equals(create_formdata(['key', null]).get('key'), "null");
+ }, 'testFormDataAppendNull1');
+ test(function() {
+ assert_equals(create_formdata(['key', null], ['key', 'value1']).get('key'), "null");
+ }, 'testFormDataAppendNull2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataAppendToForm1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', 'value2');
+ fd.append('key', 'value1');
+ assert_equals(fd.get('key'), "value2");
+ }, 'testFormDataAppendToForm2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', undefined);
+ assert_equals(fd.get('key'), "undefined");
+ }, 'testFormDataAppendToFormUndefined1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', undefined);
+ fd.append('key', 'value1');
+ assert_equals(fd.get('key'), "undefined");
+ }, 'testFormDataAppendToFormUndefined2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', null);
+ assert_equals(fd.get('key'), "null");
+ }, 'testFormDataAppendToFormNull1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', null);
+ fd.append('key', 'value1');
+ assert_equals(fd.get('key'), "null");
+ }, 'testFormDataAppendToFormNull2');
+ test(function() {
+ var before = new Date(new Date().getTime() - 2000); // two seconds ago, in case there's clock drift
+ var fd = create_formdata(['key', new Blob(), 'blank.txt']).get('key');
+ assert_equals(fd.name, "blank.txt");
+ assert_equals(fd.type, "");
+ assert_equals(fd.size, 0);
+ assert_greater_than_equal(fd.lastModified, before);
+ assert_less_than_equal(fd.lastModified, new Date());
+ }, 'testFormDataAppendEmptyBlob');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/OWNERS b/testing/web-platform/tests/XMLHttpRequest/OWNERS
new file mode 100644
index 000000000..5962543a2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/OWNERS
@@ -0,0 +1,12 @@
+@emilio
+@hallvors
+@kangxu
+@caitp
+@Manishearth
+@plehegar
+@jungkees
+@ibelem
+@mathiasbynens
+@ronkorving
+@jdm
+@Ms2ger
diff --git a/testing/web-platform/tests/XMLHttpRequest/XMLHttpRequest-withCredentials.any.js b/testing/web-platform/tests/XMLHttpRequest/XMLHttpRequest-withCredentials.any.js
new file mode 100644
index 000000000..96e95c90f
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/XMLHttpRequest-withCredentials.any.js
@@ -0,0 +1,40 @@
+test(function() {
+ var client = new XMLHttpRequest()
+ assert_false(client.withCredentials, "withCredentials defaults to false")
+ client.withCredentials = true
+ assert_true(client.withCredentials, "is true after setting")
+}, "default value is false, set value is true")
+
+test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/delay.py?ms=1000", true)
+ client.withCredentials = true
+ assert_true(client.withCredentials, "set in OPEN state")
+}, "can also be set in OPEN state")
+
+test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/delay.py?ms=1000", false)
+ client.withCredentials = true
+ assert_true(client.withCredentials, "set in OPEN state")
+}, "setting on synchronous XHR")
+
+async_test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/delay.py?ms=1000")
+ client.send()
+ assert_throws("InvalidStateError", function() { client.withCredentials = true })
+ client.onreadystatechange = this.step_func(function() {
+ assert_throws("InvalidStateError", function() { client.withCredentials = true })
+ if (client.readyState === 4) {
+ this.done()
+ }
+ })
+}, "setting withCredentials when not in UNSENT, OPENED state (asynchronous)")
+
+test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/delay.py?ms=1000", false)
+ client.send();
+ assert_throws("InvalidStateError", function() { client.withCredentials = true })
+}, "setting withCredentials when in DONE state (synchronous)")
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-after-receive.htm b/testing/web-platform/tests/XMLHttpRequest/abort-after-receive.htm
new file mode 100644
index 000000000..bd97b6835
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-after-receive.htm
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: abort() after successful receive should not fire "abort" event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[5]"/>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+
+ test.step(function() {
+ var client = new XMLHttpRequest();
+
+ client.onreadystatechange = test.step_func(function() {
+ if (client.readyState == 4) {
+ // abort should not cause the "abort" event to fire
+
+ client.abort();
+
+ assert_equals(client.readyState, 0);
+
+ setTimeout(function(){ // use a timeout to catch any implementation that might queue an abort event for later - just in case
+ test.step(function(){test.done();});
+ }, 200);
+ }
+ });
+
+ client.onabort = test.step_func(function () {
+ // this should not fire!
+
+ assert_unreached("abort() should not cause the abort event to fire");
+ });
+
+ client.open("GET", "resources/well-formed.xml", true);
+ client.send(null);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-after-send.htm b/testing/web-platform/tests/XMLHttpRequest/abort-after-send.htm
new file mode 100644
index 000000000..523a0d616
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-after-send.htm
@@ -0,0 +1,46 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: abort() after send()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-event-order.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[1] following-sibling::ol/li[3] following-sibling::ol/li[4] following-sibling::ol/li[4]/ol/li[1] following-sibling::ol/li[4]/ol/li[3] following-sibling::ol/li[4]/ol/li[4] following-sibling::ol/li[4]/ol/li[5] following-sibling::ol/li[4]/ol/li[6] following-sibling::ol/li[5]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol/li[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol/li[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getallresponseheaders" data-tested-assertations="following::ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getresponseheader" data-tested-assertations="following::ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-statustext-attribute" data-tested-assertations="following::ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[1] following::dd[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ control_flag = false;
+ prepare_xhr_for_event_order_test(client);
+ client.addEventListener("readystatechange", test.step_func(function() {
+ if(client.readyState == 4) {
+ control_flag = true
+ assert_equals(client.responseXML, null)
+ assert_equals(client.responseText, "")
+ assert_equals(client.status, 0)
+ assert_equals(client.statusText, "")
+ assert_equals(client.getAllResponseHeaders(), "")
+ assert_equals(client.getResponseHeader('Content-Type'), null)
+ }
+ }))
+ client.open("GET", "resources/well-formed.xml", true)
+ client.send(null)
+ client.abort()
+ assert_true(control_flag)
+ assert_equals(client.readyState, 0)
+ assert_xhr_event_order_matches([1, "loadstart(0,0,false)", 4, "abort(0,0,false)", "loadend(0,0,false)"])
+ test.done()
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-after-stop.htm b/testing/web-platform/tests/XMLHttpRequest/abort-after-stop.htm
new file mode 100644
index 000000000..87e9ebcd8
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-after-stop.htm
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: abort event should fire when stop() method is used</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[3] following::dt[3]/following::dd[1]/p"/>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ var abortFired = false;
+ client.onabort = test.step_func(function (e) {
+ assert_equals(e.type, 'abort');
+ abortFired = true;
+ });
+ client.open("GET", "resources/delay.py?ms=3000", true);
+ client.send(null);
+ setTimeout(function(){
+ test.step(function(){
+ assert_equals(abortFired, true);
+ test.done();
+ });
+ }, 200);
+ window.stop();
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-after-timeout.htm b/testing/web-platform/tests/XMLHttpRequest/abort-after-timeout.htm
new file mode 100644
index 000000000..e8e84b1a3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-after-timeout.htm
@@ -0,0 +1,58 @@
+<!doctype html>
+<html>
+<head>
+ <title>XMLHttpRequest: abort() after a timeout should not fire "abort" event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[5]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]"/>
+</head>
+<body>
+<div id="log"></div>
+<script>
+ var test = async_test();
+
+ test.step(function() {
+ // timeout is 100ms
+ // the download would otherwise take 1000ms
+ // we check after 300ms to make sure abort does not fire an "abort" event
+
+ var timeoutFired = false;
+
+ var client = new XMLHttpRequest();
+
+ assert_true('timeout' in client, 'xhr.timeout is not supported in this user agent');
+
+ client.timeout = 100;
+
+ setTimeout(test.step_func(function() {
+ assert_true(timeoutFired);
+
+ // abort should not cause the "abort" event to fire
+ client.abort();
+
+ setTimeout(function(){ // use a timeout to catch any implementation that might queue an abort event for later - just in case
+ test.step(function(){test.done();});
+ }, 200);
+
+ assert_equals(client.readyState, 0);
+
+ test.done();
+ }), 300);
+
+ client.ontimeout = function () {
+ timeoutFired = true;
+ };
+
+ client.onabort = test.step_func(function () {
+ // this should not fire!
+
+ assert_unreached("abort() should not cause the abort event to fire");
+ });
+
+ client.open("GET", "/common/blank.html?pipe=trickle(d1)", true);
+ client.send(null);
+ });
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-during-done.htm b/testing/web-platform/tests/XMLHttpRequest/abort-during-done.htm
new file mode 100644
index 000000000..a8b604fe3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-during-done.htm
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: abort() during DONE</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4] following-sibling::ol/li[5]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ result = [],
+ expected = [1, 4] // open() -> 1, send() -> 4
+ client.onreadystatechange = function() {
+ test.step(function() {
+ result.push(client.readyState)
+ })
+ }
+ client.open("GET", "resources/well-formed.xml", false)
+ client.send(null)
+ assert_equals(client.readyState, 4)
+ client.abort()
+ assert_equals(client.readyState, 0)
+ assert_array_equals(result, expected)
+ test.done()
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-during-open.htm b/testing/web-platform/tests/XMLHttpRequest/abort-during-open.htm
new file mode 100644
index 000000000..dde94f239
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-during-open.htm
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: abort() during OPEN</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4] following-sibling::ol/li[5]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol/li[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script src="abort-during-open.js"></script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-during-open.js b/testing/web-platform/tests/XMLHttpRequest/abort-during-open.js
new file mode 100644
index 000000000..4ddb84fe8
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-during-open.js
@@ -0,0 +1,14 @@
+var test = async_test()
+test.step(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "...")
+ client.onreadystatechange = function() {
+ test.step(function() {
+ assert_unreached()
+ })
+ }
+ client.abort()
+ assert_equals(client.readyState, 0)
+ assert_throws("InvalidStateError", function() { client.send("test") }, "calling send() after abort()")
+})
+test.done()
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-during-open.worker.js b/testing/web-platform/tests/XMLHttpRequest/abort-during-open.worker.js
new file mode 100644
index 000000000..ffb687d0c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-during-open.worker.js
@@ -0,0 +1,3 @@
+importScripts("/resources/testharness.js");
+importScripts("abort-during-open.js");
+done();
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-during-unsent.htm b/testing/web-platform/tests/XMLHttpRequest/abort-during-unsent.htm
new file mode 100644
index 000000000..bc2f5cab5
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-during-unsent.htm
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: abort() during UNSENT</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4] following-sibling::ol/li[5]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ assert_unreached()
+ })
+ }
+ client.abort()
+ assert_equals(client.readyState, 0)
+ })
+ test.done()
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-during-upload.htm b/testing/web-platform/tests/XMLHttpRequest/abort-during-upload.htm
new file mode 100644
index 000000000..9fbc8b9bb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-during-upload.htm
@@ -0,0 +1,30 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: abort() while sending data</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-event-order.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4]/ol/li[7] following-sibling::ol/li[4]/ol/li[7]/ol/li[2] following-sibling::ol/li[4]/ol/li[7]/ol/li[3] following-sibling::ol/li[4]/ol/li[7]/ol/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#make-upload-progress-notifications" data-tested-assertations="following::ul[1]/li[1] following::ul[1]/li[2]/ol[1]/li[2] following::ul[1]/li[2]/ol[1]/li[3] following::ul[1]/li[2]/ol[1]/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test(document.title, {timeout:1100})
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ prepare_xhr_for_event_order_test(client);
+ client.open("POST", "resources/delay.py?ms=1000")
+ client.addEventListener("loadend", function(e) {
+ test.step(function() {
+ assert_xhr_event_order_matches([1, "loadstart(0,0,false)", "upload.loadstart(0,9999,true)", 4, "upload.abort(0,0,false)", "upload.loadend(0,0,false)", "abort(0,0,false)", "loadend(0,0,false)"]);
+ test.done()
+ })
+ });
+ client.send((new Array(10000)).join('a'))
+ client.abort()
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-event-abort.htm b/testing/web-platform/tests/XMLHttpRequest/abort-event-abort.htm
new file mode 100644
index 000000000..2382241ca
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-event-abort.htm
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4]/ol/li[5]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The abort() method: do not fire abort event in OPENED state when send() flag is unset. send() throws after abort().</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test()
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest()
+
+ xhr.onreadystatechange = function()
+ {
+ test.step(function()
+ {
+ if (xhr.readyState == 1)
+ {
+ xhr.abort();
+ }
+ });
+ };
+
+ xhr.onabort = function(e)
+ {
+ test.step(function()
+ {
+ assert_unreached('when abort() is called, state is OPENED with the send() flag being unset, must not fire abort event per spec')
+ });
+ };
+
+ xhr.open("GET", "./resources/content.py", true); // This should cause a readystatechange event that calls abort()
+ assert_throws("InvalidStateError", function(){ xhr.send() })
+ test.done()
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-event-listeners.htm b/testing/web-platform/tests/XMLHttpRequest/abort-event-listeners.htm
new file mode 100644
index 000000000..1c50ed394
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-event-listeners.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: abort() should not reset event listeners</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[6] following-sibling::ol/li[7]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ test = function() {}
+ client.onreadystatechange = test
+ client.open("GET", "resources/well-formed.xml")
+ client.send(null)
+ client.abort()
+ assert_equals(client.onreadystatechange, test)
+ })
+ test.done()
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-event-loadend.htm b/testing/web-platform/tests/XMLHttpRequest/abort-event-loadend.htm
new file mode 100644
index 000000000..8b8dfdaa4
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-event-loadend.htm
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4]/ol/li[6]"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The abort() method: Fire a progress event named loadend</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test(function(test)
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.onloadstart = function()
+ {
+ test.step(function()
+ {
+ if (xhr.readyState == 1)
+ {
+ xhr.abort();
+ }
+ });
+ };
+
+ xhr.onloadend = function(e)
+ {
+ test.step(function()
+ {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "loadend");
+ test.done();
+ });
+ };
+
+ xhr.open("GET", "resources/content.py", true);
+ xhr.send();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-event-order.htm b/testing/web-platform/tests/XMLHttpRequest/abort-event-order.htm
new file mode 100644
index 000000000..f05c20628
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-event-order.htm
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4]/ol/li[3] following-sibling::ol/li[4]/ol/li[5] following-sibling::ol/li[4]/ol/li[6] following-sibling::ol/li[4]/ol/li[7]/ol/li[3] following-sibling::ol/li[4]/ol/li[7]/ol/li[4] following-sibling::ol/li[5]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-event-order.js"></script>
+ <title>XMLHttpRequest: The abort() method: abort and loadend events</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ prepare_xhr_for_event_order_test(xhr);
+
+ xhr.addEventListener("loadstart", function() {
+ test.step(function()
+ {
+ var readyState = xhr.readyState;
+ if (readyState == 1)
+ {
+ xhr.abort();
+ VerifyResult();
+ } else {
+ assert_unreached('Loadstart event should not fire in readyState '+readyState);
+ }
+ });
+ });
+
+ function VerifyResult()
+ {
+ test.step(function()
+ {
+ assert_xhr_event_order_matches([1, "loadstart(0,0,false)", 4, "upload.abort(0,0,false)", "upload.loadend(0,0,false)", "abort(0,0,false)", "loadend(0,0,false)"]);
+
+ assert_equals(xhr.readyState, 0, 'state should be UNSENT');
+ test.done();
+ });
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send("Test Message");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-upload-event-abort.htm b/testing/web-platform/tests/XMLHttpRequest/abort-upload-event-abort.htm
new file mode 100644
index 000000000..1d045448b
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-upload-event-abort.htm
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4]/ol/li[7]/ol/li[3]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The abort() method: Fire a progress event named abort on the XMLHttpRequestUpload object</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.onloadstart = function()
+ {
+ test.step(function()
+ {
+ if (xhr.readyState == 1)
+ {
+ xhr.abort();
+ }
+ });
+ };
+
+ xhr.upload.onabort = function(e)
+ {
+ test.step(function()
+ {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "abort");
+ assert_equals(e.target, xhr.upload);
+ test.done();
+ });
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send("Test Message");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/abort-upload-event-loadend.htm b/testing/web-platform/tests/XMLHttpRequest/abort-upload-event-loadend.htm
new file mode 100644
index 000000000..5b10b6530
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-upload-event-loadend.htm
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4]/ol/li[7]/ol/li[4]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The abort() method: Fire a progress event named loadend on the XMLHttpRequestUpload object</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.onloadstart = function()
+ {
+ test.step(function ()
+ {
+ if (xhr.readyState == 1)
+ {
+ xhr.abort();
+ }
+ });
+ };
+
+ xhr.upload.onloadend = function(e)
+ {
+ test.step(function()
+ {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "loadend");
+ assert_equals(e.target, xhr.upload);
+ test.done();
+ });
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send("Test Message");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/anonymous-mode-unsupported.htm b/testing/web-platform/tests/XMLHttpRequest/anonymous-mode-unsupported.htm
new file mode 100644
index 000000000..9cacf61b7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/anonymous-mode-unsupported.htm
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: anonymous mode unsupported</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ /*
+ Older versions of the XMLHttpRequest spec had an 'anonymous' mode
+ The point of this mode was to handle same-origin requests like other-origin requests,
+ i.e. require preflight, drop authentication data (cookies and HTTP auth)
+ Also the Origin: and Referer: headers would not be sent
+
+ This mode was dropped due to lack of implementations and interest,
+ and this test is here just to assert failure if any implementation
+ supports this based on an older spec version.
+ */
+ document.cookie = 'test=anonymous-mode-unsupported'
+ test = async_test();
+ test.add_cleanup(function(){
+ // make sure we clean up the cookie again to avoid confusing other tests..
+ document.cookie = 'test=;expires=Fri, 28 Feb 2014 07:25:59 GMT';
+ })
+ test.step(function() {
+ var client = new XMLHttpRequest({anonymous:true})
+ client.open("GET", "resources/inspect-headers.py?filter_name=cookie")
+ client.onreadystatechange = test.step_func(function(){
+ if(client.readyState === 4){
+ assert_equals(client.responseText, 'cookie: test=anonymous-mode-unsupported\n', 'The deprecated anonymous:true should be ignored, cookie sent anyway')
+ test.done();
+ }
+ });
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/data-uri.htm b/testing/web-platform/tests/XMLHttpRequest/data-uri.htm
new file mode 100644
index 000000000..8c2970583
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/data-uri.htm
@@ -0,0 +1,53 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>XMLHttpRequest: data uri</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#data:-urls-and-http" data-tested-assertations="following::ul/li[1] following::ul/li[2] following::ul/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ul/li[10]/dl/dt[2]" />
+<div id="log"></div>
+
+<script>
+ function do_test(method, uri, charset, testNamePostfix) {
+ if (typeof charset === 'undefined' || charset === null) charset = 'text/plain';
+ var test = async_test("XHR method " + method + " with charset " + charset+(testNamePostfix||''));
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onreadystatechange = test.step_func(function () {
+ if (client.readyState !== 4) {
+ return;
+ }
+
+ // Note: fetching a data URL with a non-GET method returns a network
+ // error per <http://fetch.spec.whatwg.org/#basic-fetch>.
+ if (method.toUpperCase() !== 'GET') {
+ assert_equals(client.status, 0);
+ assert_equals(client.responseText, '');
+ assert_equals(client.statusText, '');
+ test.done();
+ return;
+ }
+
+ assert_equals(client.responseText, "Hello, World!");
+ assert_equals(client.status, 200);
+ assert_equals(client.getResponseHeader('Content-Type'), charset);
+ var allHeaders = client.getAllResponseHeaders();
+ assert_regexp_match(allHeaders, /content\-type\:/i, 'getAllResponseHeaders() includes Content-Type');
+ assert_false(/content\-length\:/i.test(allHeaders), 'getAllResponseHeaders() must not include Content-Length');
+ test.done();
+ });
+ client.open(method, uri);
+ client.send(null);
+ });
+ }
+ do_test('GET', "data:text/plain,Hello, World!");
+ do_test('GET', "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==", undefined, " (base64)");
+ do_test('GET', "data:text/html,Hello, World!", 'text/html');
+ do_test('GET', "data:text/html;charset=UTF-8,Hello, World!", 'text/html;charset=UTF-8');
+ do_test('GET', "data:image/png,Hello, World!", 'image/png');
+ do_test('POST', "data:text/plain,Hello, World!");
+ do_test('PUT', "data:text/plain,Hello, World!");
+ do_test('DELETE', "data:text/plain,Hello, World!");
+ do_test('HEAD', "data:text/plain,Hello, World!");
+ do_test('UNICORN', "data:text/plain,Hello, World!");
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-abort.htm b/testing/web-platform/tests/XMLHttpRequest/event-abort.htm
new file mode 100644
index 000000000..ce8d937d7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-abort.htm
@@ -0,0 +1,29 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: abort event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onabort" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-abort" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-abort" data-tested-assertations="following::ol//ol//ol/li[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onabort = test.step_func(function() {
+ test.done();
+ });
+ client.open("GET", "resources/well-formed.xml");
+ client.send(null);
+ client.abort();
+ setTimeout(test.step_func(function () {
+ assert_unreached("onabort not called after 4 ms");
+ }), 4);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-error-order.sub.html b/testing/web-platform/tests/XMLHttpRequest/event-error-order.sub.html
new file mode 100644
index 000000000..9be8b4a1b
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-error-order.sub.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="assert" content="Check the order of events fired when the request has failed.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-event-order.js"></script>
+ <title>XMLHttpRequest: event - error (order of events)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ prepare_xhr_for_event_order_test(xhr);
+
+ xhr.addEventListener("loadend", function() {
+ test.step(function() {
+ // no progress events due to CORS failure
+ assert_xhr_event_order_matches([1, "loadstart(0,0,false)", "upload.loadstart(0,12,true)", 2, 4, "upload.error(0,0,false)", "upload.loadend(0,0,false)", "error(0,0,false)", "loadend(0,0,false)"]);
+ test.done();
+ });
+ });
+
+ xhr.open("POST", "http://nonexistent-origin.{{host}}:{{ports[http][0]}}", true);
+ xhr.send("Test Message");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-error.sub.html b/testing/web-platform/tests/XMLHttpRequest/event-error.sub.html
new file mode 100644
index 000000000..3171c49d7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-error.sub.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>XMLHttpRequest Test: event - error</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="Check if event onerror is fired When the request has failed.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<script>
+
+async_test(function (t) {
+ var client = new XMLHttpRequest();
+ client.onerror = t.step_func(function(e) {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "error");
+ t.done();
+ });
+
+ client.open("GET", "http://nonexistent-origin.{{host}}:{{ports[http][0]}}");
+ client.send("null");
+}, document.title);
+
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-load.htm b/testing/web-platform/tests/XMLHttpRequest/event-load.htm
new file mode 100644
index 000000000..9098eebc7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-load.htm
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>XMLHttpRequest: The send() method: Fire an event named load (synchronous flag is unset)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onload" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-load" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::a[contains(@href,'#switch-done')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::ol/li[6]" />
+<div id="log"></div>
+
+<script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onload = test.step_func(function(e) {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "load");
+ assert_equals(client.readyState, 4);
+ test.done();
+ });
+ client.onreadystatechange = test.step_func(function() {
+ if (client.readyState !== 4) return;
+
+ setTimeout(test.step_func(function() {
+ assert_unreached("Didn't get load event within 4ms of readystatechange==4");
+ }), 4);
+ });
+ client.open("GET", "resources/well-formed.xml");
+ client.send(null);
+ });
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-loadend.htm b/testing/web-platform/tests/XMLHttpRequest/event-loadend.htm
new file mode 100644
index 000000000..b0c621317
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-loadend.htm
@@ -0,0 +1,35 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: loadend event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadend" data-tested-assertations="/../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="/../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="/following-sibling::ol/li[10]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::a[contains(@href,'#switch-done')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::ol[1]/li[7]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onloadend = test.step_func(function(e) {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "loadend");
+ test.done();
+ });
+ client.onreadystatechange = function() {
+ if (client.readyState !== 4) return;
+ setTimeout(test.step_func(function() {
+ assert_unreached("onloadend not called after 100 ms");
+ }), 100);
+ };
+ client.open("GET", "resources/well-formed.xml");
+ client.send(null);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-loadstart.htm b/testing/web-platform/tests/XMLHttpRequest/event-loadstart.htm
new file mode 100644
index 000000000..514900303
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-loadstart.htm
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: loadstart event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol/li[9]/ol/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onloadstart = test.step_func(function(e) {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "loadstart");
+ assert_equals(client.readyState, 1);
+ test.done();
+ });
+ setTimeout(test.step_func(function () {
+ assert_unreached("onloadstart not called after 500 ms");
+ }), 500);
+ client.open("GET", "resources/well-formed.xml");
+ client.send(null);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-progress.htm b/testing/web-platform/tests/XMLHttpRequest/event-progress.htm
new file mode 100644
index 000000000..f2f40b85b
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-progress.htm
@@ -0,0 +1,29 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>XMLHttpRequest: The send() method: Fire a progress event named progress (synchronous flag is unset)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onprogress" data-tested-assertations="../.." />
+<link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-progress" data-tested-assertations="../.." />
+<link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::*//a[contains(@href,'#make-progress-notifications')]" />
+<link rel="help" href="https://xhr.spec.whatwg.org/#make-progress-notifications" data-tested-assertations=".." />
+<link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::li[5]" />
+<div id="log"></div>
+<script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onprogress = test.step_func(function(e) {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "progress");
+ test.done();
+ });
+ client.onreadystatechange = test.step_func(function() {
+ if (client.readyState === 4)
+ assert_unreached("onprogress not called.");
+ });
+ client.open("GET", "resources/trickle.py?count=4&delay=150");
+ client.send(null);
+ });
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-readystate-sync-open.htm b/testing/web-platform/tests/XMLHttpRequest/event-readystate-sync-open.htm
new file mode 100644
index 000000000..ae9697ea1
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-readystate-sync-open.htm
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() call fires sync readystate event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[13]/ol[1]/li[2]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ var eventsFired = []
+ client.onreadystatechange = function(){
+ eventsFired.push(client.readyState)
+ }
+ client.open('GET', "...", false)
+ assert_array_equals(eventsFired, [1])
+ }, document.title + ' (sync)')
+ test(function() {
+ var client = new XMLHttpRequest()
+ var eventsFired = []
+ client.onreadystatechange = function(){
+ eventsFired.push(client.readyState)
+ }
+ client.open('GET', "...", true)
+ assert_array_equals(eventsFired, [1])
+ }, document.title + ' (async)')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-readystatechange-loaded.htm b/testing/web-platform/tests/XMLHttpRequest/event-readystatechange-loaded.htm
new file mode 100644
index 000000000..4368f8c9a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-readystatechange-loaded.htm
@@ -0,0 +1,38 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>XMLHttpRequest: the LOADING state change should only happen once</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[10]/dt[1]">
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[7] following::a[contains(@href,'#switch-loading')]/..">
+ <link rel="help" href="https://xhr.spec.whatwg.org/#switch-loading" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2]">
+</head>
+
+<div id="log"></div>
+
+<script>
+
+var test = async_test();
+
+test.step(function() {
+ var client = new XMLHttpRequest();
+ var countedLoading = 0;
+
+ client.onreadystatechange = test.step_func(function() {
+ if (client.readyState === 3) {
+ countedLoading += 1;
+ }
+
+ if (client.readyState === 4) {
+ assert_equals(countedLoading, 1, "LOADING state change may only be emitted once");
+
+ test.done();
+ }
+ });
+
+ client.open("GET", "resources/trickle.py?count=10"); // default timeout in trickle.py is 1/2 sec, so this request will take 5 seconds to complete
+ client.send(null);
+});
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-timeout-order.htm b/testing/web-platform/tests/XMLHttpRequest/event-timeout-order.htm
new file mode 100644
index 000000000..7376ca2f8
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-timeout-order.htm
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="assert" content="Check the order of events fired when the request has failed.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-event-order.js"></script>
+ <title>XMLHttpRequest: event - timeout (order of events)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ prepare_xhr_for_event_order_test(xhr);
+ xhr.addEventListener("loadend", function() {
+ test.step(function() {
+ assert_xhr_event_order_matches([1, "loadstart(0,0,false)", "upload.loadstart(0,12,true)", 4, "upload.timeout(0,0,false)", "upload.loadend(0,0,false)", "timeout(0,0,false)", "loadend(0,0,false)"]);
+ test.done();
+ });
+ });
+
+ xhr.timeout = 5;
+ xhr.open("POST", "resources/delay.py?ms=20000");
+ xhr.send("Test Message");
+ setTimeout(test.step_func(function () {
+ assert_unreached("ontimeout not called.");
+ }), 10);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-timeout.htm b/testing/web-platform/tests/XMLHttpRequest/event-timeout.htm
new file mode 100644
index 000000000..3368efc4b
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-timeout.htm
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: timeout event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-timeout" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following-sibling::ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.ontimeout = function() {
+ test.step(function() {
+ assert_equals(client.readyState, 4);
+ test.done();
+ });
+ };
+ client.timeout = 5;
+ client.open("GET", "resources/delay.py?ms=20000");
+ client.send(null);
+ setTimeout(test.step_func(function () {
+ assert_unreached("ontimeout not called.");
+ }), 10);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-upload-progress-crossorigin.sub.htm b/testing/web-platform/tests/XMLHttpRequest/event-upload-progress-crossorigin.sub.htm
new file mode 100644
index 000000000..66461689c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-upload-progress-crossorigin.sub.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>XMLHttpRequest: upload progress event for cross-origin requests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onprogress" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::*//a[contains(@href,'#make-upload-progress-notifications')] following::ol[1]/li[8]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#make-upload-progress-notifications" data-tested-assertations=".. ../following::ul/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-upload" data-tested-assertations=".." />
+
+<div id="log"></div>
+<script src="/common/get-host-info.sub.js"></script>
+<script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.upload.onprogress = test.step_func(function() {
+ test.done();
+ });
+ client.onload = test.step_func(function() {
+ assert_unreached("onprogress not called.");
+ });
+ client.open("POST", get_host_info().HTTP_REMOTE_ORIGIN + "/XMLHttpRequest/resources/corsenabled.py");
+ client.send("This is a test string.");
+ });
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/event-upload-progress.htm b/testing/web-platform/tests/XMLHttpRequest/event-upload-progress.htm
new file mode 100644
index 000000000..98c76cc3f
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/event-upload-progress.htm
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>XMLHttpRequest: upload progress event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onprogress" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::*//a[contains(@href,'#make-upload-progress-notifications')] following::ol[1]/li[8]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#make-upload-progress-notifications" data-tested-assertations=".. ../following::ul/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-upload" data-tested-assertations=".." />
+
+<div id="log"></div>
+<script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.upload.onprogress = test.step_func(function() {
+ test.done();
+ });
+ client.onreadystatechange = test.step_func(function() {
+ if (client.readyState === 4) assert_unreached("onprogress not called.");
+ });
+ client.open("POST", "resources/upload.py");
+ client.send("This is a test string.");
+ });
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/folder.txt b/testing/web-platform/tests/XMLHttpRequest/folder.txt
new file mode 100644
index 000000000..bf1a1fdef
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/folder.txt
@@ -0,0 +1 @@
+top
diff --git a/testing/web-platform/tests/XMLHttpRequest/formdata-blob.htm b/testing/web-platform/tests/XMLHttpRequest/formdata-blob.htm
new file mode 100644
index 000000000..5efef7b61
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/formdata-blob.htm
@@ -0,0 +1,46 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>XMLHttpRequest: upload formdata with blob</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#interface-formdata" data-tested-assertations="following::P[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata" data-tested-assertations="following::P[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-append" data-tested-assertations=".. following::P[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-append" data-tested-assertations="following::P[2] following::UL[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-FormData" data-tested-assertations="following::DD[1]" />
+<div id="log"></div>
+<script>
+ function do_test (name, fd, expected) {
+ var test = async_test(name);
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onreadystatechange = test.step_func(function () {
+ if (client.readyState !== 4) return;
+ assert_equals(client.responseText, expected);
+ test.done();
+ });
+ client.open("POST", "resources/upload.py");
+ client.send(fd);
+ });
+ }
+
+ function create_formdata () {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ }
+ return fd;
+ }
+
+ do_test("formdata with blob", create_formdata(['key', new Blob(['value'], {type: 'text/x-value'})]), '\nkey=blob:text/x-value:5,');
+ do_test("formdata with named blob", create_formdata(['key', new Blob(['value'], {type: 'text/x-value'}), 'blob.txt']), '\nkey=blob.txt:text/x-value:5,');
+ // If 3rd argument is given and 2nd is not a Blob, formdata.append() should throw
+ var test = async_test('formdata.append() should throw if value is string and file name is given'); // needs to be async just because the others above are
+ test.step(function(){
+ assert_throws(new TypeError(), function(){
+ create_formdata('a', 'b', 'c');
+ });
+ });
+ test.done();
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/formdata-delete.htm b/testing/web-platform/tests/XMLHttpRequest/formdata-delete.htm
new file mode 100644
index 000000000..283b44b5a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/formdata-delete.htm
@@ -0,0 +1,65 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>FormData: delete</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-get" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-getall" />
+<div id="log"></div>
+<form id="form1">
+ <input type="hidden" name="key" value="value1">
+ <input type="hidden" name="key" value="value2">
+</form>
+<form id="form2">
+ <input type="hidden" name="key1" value="value1">
+ <input type="hidden" name="key2" value="value2">
+</form>
+<form id="empty-form" />
+<script>
+ test(function() {
+ var fd = create_formdata(['key', 'value1'], ['key', 'value2']);
+ fd.delete('key');
+ assert_equals(fd.get('key'), null);
+ }, 'testFormDataDelete');
+ test(function() {
+ var fd = new FormData(document.getElementById('form1'));
+ fd.delete('key');
+ assert_equals(fd.get('key'), null);
+ }, 'testFormDataDeleteFromForm');
+ test(function() {
+ var fd = new FormData(document.getElementById('form1'));
+ fd.delete('nil');
+ assert_equals(fd.get('key'), 'value1');
+ }, 'testFormDataDeleteFromFormNonExistentKey');
+ test(function() {
+ var fd = new FormData(document.getElementById('form2'));
+ fd.delete('key1');
+ assert_equals(fd.get('key1'), null);
+ assert_equals(fd.get('key2'), 'value2');
+ }, 'testFormDataDeleteFromFormOtherKey');
+ test(function() {
+ var fd = new FormData(document.getElementById('empty-form'));
+ fd.delete('key');
+ assert_equals(fd.get('key'), null);
+ }, 'testFormDataDeleteFromEmptyForm');
+ test(function() {
+ var fd = create_formdata(['key', 'value1'], ['key', 'value2']);
+ fd.delete('nil');
+ assert_equals(fd.get('key'), 'value1');
+ }, 'testFormDataDeleteNonExistentKey');
+ test(function() {
+ var fd = create_formdata(['key1', 'value1'], ['key2', 'value2']);
+ fd.delete('key1');
+ assert_equals(fd.get('key1'), null);
+ assert_equals(fd.get('key2'), 'value2');
+ }, 'testFormDataDeleteOtherKey');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/formdata-foreach.html b/testing/web-platform/tests/XMLHttpRequest/formdata-foreach.html
new file mode 100644
index 000000000..9b10367ae
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/formdata-foreach.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>FormData: foreach</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#interface-formdata" />
+<script>
+ var fd = new FormData();
+ fd.append('n1', 'v1');
+ fd.append('n2', 'v2');
+ fd.append('n3', 'v3');
+ fd.append('n1', 'v4');
+ fd.append('n2', 'v5');
+ fd.append('n3', 'v6');
+ fd.delete('n2');
+ var expected_keys = ['n1', 'n3', 'n1', 'n3'];
+ var expected_values = ['v1', 'v3', 'v4', 'v6'];
+ test(function() {
+ var mykeys = [], myvalues = [];
+ for(var entry of fd) {
+ assert_equals(entry.length, 2,
+ 'Default iterator should yield key/value pairs');
+ mykeys.push(entry[0]);
+ myvalues.push(entry[1]);
+ }
+ assert_array_equals(mykeys, expected_keys,
+ 'Default iterator should see duplicate keys');
+ assert_array_equals(myvalues, expected_values,
+ 'Default iterator should see non-deleted values');
+ }, 'Iterator should return duplicate keys and non-deleted values');
+ test(function() {
+ var mykeys = [], myvalues = [];
+ for(var entry of fd.entries()) {
+ assert_equals(entry.length, 2,
+ 'entries() iterator should yield key/value pairs');
+ mykeys.push(entry[0]);
+ myvalues.push(entry[1]);
+ }
+ assert_array_equals(mykeys, expected_keys,
+ 'entries() iterator should see duplicate keys');
+ assert_array_equals(myvalues, expected_values,
+ 'entries() iterator should see non-deleted values');
+ }, 'Entries iterator should return duplicate keys and non-deleted values');
+ test(function() {
+ var mykeys = [];
+ for(var entry of fd.keys())
+ mykeys.push(entry);
+ assert_array_equals(mykeys, expected_keys,
+ 'keys() iterator should see duplicate keys');
+ }, 'Keys iterator should return duplicates');
+ test(function() {
+ var myvalues = [];
+ for(var entry of fd.values())
+ myvalues.push(entry);
+ assert_array_equals(myvalues, expected_values,
+ 'values() iterator should see non-deleted values');
+ }, 'Values iterator should return non-deleted values');
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/formdata-get.htm b/testing/web-platform/tests/XMLHttpRequest/formdata-get.htm
new file mode 100644
index 000000000..b71a72fa9
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/formdata-get.htm
@@ -0,0 +1,60 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>FormData: get and getAll</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-get" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-getall" />
+<div id="log"></div>
+<form id="form">
+ <input type="hidden" name="key" value="value1">
+ <input type="hidden" name="key" value="value2">
+</form>
+<form id="empty-form" />
+<script>
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1'], ['key', 'value2']).get('key'), "value1");
+ }, 'testFormDataGet');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('form')).get('key'), "value1");
+ }, 'testFormDataGetFromForm');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('form')).get('nil'), null);
+ }, 'testFormDataGetFromFormNull');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('empty-form')).get('key'), null);
+ }, 'testFormDataGetFromEmptyForm');
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1'], ['key', 'value2']).get('nil'), null);
+ }, 'testFormDataGetNull1');
+ test(function() {
+ assert_equals(create_formdata().get('key'), null);
+ }, 'testFormDataGetNull2');
+ test(function() {
+ assert_array_equals(create_formdata(['key', 'value1'], ['key', 'value2']).getAll('key'), ["value1", "value2"]);
+ }, 'testFormDataGetAll');
+ test(function() {
+ assert_array_equals(create_formdata(['key', 'value1'], ['key', 'value2']).getAll('nil'), []);
+ }, 'testFormDataGetAllEmpty1');
+ test(function() {
+ assert_array_equals(create_formdata().getAll('key'), []);
+ }, 'testFormDataGetAllEmpty2');
+ test(function() {
+ assert_array_equals(new FormData(document.getElementById('form')).getAll('key'), ["value1", "value2"]);
+ }, 'testFormDataGetAllFromForm');
+ test(function() {
+ assert_array_equals(new FormData(document.getElementById('form')).getAll('nil'), []);
+ }, 'testFormDataGetAllFromFormNull');
+ test(function() {
+ assert_array_equals(new FormData(document.getElementById('empty-form')).getAll('key'), []);
+ }, 'testFormDataGetAllFromEmptyForm');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/formdata-has.htm b/testing/web-platform/tests/XMLHttpRequest/formdata-has.htm
new file mode 100644
index 000000000..ecd22b4e3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/formdata-has.htm
@@ -0,0 +1,42 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>FormData: has</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-get" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-getall" />
+<div id="log"></div>
+<form id="form">
+ <input type="hidden" name="key" value="value1">
+ <input type="hidden" name="key" value="value2">
+</form>
+<form id="empty-form" />
+<script>
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1'], ['key', 'value2']).has('key'), true);
+ }, 'testFormDataHas');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('form')).has('key'), true);
+ }, 'testFormDataHasFromForm');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('form')).has('nil'), false);
+ }, 'testFormDataHasFromFormNull');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('empty-form')).has('key'), false);
+ }, 'testFormDataHasFromEmptyForm');
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1'], ['key', 'value2']).has('nil'), false);
+ }, 'testFormDataHasEmpty1');
+ test(function() {
+ assert_equals(create_formdata().has('key'), false);
+ }, 'testFormDataHasEmpty2');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/formdata-set.htm b/testing/web-platform/tests/XMLHttpRequest/formdata-set.htm
new file mode 100644
index 000000000..f030caa78
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/formdata-set.htm
@@ -0,0 +1,98 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>FormData: set</title>
+<link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-set">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form id="form" />
+<script>
+ function test_formdata(creator, verifier, description) {
+ async_test(description).step(function() {
+ var fd = creator();
+ var xhr = new XMLHttpRequest();
+ xhr.onload = this.step_func(function() {
+ verifier(xhr.responseText);
+ this.done();
+ });
+ xhr.open("POST", "resources/upload.py");
+ xhr.send(fd);
+ });
+ }
+
+ test_formdata(function() {
+ var fd = new FormData();
+ fd.set("name", new String("value"));
+ return fd;
+ }, function(data) {
+ assert_equals(data, "name=value,\n");
+ }, "Passing a String object to FormData.set should work");
+
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataSet1');
+ test(function() {
+ assert_equals(create_formdata(['key', 'value2'], ['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataSet2');
+ test(function() {
+ assert_equals(create_formdata(['key', undefined]).get('key'), "undefined");
+ }, 'testFormDataSetUndefined1');
+ test(function() {
+ assert_equals(create_formdata(['key', undefined], ['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataSetUndefined2');
+ test(function() {
+ assert_equals(create_formdata(['key', null]).get('key'), "null");
+ }, 'testFormDataSetNull1');
+ test(function() {
+ assert_equals(create_formdata(['key', null], ['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataSetNull2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataSetToForm1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', 'value2');
+ fd.set('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataSetToForm2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', undefined);
+ assert_equals(fd.get('key'), "undefined");
+ }, 'testFormDataSetToFormUndefined1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', undefined);
+ fd.set('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataSetToFormUndefined2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', null);
+ assert_equals(fd.get('key'), "null");
+ }, 'testFormDataSetToFormNull1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', null);
+ fd.set('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataSetToFormNull2');
+ test(function() {
+ var fd = new FormData();
+ fd.set('key', new Blob([]), 'blank.txt');
+ var file = fd.get('key');
+
+ assert_true(file instanceof File);
+ assert_equals(file.name, 'blank.txt');
+ }, 'testFormDataSetEmptyBlob');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.set.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/formdata.htm b/testing/web-platform/tests/XMLHttpRequest/formdata.htm
new file mode 100644
index 000000000..e0d0a4e1d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/formdata.htm
@@ -0,0 +1,43 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>XMLHttpRequest: upload formdata</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#interface-formdata" data-tested-assertations="following::P[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata" data-tested-assertations=".. following::P[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-append" data-tested-assertations=".. following::UL[1]/LI[1] following::UL[1]/LI[2] following::UL[1]/LI[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-FormData" data-tested-assertations="following::DD[1]" />
+<div id="log"></div>
+<form id="form">
+ <input type="hidden" name="key" value="value">
+</form>
+<script>
+ function do_test (name, fd, expected) {
+ var test = async_test(name);
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onreadystatechange = test.step_func(function () {
+ if (client.readyState !== 4) return;
+ assert_equals(client.responseText, expected);
+ test.done();
+ });
+ client.open("POST", "resources/upload.py");
+ client.send(fd);
+ });
+ }
+
+ function create_formdata () {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
+
+ do_test("empty formdata", new FormData(), '\n');
+ do_test("formdata with string", create_formdata(['key', 'value']), 'key=value,\n');
+ do_test("formdata with named string", create_formdata(['key', new Blob(['value'], {type: 'text/plain'}), 'kv.txt']), '\nkey=kv.txt:text/plain:5,');
+ do_test("formdata from form", new FormData(document.getElementById('form')), 'key=value,\n');
+
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/getallresponseheaders-cookies.htm b/testing/web-platform/tests/XMLHttpRequest/getallresponseheaders-cookies.htm
new file mode 100644
index 000000000..2cd809818
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/getallresponseheaders-cookies.htm
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: getAllResponseHeaders() excludes cookies</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getallresponseheaders" data-tested-assertations="/following::OL[1]/LI[1] /following::OL[1]/LI[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ assert_equals(client.getAllResponseHeaders(), "")
+ client.onreadystatechange = function() {
+ test.step(function() {
+ var headers = client.getAllResponseHeaders().toLowerCase()
+ if(client.readyState == 1) {
+ assert_equals(headers, "")
+ }
+ if(client.readyState > 1) {
+ assert_true(headers.indexOf("\r\n") != -1, "carriage return")
+ assert_true(headers.indexOf("content-type") != -1, "content-type")
+ assert_true(headers.indexOf("x-custom-header") != -1, "x-custom-header")
+ assert_false(headers.indexOf("set-cookie") != -1, "set-cookie")
+ assert_false(headers.indexOf("set-cookie2") != -1, "set-cookie2")
+ }
+ if(client.readyState == 4)
+ test.done()
+ })
+ }
+ client.open("GET", "resources/headers.py")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/getallresponseheaders-status.htm b/testing/web-platform/tests/XMLHttpRequest/getallresponseheaders-status.htm
new file mode 100644
index 000000000..ec1aa9a80
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/getallresponseheaders-status.htm
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: getAllResponseHeaders() excludes status</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getallresponseheaders" data-tested-assertations="/following::OL[1]/LI[1] /following::OL[1]/LI[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ var headersUnsent = client.getAllResponseHeaders();
+ test.step(function() {
+ assert_equals(headersUnsent, "")
+ });
+ client.onreadystatechange = function() {
+ test.step(function() {
+ var headers = client.getAllResponseHeaders().toLowerCase()
+ if(client.readyState == 1) {
+ assert_equals(headers, "")
+ }
+ if(client.readyState > 1) {
+ assert_false(headers.indexOf("200 ok") != -1)
+ assert_false(headers.indexOf("http/1.") != -1)
+ }
+ if(client.readyState == 4)
+ test.done()
+ })
+ }
+ client.open("GET", "resources/headers.py")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/getresponseheader-case-insensitive.htm b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-case-insensitive.htm
new file mode 100644
index 000000000..8e0537edf
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-case-insensitive.htm
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: getResponseHeader() case-insensitive matching</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getresponseheader" data-tested-assertations="following::OL[1]/LI[4] following::OL[1]/LI[5] following::OL[1]/LI[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.getResponseHeader("x-custom-header"), "test")
+ assert_equals(client.getResponseHeader("X-Custom-Header"), "test")
+ assert_equals(client.getResponseHeader("X-CUSTOM-HEADER"), "test")
+ assert_equals(client.getResponseHeader("X-custom-HEADER"), "test")
+ assert_equals(client.getResponseHeader("X-CUSTOM-header-COMMA"), "1, 2")
+ assert_equals(client.getResponseHeader("X-CUSTOM-no-such-header-in-response"), null)
+ assert_true(client.getResponseHeader("CONTENT-TYPE").indexOf("text/plain") != -1)
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/headers.py")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/getresponseheader-chunked-trailer.htm b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-chunked-trailer.htm
new file mode 100644
index 000000000..3cbdb9c06
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-chunked-trailer.htm
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: getResponseHeader() and HTTP trailer</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getresponseheader" data-tested-assertations="/following::OL[1]/LI[4] /following::OL[1]/LI[5] /following::OL[1]/LI[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.getResponseHeader('Trailer'), 'X-Test-Me')
+ assert_equals(client.getResponseHeader('X-Test-Me'), null)
+ assert_equals(client.getAllResponseHeaders().indexOf('Trailer header value'), -1)
+ assert_regexp_match(client.getAllResponseHeaders(), /Trailer:\sX-Test-Me/)
+ assert_equals(client.responseText, "First chunk\r\nSecond chunk\r\nYet another (third) chunk\r\nYet another (fourth) chunk\r\n")
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/chunked.py")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/getresponseheader-cookies-and-more.htm b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-cookies-and-more.htm
new file mode 100644
index 000000000..053fe441f
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-cookies-and-more.htm
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: getResponseHeader() custom/non-existent headers and cookies</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getresponseheader" data-tested-assertations="following::OL[1]/LI[3] following::OL[1]/LI[5] following::OL[1]/LI[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 1) {
+ assert_equals(client.getResponseHeader("x-custom-header"), null)
+ }
+ if(client.readyState > 1) {
+ assert_equals(client.getResponseHeader("x-custom-header"), "test")
+ assert_equals(client.getResponseHeader("x-custom-header-empty"), "")
+ assert_equals(client.getResponseHeader("set-cookie"), null)
+ assert_equals(client.getResponseHeader("set-cookie2"), null)
+ assert_equals(client.getResponseHeader("x-non-existent-header"), null)
+ }
+ if(client.readyState == 4)
+ test.done()
+ })
+ }
+ client.open("GET", "resources/headers.py")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/getresponseheader-error-state.htm b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-error-state.htm
new file mode 100644
index 000000000..c9695fdee
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-error-state.htm
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: getResponseHeader() in error state (failing cross-origin test)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getresponseheader" data-tested-assertations="following::OL[1]/LI[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 1) {
+ assert_equals(client.getResponseHeader("x-custom-header"), null)
+ }
+ if(client.readyState > 1) {
+ assert_equals(client.getResponseHeader("x-custom-header"), null)
+ }
+ if(client.readyState == 4){
+ assert_equals(client.getResponseHeader("x-custom-header"), null)
+ test.done()
+ }
+ })
+ }
+ var url = location.protocol + "//" + 'www1.' + location.host + (location.pathname.replace(/getresponseheader-error-state\.htm/, 'resources/nocors/folder.txt'))
+ client.open("GET", url)
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/getresponseheader-server-date.htm b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-server-date.htm
new file mode 100644
index 000000000..409bc3503
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-server-date.htm
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: getResponseHeader() server and date</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getresponseheader" data-tested-assertations="/following::OL[1]/LI[4] /following::OL[1]/LI[5] /following::OL[1]/LI[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_true(client.getResponseHeader("Server") != null)
+ assert_true(client.getResponseHeader("Date") != null)
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/headers.py")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/getresponseheader-special-characters.htm b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-special-characters.htm
new file mode 100644
index 000000000..980f8481c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-special-characters.htm
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: getResponseHeader() funny characters</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getresponseheader" data-tested-assertations="/following::OL[1]/LI[5] /following::OL[1]/LI[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.getResponseHeader("x-custom-header "), null)
+ assert_equals(client.getResponseHeader(" x-custom-header"), null)
+ assert_equals(client.getResponseHeader("x-custom-header-bytes"), "\xE2\x80\xA6")
+ assert_equals(client.getResponseHeader("x¾"), null)
+ assert_equals(client.getResponseHeader("x-custom-header\n"), null)
+ assert_equals(client.getResponseHeader("\nx-custom-header"), null)
+ assert_equals(client.getResponseHeader("x-custom-header:"), null)
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/headers.py")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/getresponseheader-unsent-opened-state.htm b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-unsent-opened-state.htm
new file mode 100644
index 000000000..e3bc2720f
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/getresponseheader-unsent-opened-state.htm
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: getResponseHeader() in unsent, opened states</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getresponseheader" data-tested-assertations="/following::OL[1]/LI[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ assert_equals(client.getResponseHeader("x-custom-header"), null)
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState < 2) {
+ assert_equals(client.getResponseHeader("x-custom-header"), null)
+ assert_equals(client.getResponseHeader("CONTENT-TYPE"), null)
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/headers.py")
+ assert_equals(client.getResponseHeader("x-custom-header"), null)
+ assert_equals(client.getResponseHeader("Date"), null)
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/headers-normalize-response.htm b/testing/web-platform/tests/XMLHttpRequest/headers-normalize-response.htm
new file mode 100644
index 000000000..466b0d977
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/headers-normalize-response.htm
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Whitespace and null in header values</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=support.js?pipe=sub></script>
+
+<h1>Whitespace and null in response header values</h1>
+
+<div id=log></div>
+
+<script>
+
+function matchHeaderValue(val) {
+ test(function () {
+ var client = new XMLHttpRequest();
+ var trimmed = val.trim();
+ client.open("GET", "resources/parse-headers.py?my-custom-header="+encodeURIComponent(val), false);
+ client.send();
+ var r = client.getResponseHeader("My-Custom-Header");
+
+ assert_equals(r, trimmed);
+ }, "Header value: " + val.replace(/\t/g, "[tab]").replace(/ /g, "_").replace("\0", "\\0"));
+}
+
+matchHeaderValue("hello world\0");
+matchHeaderValue("\0hello world");
+matchHeaderValue("hello\0world");
+matchHeaderValue(" hello world");
+matchHeaderValue("hello world ");
+matchHeaderValue(" hello world ");
+matchHeaderValue("\thello world");
+matchHeaderValue("hello world\t");
+matchHeaderValue("\thello world\t");
+matchHeaderValue("hello world");
+matchHeaderValue("hello\tworld");
+matchHeaderValue("\0");
+matchHeaderValue(" ");
+matchHeaderValue("\t");
+matchHeaderValue("");
+
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/interfaces.html b/testing/web-platform/tests/XMLHttpRequest/interfaces.html
new file mode 100644
index 000000000..96de3c00f
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/interfaces.html
@@ -0,0 +1,171 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>XMLHttpRequest IDL tests</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/WebIDLParser.js></script>
+<script src=/resources/idlharness.js></script>
+
+<h1>XMLHttpRequest IDL tests</h1>
+<div id=log></div>
+
+<script type=text/plain class=untested>
+[Constructor(DOMString type, optional EventInit eventInitDict)/*,
+ Exposed=(Window,Worker)*/]
+interface Event {
+ readonly attribute DOMString type;
+ readonly attribute EventTarget? target;
+ readonly attribute EventTarget? currentTarget;
+
+ const unsigned short NONE = 0;
+ const unsigned short CAPTURING_PHASE = 1;
+ const unsigned short AT_TARGET = 2;
+ const unsigned short BUBBLING_PHASE = 3;
+ readonly attribute unsigned short eventPhase;
+
+ void stopPropagation();
+ void stopImmediatePropagation();
+
+ readonly attribute boolean bubbles;
+ readonly attribute boolean cancelable;
+ void preventDefault();
+ readonly attribute boolean defaultPrevented;
+
+ [Unforgeable] readonly attribute boolean isTrusted;
+ readonly attribute DOMTimeStamp timeStamp;
+
+ void initEvent(DOMString type, boolean bubbles, boolean cancelable);
+};
+
+dictionary EventInit {
+ boolean bubbles = false;
+ boolean cancelable = false;
+};
+
+/*[Exposed=(Window,Worker)]*/
+interface EventTarget {
+ void addEventListener(DOMString type, EventListener? callback, optional boolean capture = false);
+ void removeEventListener(DOMString type, EventListener? callback, optional boolean capture = false);
+ boolean dispatchEvent(Event event);
+};
+</script>
+<script type=text/plain class=untested>
+[TreatNonCallableAsNull]
+callback EventHandlerNonNull = any (Event event);
+typedef EventHandlerNonNull? EventHandler;
+</script>
+<script type=text/plain>
+/*[Exposed=(Window,Worker)]*/
+interface XMLHttpRequestEventTarget : EventTarget {
+ // event handlers
+ attribute EventHandler onloadstart;
+ attribute EventHandler onprogress;
+ attribute EventHandler onabort;
+ attribute EventHandler onerror;
+ attribute EventHandler onload;
+ attribute EventHandler ontimeout;
+ attribute EventHandler onloadend;
+};
+
+/*[Exposed=(Window,Worker)]*/
+interface XMLHttpRequestUpload : XMLHttpRequestEventTarget {
+};
+
+enum XMLHttpRequestResponseType {
+ "",
+ "arraybuffer",
+ "blob",
+ "document",
+ "json",
+ "text"
+};
+
+[Constructor/*,
+ Exposed=(Window,Worker)*/]
+interface XMLHttpRequest : XMLHttpRequestEventTarget {
+ // event handler
+ attribute EventHandler onreadystatechange;
+
+ // states
+ const unsigned short UNSENT = 0;
+ const unsigned short OPENED = 1;
+ const unsigned short HEADERS_RECEIVED = 2;
+ const unsigned short LOADING = 3;
+ const unsigned short DONE = 4;
+ readonly attribute unsigned short readyState;
+
+ // request
+ void open(ByteString method, USVString url);
+ void open(ByteString method, USVString url, boolean async, optional USVString? username = null, optional USVString? password = null);
+ void setRequestHeader(ByteString name, ByteString value);
+ attribute unsigned long timeout;
+ attribute boolean withCredentials;
+ readonly attribute XMLHttpRequestUpload upload;
+ void send(optional (Document or BodyInit)? body = null);
+ void abort();
+
+ // response
+ readonly attribute USVString responseURL;
+ readonly attribute unsigned short status;
+ readonly attribute ByteString statusText;
+ ByteString? getResponseHeader(ByteString name);
+ ByteString getAllResponseHeaders();
+ void overrideMimeType(DOMString mime);
+ attribute XMLHttpRequestResponseType responseType;
+ readonly attribute any response;
+ readonly attribute USVString responseText;
+ [Exposed=Window] readonly attribute Document? responseXML;
+};
+
+typedef (File or USVString) FormDataEntryValue;
+
+[Constructor(optional HTMLFormElement form)/*,
+ Exposed=(Window,Worker)*/]
+interface FormData {
+ void append(USVString name, Blob value, optional USVString filename);
+ void append(USVString name, USVString value);
+ void delete(USVString name);
+ FormDataEntryValue? get(USVString name);
+ sequence<FormDataEntryValue> getAll(USVString name);
+ boolean has(USVString name);
+ void set(USVString name, Blob value, optional USVString filename);
+ void set(USVString name, USVString value);
+ /*iterable<USVString, FormDataEntryValue>;*/
+};
+
+[Constructor(DOMString type, optional ProgressEventInit eventInitDict)/*,
+ Exposed=(Window,Worker)*/]
+interface ProgressEvent : Event {
+ readonly attribute boolean lengthComputable;
+ readonly attribute unsigned long long loaded;
+ readonly attribute unsigned long long total;
+};
+
+dictionary ProgressEventInit : EventInit {
+ boolean lengthComputable = false;
+ unsigned long long loaded = 0;
+ unsigned long long total = 0;
+};
+</script>
+<script>
+"use strict";
+var form;
+var idlArray;
+setup(function() {
+ form = document.createElement("form");
+ idlArray = new IdlArray();
+ [].forEach.call(document.querySelectorAll("script[type=text\\/plain]"), function(node) {
+ if (node.className == "untested") {
+ idlArray.add_untested_idls(node.textContent);
+ } else {
+ idlArray.add_idls(node.textContent);
+ }
+ });
+ idlArray.add_objects({
+ XMLHttpRequest: ['new XMLHttpRequest()'],
+ XMLHttpRequestUpload: ['(new XMLHttpRequest()).upload'],
+ FormData: ['new FormData()', 'new FormData(form)']
+ });
+});
+idlArray.test();
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-after-abort.htm b/testing/web-platform/tests/XMLHttpRequest/open-after-abort.htm
new file mode 100644
index 000000000..ca8a4e1e6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-after-abort.htm
@@ -0,0 +1,35 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() after abort()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[15] following::ol/li[15]/ol/li[1] following::ol/li[15]/ol/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ result = [],
+ expected = [1, 4, 1] // open() -> 1,
+ // abort() -> 4, open() -> 1
+ client.onreadystatechange = function() {
+ test.step(function() {
+ result.push(client.readyState)
+ })
+ }
+ client.open("GET", "resources/well-formed.xml")
+ assert_equals(client.readyState, 1)
+ client.send(null)
+ client.abort()
+ assert_equals(client.readyState, 0)
+ client.open("GET", "resources/well-formed.xml")
+ assert_equals(client.readyState, 1)
+ assert_array_equals(result, expected)
+ })
+ test.done()
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-after-setrequestheader.htm b/testing/web-platform/tests/XMLHttpRequest/open-after-setrequestheader.htm
new file mode 100644
index 000000000..525edbfc1
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-after-setrequestheader.htm
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() after setRequestHeader()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[14]/ul/li[4]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState === 4){
+ assert_equals(client.responseText, '')
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/inspect-headers.py?filter_name=X-foo")
+ assert_equals(client.readyState, 1)
+ client.setRequestHeader('X-foo', 'bar')
+ client.open("GET", "resources/inspect-headers.py?filter_name=X-foo")
+ assert_equals(client.readyState, 1)
+ client.send()
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-during-abort.htm b/testing/web-platform/tests/XMLHttpRequest/open-during-abort.htm
new file mode 100755
index 000000000..1d01415d5
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-during-abort.htm
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() during abort()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest(),
+ abort_flag = false,
+ result = [],
+ expected = [1, 4, 1] // open() => 1, abort() => 4, open() => 1
+
+ client.onreadystatechange = this.step_func(function() {
+ result.push(client.readyState)
+ if (abort_flag) {
+ abort_flag = false
+ client.open("GET", "...")
+ }
+ })
+ client.open("GET", "resources/well-formed.xml")
+ client.send(null)
+ abort_flag = true
+ client.abort()
+ assert_array_equals(result, expected)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-method-bogus.htm b/testing/web-platform/tests/XMLHttpRequest/open-method-bogus.htm
new file mode 100644
index 000000000..263e7b6db
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-method-bogus.htm
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - bogus methods</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function method(method) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ assert_throws("SyntaxError", function() { client.open(method, "...") })
+ }, document.title + " (" + method + ")")
+ }
+ method("")
+ method(">")
+ method(" GET")
+ method("G T")
+ method("@GET")
+ method("G:ET")
+ method("GET?")
+ method("GET\n")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-method-case-insensitive.htm b/testing/web-platform/tests/XMLHttpRequest/open-method-case-insensitive.htm
new file mode 100644
index 000000000..103381745
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-method-case-insensitive.htm
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - case-insensitive methods test</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[5]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function method(method) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open(method, "resources/content.py", false)
+ client.send(null)
+ assert_equals(client.getResponseHeader("x-request-method"), method.toUpperCase())
+ }, document.title + " (" + method.toUpperCase() + ")")
+ }
+ method("deLETE")
+ method("get")
+ method("heAd")
+ method("OpTIOns")
+ method("post")
+ method("Put")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-method-case-sensitive.htm b/testing/web-platform/tests/XMLHttpRequest/open-method-case-sensitive.htm
new file mode 100644
index 000000000..270e32d67
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-method-case-sensitive.htm
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - case-sensitive methods test</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[5]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function method(method) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open(method, "resources/content.py", false)
+ client.send(null)
+ assert_equals(client.getResponseHeader("x-request-method"), method)
+ }, document.title + " (" + method + ")")
+ }
+ method("XUNICORN")
+ method("xUNIcorn")
+ method("chiCKEN")
+ method("PATCH")
+ method("patCH")
+ method("copy")
+ method("COpy")
+ method("inDEX")
+ method("movE")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-method-insecure.htm b/testing/web-platform/tests/XMLHttpRequest/open-method-insecure.htm
new file mode 100644
index 000000000..1a77ff3ec
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-method-insecure.htm
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - "insecure" methods</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[5] following::ol/li[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function method(method) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ assert_throws("SecurityError", function() { client.open(method, "...") })
+ }, document.title + " (" + method + ")")
+ }
+ method("track")
+ method("TRACK")
+ method("trAck")
+ method("TRACE")
+ method("trace")
+ method("traCE")
+ method("connect")
+ method("CONNECT")
+ method("connECT")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-method-responsetype-set-sync.htm b/testing/web-platform/tests/XMLHttpRequest/open-method-responsetype-set-sync.htm
new file mode 100644
index 000000000..0b4d81404
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-method-responsetype-set-sync.htm
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() sync request not allowed if responseType is set</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[10]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // Note: the case of calling synchronous open() first, and then setting
+ // responseType, is tested in responsetype.html.
+ function request(type) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = this.step_func(function(){
+ assert_unreached('No events should fire here')
+ })
+ client.responseType = type
+ assert_throws("InvalidAccessError", function() { client.open('GET', "...", false) })
+ }, document.title + " (" + type + ")")
+ }
+ request("arraybuffer")
+ request("blob")
+ request("json")
+ request("text")
+ request("document")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-open-send.htm b/testing/web-platform/tests/XMLHttpRequest/open-open-send.htm
new file mode 100644
index 000000000..ebc1801ab
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-open-send.htm
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - open() - send()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[14]/ul/li[1] following::ol/li[14]/ul/li[2] following::ol/li[15]/ol/li[1] following::ol/li[15]/ol/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ result = [],
+ expected = [1,2,3,4]
+ client.onreadystatechange = function() {
+ test.step(function() {
+ result.push(client.readyState)
+ if(4 == client.readyState) {
+ assert_array_equals(result, expected)
+ assert_equals(client.responseText, 'top\n')
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/folder.txt")
+ client.open("GET", "folder.txt")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-open-sync-send.htm b/testing/web-platform/tests/XMLHttpRequest/open-open-sync-send.htm
new file mode 100644
index 000000000..b0badfd8a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-open-sync-send.htm
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - open() (sync) - send()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[14]/ul/li[1] following::ol/li[14]/ul/li[2] following::ol/li[14]/ul/li[3] following::ol/li[15]/ol/li[1] following::ol/li[15]/ol/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ result = [],
+ expected = [1,4]
+ client.onreadystatechange = function() {
+ test.step(function() {
+ result.push(client.readyState)
+ })
+ }
+ client.open("GET", "folder.txt")
+ client.open("GET", "folder.txt", false)
+ client.send(null)
+ assert_equals(client.responseText, 'top\n')
+ assert_array_equals(result, expected)
+ test.done()
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-referer.htm b/testing/web-platform/tests/XMLHttpRequest/open-referer.htm
new file mode 100644
index 000000000..4ffdfe0c5
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-referer.htm
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - value of Referer header</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="/following::ol[1]/li[2]/ol[1]/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/inspect-headers.py?filter_name=referer", false)
+ client.send(null)
+ assert_equals(client.responseText, "referer: "+location.href+'\n')
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-send-open.htm b/testing/web-platform/tests/XMLHttpRequest/open-send-open.htm
new file mode 100644
index 000000000..d57592c0b
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-send-open.htm
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - send() - open()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[14]/ul/li[1] following::ol/li[14]/ul/li[2] following::ol/li[15]/ol/li[1] following::ol/li[15]/ol/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ result = [],
+ expected = [1, 'a', 'b', 'c']
+ client.onreadystatechange = function() {
+ test.step(function() {
+ result.push(client.readyState)
+ })
+ }
+ client.open("GET", "folder.txt")
+ result.push('a')
+ client.send()
+ result.push('b')
+ client.open("GET", "folder.txt")
+ result.push('c')
+ assert_array_equals(result, expected)
+ test.done()
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-sync-open-send.htm b/testing/web-platform/tests/XMLHttpRequest/open-sync-open-send.htm
new file mode 100644
index 000000000..cc81c5223
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-sync-open-send.htm
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() (sync) - send() - open()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[14]/ul/li[1] following::ol[1]/li[14]/ul/li[2] following::ol[1]/li[14]/ul/li[3] following::ol[1]/li[15]/ol/li[1] following::ol[1]/li[15]/ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol[1]/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-statustext-attribute" data-tested-assertations="following::ol[1]/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-getallresponseheaders()-method" data-tested-assertations="following::ol[1]/li[1]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ result = [],
+ expected = [1]
+ client.onreadystatechange = function() {
+ test.step(function() {
+ result.push(client.readyState)
+ })
+ }
+ client.open("GET", "folder.txt")
+ client.send(null)
+ client.open("GET", "folder.txt", false)
+ assert_array_equals(result, expected)
+ assert_equals(client.responseXML, null)
+ assert_equals(client.responseText, "")
+ assert_equals(client.status, 0)
+ assert_equals(client.statusText, "")
+ assert_equals(client.getAllResponseHeaders(), "")
+ test.done()
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-about-blank-window.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-about-blank-window.htm
new file mode 100644
index 000000000..5be3b77dd
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-about-blank-window.htm
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs (about:blank iframe)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[2]/ol/li[2] following::ol/li[7] following::ol/li[14]/ul/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#concept-xmlhttprequest-document" data-tested-assertations=".." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <iframe src="about:blank"></iframe>
+ <script>
+ test(function() {
+ var client = new self[0].XMLHttpRequest()
+ client.open("GET", "folder.txt", false)
+ client.send("")
+ assert_equals(client.responseText, "top\n")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-base-inserted-after-open.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-base-inserted-after-open.htm
new file mode 100644
index 000000000..a4d641faf
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-base-inserted-after-open.htm
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs - insert &lt;base> after open()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[2]/ol/li[2] following::ol/li[7] following::ol/li[14]/ul/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest(),
+ base = document.createElement("base")
+ base.href = location.href.replace(/\/[^/]*$/, '') + "/resources/"
+ client.open("GET", "folder.txt", false)
+ document.getElementsByTagName("head")[0].appendChild(base)
+ client.send(null)
+ assert_equals(client.responseText, "top\n")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-base-inserted.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-base-inserted.htm
new file mode 100644
index 000000000..69ad6193d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-base-inserted.htm
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs - insert &lt;base></title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[2]/ol/li[2] following::ol/li[7] following::ol/li[14]/ul/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest(),
+ base = document.createElement("base")
+ base.href = location.href.replace(/\/[^/]*$/, '') + "/resources/"
+ document.getElementsByTagName("head")[0].appendChild(base)
+ client.open("GET", "folder.txt", false)
+ client.send(null)
+ assert_equals(client.responseText, "bottom\n")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-base.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-base.htm
new file mode 100644
index 000000000..3c0e8c99d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-base.htm
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs - &lt;base></title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <base href="./resources/">
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[2]/ol/li[2] following::ol/li[7] following::ol/li[14]/ul/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "folder.txt", false)
+ client.send(null)
+ assert_equals(client.responseText, "bottom\n")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-bogus.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-bogus.htm
new file mode 100644
index 000000000..117bd4958
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-bogus.htm
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - bogus URLs</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[7] following::ol/li[8]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function url(url) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ assert_throws("SyntaxError", function() { client.open("GET", url) })
+ }, document.title + " (" + url + ")")
+ }
+ url("//[")
+ url("ftp:")
+ url("http://a a/")
+ url("http:////////////")
+ url("http://u:p@/")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-encoding.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-encoding.htm
new file mode 100644
index 000000000..7acdac86a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-encoding.htm
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset=windows-1252>
+ <title>XMLHttpRequest: open() - URL encoding</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[7] following::ol/li[14]/ul/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/content.py?\u00DF", false) // This is the German "eszett" character
+ client.send()
+ assert_equals(client.getResponseHeader("x-request-query"), "%C3%9F")
+ }, "percent encode characters");
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/content.py?\uD83D", false)
+ client.send()
+ assert_equals(client.getResponseHeader("x-request-query"), "%EF%BF%BD")
+ }, "lone surrogate should return U+FFFD");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-fragment.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-fragment.htm
new file mode 100644
index 000000000..6b3fdeb8a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-fragment.htm
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs - fragment identifier</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[7]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "folder.txt#foobar", false)
+ client.send(null)
+ assert_equals(client.responseText, "top\n")
+ })
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/requri.py#foobar", false)
+ client.send(null)
+ assert_regexp_match(client.responseText, /XMLHttpRequest\/resources\/requri\.py$/)
+ }, 'make sure fragment is removed from URL before request')
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/requri.py?help=#foobar", false)
+ client.send(null)
+ assert_regexp_match(client.responseText, /XMLHttpRequest\/resources\/requri\.py\?help=$/)
+ }, 'make sure fragment is removed from URL before request (with query string)')
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/requri.py?" +encodeURIComponent("#foobar"), false)
+ client.send(null)
+ assert_regexp_match(client.responseText, /XMLHttpRequest\/resources\/requri\.py\?%23foobar$/)
+ }, 'make sure escaped # is not removed')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-javascript-window-2.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-javascript-window-2.htm
new file mode 100644
index 000000000..f5ddd4249
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-javascript-window-2.htm
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - resolving URLs (javascript: &lt;iframe>; 2)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[2] following::ol[1]/li[7] following::ol[1]/li[14]/ul/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var iframe = document.body.appendChild(document.createElement("iframe"))
+ iframe.src = "javascript:parent.test.step(function() { var x = new XMLHttpRequest(); x.open('GET', 'folder.txt', false); x.send(null); parent.assert_equals(x.responseText, 'top\\n'); parent.test.done() })"
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-javascript-window.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-javascript-window.htm
new file mode 100644
index 000000000..cd208d51a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-javascript-window.htm
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - resolving URLs (javascript: &lt;iframe>; 1)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[2] following::ol[1]/li[7] following::ol[1]/li[14]/ul/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ function request() {
+ test.step(function() {
+ var x = new XMLHttpRequest()
+ x.open("GET", "folder.txt", false)
+ x.send(null)
+ assert_equals(x.responseText, "top\n")
+ test.done()
+ })
+ }
+ test.step(function() {
+ var iframe = document.body.appendChild(document.createElement("iframe"))
+ iframe.src = "javascript:parent.request()"
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-2.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-2.htm
new file mode 100644
index 000000000..398764e70
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-2.htm
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs (multi-Window; 2; evil)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function init(){ // called from page inside IFRAME
+ test(function() {
+ var client = new self[0].XMLHttpRequest()
+ document.body.removeChild(document.getElementsByTagName("iframe")[0])
+ assert_throws("InvalidStateError", function() {
+ client.open("GET", "folder.txt")
+ }, "open() when associated document's IFRAME is removed")
+ })
+ }
+ </script>
+ <iframe src="resources/init.htm"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-3.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-3.htm
new file mode 100644
index 000000000..b3652dfa5
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-3.htm
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs (multi-Window; 3; evil)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function init() {
+ test(function() {
+ var client = new self[0].XMLHttpRequest()
+ client.open("GET", "folder.txt")
+ document.body.removeChild(document.getElementsByTagName("iframe")[0])
+ assert_throws("InvalidStateError", function() {
+ client.send(null)
+ }, "send() when associated document's IFRAME is removed")
+ })
+ }
+ </script>
+ <iframe src="resources/init.htm"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-4.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-4.htm
new file mode 100644
index 000000000..9ddbb9b47
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-4.htm
@@ -0,0 +1,50 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs (multi-Window; 4; evil)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ /*
+ It's unclear what the pass condition should be for this test.
+ Implementations:
+ Firefox, Opera (Presto): terminate request with no further events when IFRAME is removed.
+ Chrome: completes request to readyState=4 but responseText is "" so it's pretty much terminated with an extra event for "DONE" state
+ Pass condition is now according to my suggested spec text in https://github.com/whatwg/xhr/pull/3 , if that's not accepted we'll have to amend this test
+ */
+ var test = async_test()
+ function init() {
+ test.step(function() {
+ var hasErrorEvent = false
+ var client = new self[0].XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.responseText, "", "responseText is empty on inactive document error condition")
+ }
+ })
+ }
+ client.addEventListener('error', function(){
+ test.step(function() {
+ hasErrorEvent = true
+ assert_equals(client.readyState, 4, "readyState is 4 when error listener fires")
+ })
+ })
+ client.addEventListener('loadend', function(){
+ test.step(function() {
+ assert_true(hasErrorEvent, "should get an error event")
+ test.done()
+ })
+ })
+ client.open("GET", "folder.txt")
+ client.send(null)
+ document.body.removeChild(document.getElementsByTagName("iframe")[0])
+ })
+ }
+ </script>
+ <iframe src="resources/init.htm"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-5.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-5.htm
new file mode 100644
index 000000000..a27d2b366
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-5.htm
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs (multi-Window; 5)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test(),
+ client,
+ count = 0
+ function init() {
+ test.step(function() {
+ if(0 == count) {
+ client = new self[0].XMLHttpRequest()
+ count++
+ self[0].location.reload()
+ } else if(1 == count) {
+ assert_throws("InvalidStateError", function() { client.open("GET", "...") })
+ test.done()
+ }
+ })
+ }
+ </script>
+ <iframe src="resources/init.htm"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-6.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-6.htm
new file mode 100644
index 000000000..b6f15828a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window-6.htm
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() in document that is not fully active (but may be active) should throw</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method">
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test(),
+ client,
+ count = 0,
+ win = window.open("resources/init.htm");
+ test.add_cleanup(function() { win.close(); });
+ function init() {
+ test.step(function() {
+ if(0 == count) {
+ var doc = win.document;
+ var ifr = document.createElement("iframe");
+ ifr.onload = function() {
+ // Again, do things async so we're not doing loads from inside
+ // load events.
+ setTimeout(function() {
+ client = new ifr.contentWindow.XMLHttpRequest();
+ count++;
+ // Important to do a normal navigation, not a reload.
+ win.location.href = "resources/init.htm";
+ }, 100);
+ }
+ doc.body.appendChild(ifr);
+ } else if(1 == count) {
+ assert_throws("InvalidStateError", function() { client.open("GET", "...") })
+ test.done()
+ }
+ })
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window.htm
new file mode 100644
index 000000000..347f4b7e5
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-multi-window.htm
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() resolving URLs (multi-Window; 1)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[2] following::ol[1]/li[7] following::ol[1]/li[14]/ul/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ function init() {
+ test.step(function() {
+ var client = new self[0].XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.responseText, "bottom\n")
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "folder.txt")
+ client.send("")
+ })
+ }
+ </script>
+ <iframe src="resources/init.htm"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-worker-origin.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-worker-origin.htm
new file mode 100644
index 000000000..acdbddbf2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-worker-origin.htm
@@ -0,0 +1,43 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XMLHttpRequest: worker scripts, origin and referrer</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::OL[1]/LI[3] following::OL[1]/LI[3]/ol[1]/li[1] following::OL[1]/LI[3]/ol[1]/li[2] following::OL[1]/LI[3]/ol[1]/li[3]" />
+</head>
+<body>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var test = async_test() // This "test" does not actually do any assertations. It's just there to have multiple, separate, asyncronous sub-tests.
+ var expectations = {
+ 'Referer header': 'referer: '+(location.href.replace(/[^/]*$/, ''))+"resources/workerxhr-origin-referrer.js\n",
+ 'Origin header': 'origin: '+location.protocol+'//'+location.hostname+((location.port === "")?"":":"+location.port)+'\n',
+ 'Request URL test' : (location.href.replace(/[^/]*$/, ''))+'resources/requri.py?full'
+ }
+ // now start the worker
+ var worker = new Worker("resources/workerxhr-origin-referrer.js", true)
+ worker.onmessage = function (e) {
+ var subtest = async_test(e.data.test)
+ subtest.step(function(){
+ var thisExpectation = expectations[e.data.test]
+ delete expectations[e.data.test]
+ assert_equals(e.data.result, thisExpectation)
+ subtest.done()
+ })
+ var allDone = true
+ for(var prop in expectations){
+ allDone = false
+ }
+ if(allDone){
+ test.step(function(){
+ test.done()
+ })
+ }
+ }
+
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-url-worker-simple.htm b/testing/web-platform/tests/XMLHttpRequest/open-url-worker-simple.htm
new file mode 100644
index 000000000..a77ef6fee
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-url-worker-simple.htm
@@ -0,0 +1,25 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XMLHttpRequest: relative URLs in worker scripts resolved by script URL</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::OL[1]/LI[3] following::OL[1]/LI[3]/ol[1]/li[1]" />
+</head>
+<body>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var test = async_test()
+ var worker = new Worker("resources/workerxhr-simple.js")
+ worker.onmessage = function (e) {
+ test.step(function(){
+ assert_equals(e.data, 'PASSED')
+ test.done()
+ })
+ }
+ worker.postMessage('start')
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/open-user-password-non-same-origin.htm b/testing/web-platform/tests/XMLHttpRequest/open-user-password-non-same-origin.htm
new file mode 100644
index 000000000..e49888cd4
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/open-user-password-non-same-origin.htm
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: open() - user/pass argument and non same-origin URL doesn't throw</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[9]/ol/li[1] following::ol/li[9]/ol/li[2] following::ol/li[15]/ol/li[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var m = "GET",
+ u = "http://test2.w3.org/",
+ a = false
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open(m, u, a, "x")
+ assert_equals(client.readyState, 1, "open() was successful - 1")
+ var client2 = new XMLHttpRequest()
+ client2.open(m, u, a, "x", "x")
+ assert_equals(client2.readyState, 1, "open() was successful - 2")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/overridemimetype-done-state.htm b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-done-state.htm
new file mode 100644
index 000000000..a1711e609
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-done-state.htm
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: overrideMimeType() in DONE state</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-overridemimetype()-method" data-tested-assertations="/following::ol/li[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ var client = new XMLHttpRequest();
+ client.onreadystatechange = test.step_func( function() {
+ if (client.readyState !== 4) return;
+ assert_throws("InvalidStateError", function() { client.overrideMimeType('application/xml;charset=Shift-JIS'); });
+ assert_equals(client.responseXML, null);
+ test.done();
+ });
+ client.open("GET", "resources/status.py?type="+encodeURIComponent('text/plain;charset=iso-8859-1')+'&content=%3Cmsg%3E%83%65%83%58%83%67%3C%2Fmsg%3E');
+ client.send();
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/overridemimetype-headers-received-state-force-shiftjis.htm b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-headers-received-state-force-shiftjis.htm
new file mode 100644
index 000000000..578e28cb2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-headers-received-state-force-shiftjis.htm
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: overrideMimeType() in HEADERS RECEIVED state, enforcing Shift-JIS encoding</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-overridemimetype()-method" data-tested-assertations="/following::ol/li[1] /following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ var client = new XMLHttpRequest();
+ var readyState2Reached = false;
+ client.onreadystatechange = test.step_func( function() {
+ if(client.readyState===2){
+ readyState2Reached = true;
+ try{
+ client.overrideMimeType('text/plain;charset=Shift-JIS');
+ }catch(e){
+ assert_unreached('overrideMimeType should not throw in state 2');
+ }
+ }
+ if (client.readyState !== 4) return;
+ assert_equals( readyState2Reached, true, "readyState = 2 event fired" );
+ assert_equals( client.responseText, 'テスト', 'overrideMimeType() in HEADERS RECEIVED state set encoding' );
+ test.done();
+ });
+ client.open("GET", "resources/status.py?type="+encodeURIComponent('text/html;charset=UTF-8')+'&content=%83%65%83%58%83%67');
+ client.send( '' );
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/overridemimetype-invalid-mime-type.htm b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-invalid-mime-type.htm
new file mode 100644
index 000000000..9cfd801e0
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-invalid-mime-type.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: overrideMimeType() in unsent state, invalid MIME types</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-overridemimetype()-method" data-tested-assertations="/following::ol/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest();
+ assert_throws("SyntaxError", function() { client.overrideMimeType('text\\plain;charset=Shift-JIS'); });
+ assert_throws("SyntaxError", function() { client.overrideMimeType('text plain;charset=Shift-JIS'); });
+ assert_throws("SyntaxError", function() { client.overrideMimeType('text\nplain;charset=Shift-JIS'); });
+ assert_throws("SyntaxError", function() { client.overrideMimeType('cahrset=Shift-JIS'); });
+ assert_throws("SyntaxError", function() { client.overrideMimeType(null); });
+ assert_throws("SyntaxError", function() { client.overrideMimeType(50212); });
+ assert_throws("SyntaxError", function() { client.overrideMimeType( (new Array(1000)).join('a/b/c/') ); });
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/overridemimetype-loading-state.htm b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-loading-state.htm
new file mode 100644
index 000000000..cce3fa49e
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-loading-state.htm
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: overrideMimeType() in LOADING state</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-overridemimetype()-method" data-tested-assertations="/following::ol/li[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onreadystatechange = test.step_func(function() {
+ if (client.readyState === 3){
+ assert_throws("InvalidStateError", function(){
+ client.overrideMimeType('application/xml;charset=Shift-JIS');
+ });
+ }else if(client.readyState===4){
+ assert_equals(client.responseXML, null);
+ test.done();
+ }
+ });
+ client.open("GET", "resources/status.py?type="+encodeURIComponent('text/plain;charset=iso-8859-1')+'&content=%3Cmsg%3E%83%65%83%58%83%67%3C%2Fmsg%3E');
+ client.send();
+ });
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/overridemimetype-open-state-force-utf-8.htm b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-open-state-force-utf-8.htm
new file mode 100644
index 000000000..5a261005d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-open-state-force-utf-8.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: overrideMimeType() in open state, enforcing UTF-8 encoding</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-overridemimetype()-method" data-tested-assertations="/following::ol/li[3] /following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onreadystatechange = function() {
+ if (client.readyState !== 4) return;
+ assert_equals( client.responseText, 'テスト' );
+ test.done();
+ };
+ client.open("GET", "resources/status.py?type="+encodeURIComponent('text/html;charset=Shift-JIS')+'&content='+encodeURIComponent('テスト'));
+ client.overrideMimeType('text/plain;charset=UTF-8');
+ client.send( '' );
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/overridemimetype-open-state-force-xml.htm b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-open-state-force-xml.htm
new file mode 100644
index 000000000..fd0664a7c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-open-state-force-xml.htm
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: overrideMimeType() in open state, XML MIME type with UTF-8 charset</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-overridemimetype()-method" data-tested-assertations="/following::ol/li[3] /following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.onreadystatechange = function() {
+ if (client.readyState !== 4) return;
+ try{
+ var str = client.responseXML.documentElement.tagName+client.responseXML.documentElement.firstChild.tagName+client.responseXML.documentElement.firstChild.textContent;
+ }catch(e){
+ assert_unreached('Exception when reading responseXML');
+ }
+ assert_equals( client.responseXML.documentElement.tagName, 'test' );
+ assert_equals( client.responseXML.documentElement.firstChild.tagName, 'message' );
+ assert_equals( client.responseXML.documentElement.firstChild.textContent, 'Hello World!' );
+ test.done();
+ };
+ client.open("GET", "resources/status.py?type="+encodeURIComponent('text/plain;charset=Shift-JIS')+'&content='+encodeURIComponent('<test><message>Hello World!</message></test>'));
+ client.overrideMimeType('application/xml;charset=UTF-8');
+ client.send();
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/overridemimetype-unsent-state-force-shiftjis.htm b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-unsent-state-force-shiftjis.htm
new file mode 100644
index 000000000..98dfe1436
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/overridemimetype-unsent-state-force-shiftjis.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: overrideMimeType() in unsent state, enforcing Shift-JIS encoding</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-overridemimetype()-method" data-tested-assertations="/following::ol/li[3] /following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest();
+ client.overrideMimeType('text/plain;charset=Shift-JIS');
+ client.onreadystatechange = function() {
+ if (client.readyState !== 4) return;
+ assert_equals( client.responseText, 'テスト' );
+ test.done();
+ };
+ client.open("GET", "resources/status.py?type="+encodeURIComponent('text/html;charset=iso-8859-1')+'&content=%83%65%83%58%83%67');
+ client.send( '' );
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/preserve-ua-header-on-redirect.htm b/testing/web-platform/tests/XMLHttpRequest/preserve-ua-header-on-redirect.htm
new file mode 100644
index 000000000..074934aef
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/preserve-ua-header-on-redirect.htm
@@ -0,0 +1,43 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: User-Agent header is preserved on redirect</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.responseText, 'user-agent: '+navigator.userAgent+'\n')
+ test.done()
+ }
+ })
+ }
+ client.open("POST", "resources/redirect.py?location="+encodeURIComponent("inspect-headers.py?filter_name=user-agent"))
+ client.send(null)
+ })
+
+ var test2 = async_test()
+ test2.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test2.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.responseText, 'user-agent: TEST\n')
+ test2.done()
+ }
+ })
+ }
+ client.open("POST", "resources/redirect.py?location="+encodeURIComponent("inspect-headers.py?filter_name=user-agent"))
+ client.setRequestHeader("User-Agent", "TEST")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/progress-events-response-data-gzip.htm b/testing/web-platform/tests/XMLHttpRequest/progress-events-response-data-gzip.htm
new file mode 100644
index 000000000..058064636
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/progress-events-response-data-gzip.htm
@@ -0,0 +1,83 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: progress events and GZIP encoding</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#firing-events-using-the-progressevent-interface-for-http" data-tested-assertations="following::p[contains(text(),'content-encodings')]" />
+ <!-- TODO: find better spec reference when https://www.w3.org/Bugs/Public/show_bug.cgi?id=25587 is fixed -->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ /*
+
+ Two behaviours are considered acceptable, so there are two ways to
+ pass this test
+
+ a) Set data for the compressed resource:
+ * event.total reflects the Content-length of the gzipp'ed resource
+ * event.loaded how many gzipped bytes have arrived over the wire so far
+ * lengthComputable is true
+
+ or
+
+ b) If the implementation does not provide progress details for the compressed
+ resource, set
+ * lengthComputable to false
+ * event.total to 0
+ * event.loaded to the number of bytes available so far after gzip decoding
+
+ Implications of this are tested here as follows:
+
+ * If lengthComputable is true:
+ * Event.total must match Content-length header
+ * event.loaded must only ever increase in progress events
+ (and may never repeat its value).
+ * event.loaded must never exceed the Content-length.
+
+ * If lengthComputable is false:
+ * event.total should be 0
+ * event.loaded must only ever increase in progress events
+ (and may never repeat its value).
+ * event.loaded should be the length of the decompressed content, i.e.
+ bigger than Content-length header value when finished loading
+
+ */
+ var lastTotal;
+ var lastLoaded = -1;
+ client.addEventListener('loadend', test.step_func(function(e){
+ var len = parseInt(client.getResponseHeader('content-length'), 10)
+ if(e.lengthComputable){
+ assert_equals(e.total, len, 'event.total is content-length')
+ assert_equals(e.loaded, len, 'event.loaded should be content-length at loadend')
+ }else{
+ assert_equals(e.total, 0, 'if implementation can\'t compute event.total for gzipped content it is 0')
+ assert_true(e.loaded >= len, 'event.loaded should be set even if total is not computable')
+ }
+ test.done();
+ }), false)
+ client.addEventListener('progress', test.step_func(function(e){
+ if(lastTotal === undefined){
+ lastTotal = e.total;
+ }
+ if(e.lengthComputable && e.total && e.loaded){
+ assert_equals(e.total, lastTotal, 'event.total should remain invariant')
+ assert_less_than_equal(e.loaded, lastTotal, 'event.loaded should not exceed content-length')
+ }else{
+ assert_equals(e.total, 0, 'event.total should be 0')
+ }
+ assert_greater_than(e.loaded, lastLoaded, 'event.loaded should only ever increase')
+ lastLoaded = e.loaded;
+ }), false)
+ // image.gif is 165375 bytes compressed. Sending 45000 bytes at a time with 1 second delay will load it in 4 seconds
+ client.open("GET", "resources/image.gif?pipe=gzip|trickle(45000:d1:r2)", true)
+ client.send()
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/readme.txt b/testing/web-platform/tests/XMLHttpRequest/readme.txt
new file mode 100644
index 000000000..2e5f64cd5
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/readme.txt
@@ -0,0 +1,31 @@
+Currently this testsuite tries to provide tests for XMLHttpRequest level 1.
+This test suite is not stable and is still under development. Tests may
+contain bugs and may change over time as a result of those bugs being fixed.
+
+When more browsers implement XMLHttpRequest level 2 this testsuite will
+slowly evolve most likely.
+
+ http://dev.w3.org/2006/webapi/XMLHttpRequest/
+ http://dev.w3.org/2006/webapi/XMLHttpRequest-2/
+
+If the folders above give the status of the feature tested you can assume
+this is against level 1 unless explicitly stated otherwise.
+
+NOTE: readyState and onreadystatechange are tested throughout the various
+tests. statusText is tested together with status.
+
+NOTE: open-url-base* have absolute paths in them. They need to be adjusted
+on a per location basis.
+
+NOTE: open-url-base-inserted-after-open.htm, open-url-base-inserted.htm,
+send-authentication.htm and open-url-base.htm refer to localhost.
+
+
+TESTS THAT ARE UNSTABLE AND (PROBABLY) NEED CHANGES
+ responsexml-basic (see email WHATWG)
+ send-authentication (see "user:password" debacle)
+
+
+TESTS NOT STARTED ON YET
+
+<iframe> document.domain = w3.org create cross-origin xhr object
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/accept-language.py b/testing/web-platform/tests/XMLHttpRequest/resources/accept-language.py
new file mode 100644
index 000000000..e0fd30c11
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/accept-language.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ return [("Content-Type", "text/plain"),
+ request.headers.get("Accept-Language", "NO")]
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/accept.py b/testing/web-platform/tests/XMLHttpRequest/resources/accept.py
new file mode 100644
index 000000000..2fdf210b6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/accept.py
@@ -0,0 +1,3 @@
+def main(request, response):
+ return [("Content-Type", "text/plain")], request.headers.get("accept", "NO")
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth1/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth1/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth1/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth2/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth2/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth2/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth2/corsenabled.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth2/corsenabled.py
new file mode 100644
index 000000000..ce2269739
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth2/corsenabled.py
@@ -0,0 +1,20 @@
+import imp
+import os
+
+def main(request, response):
+ response.headers.set('Access-Control-Allow-Origin', request.headers.get("origin"));
+ response.headers.set('Access-Control-Allow-Credentials', 'true');
+ response.headers.set('Access-Control-Allow-Methods', 'GET');
+ response.headers.set('Access-Control-Allow-Headers', 'authorization, x-user, x-pass');
+ response.headers.set('Access-Control-Expose-Headers', 'x-challenge, xhr-user, ses-user');
+ auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
+ "XMLHttpRequest",
+ "resources",
+ "authentication.py"))
+ if request.method == "OPTIONS":
+ return ""
+ else:
+ return auth.main(request, response)
+
+
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth3/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth3/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth3/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth4/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth4/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth4/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth5/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth5/auth.py
new file mode 100644
index 000000000..bc739f5eb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth5/auth.py
@@ -0,0 +1,13 @@
+def main(request, response):
+ if request.auth.username == 'usr' and request.auth.password == 'secret':
+ response.headers.set('Content-type', 'text/plain')
+ content = ""
+ else:
+ response.status = 401
+ response.headers.set('Status', '401 Authorization required')
+ response.headers.set('WWW-Authenticate', 'Basic realm="test"')
+ content = 'User name/password wrong or not given: '
+
+ content += "%s\n%s" % (request.auth.username,
+ request.auth.password)
+ return content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth6/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth6/auth.py
new file mode 100644
index 000000000..bc739f5eb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth6/auth.py
@@ -0,0 +1,13 @@
+def main(request, response):
+ if request.auth.username == 'usr' and request.auth.password == 'secret':
+ response.headers.set('Content-type', 'text/plain')
+ content = ""
+ else:
+ response.status = 401
+ response.headers.set('Status', '401 Authorization required')
+ response.headers.set('WWW-Authenticate', 'Basic realm="test"')
+ content = 'User name/password wrong or not given: '
+
+ content += "%s\n%s" % (request.auth.username,
+ request.auth.password)
+ return content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth7/corsenabled.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth7/corsenabled.py
new file mode 100644
index 000000000..ce2269739
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth7/corsenabled.py
@@ -0,0 +1,20 @@
+import imp
+import os
+
+def main(request, response):
+ response.headers.set('Access-Control-Allow-Origin', request.headers.get("origin"));
+ response.headers.set('Access-Control-Allow-Credentials', 'true');
+ response.headers.set('Access-Control-Allow-Methods', 'GET');
+ response.headers.set('Access-Control-Allow-Headers', 'authorization, x-user, x-pass');
+ response.headers.set('Access-Control-Expose-Headers', 'x-challenge, xhr-user, ses-user');
+ auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
+ "XMLHttpRequest",
+ "resources",
+ "authentication.py"))
+ if request.method == "OPTIONS":
+ return ""
+ else:
+ return auth.main(request, response)
+
+
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth8/corsenabled-no-authorize.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth8/corsenabled-no-authorize.py
new file mode 100644
index 000000000..cb40efb08
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth8/corsenabled-no-authorize.py
@@ -0,0 +1,20 @@
+import imp
+import os
+
+def main(request, response):
+ response.headers.set('Access-Control-Allow-Origin', request.headers.get("origin"));
+ response.headers.set('Access-Control-Allow-Credentials', 'true');
+ response.headers.set('Access-Control-Allow-Methods', 'GET');
+ response.headers.set('Access-Control-Allow-Headers', 'x-user, x-pass');
+ response.headers.set('Access-Control-Expose-Headers', 'x-challenge, xhr-user, ses-user');
+ auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
+ "XMLHttpRequest",
+ "resources",
+ "authentication.py"))
+ if request.method == "OPTIONS":
+ return ""
+ else:
+ return auth.main(request, response)
+
+
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/auth9/auth.py b/testing/web-platform/tests/XMLHttpRequest/resources/auth9/auth.py
new file mode 100644
index 000000000..8b6682686
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/auth9/auth.py
@@ -0,0 +1,10 @@
+import imp
+import os
+
+here = os.path.split(os.path.abspath(__file__))[0]
+
+def main(request, response):
+ auth = imp.load_source("", os.path.join(here,
+ "..",
+ "authentication.py"))
+ return auth.main(request, response)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/authentication.py b/testing/web-platform/tests/XMLHttpRequest/resources/authentication.py
new file mode 100644
index 000000000..4f65fa23d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/authentication.py
@@ -0,0 +1,32 @@
+def main(request, response):
+ if "logout" in request.GET:
+ return ((401, "Unauthorized"),
+ [("WWW-Authenticate", 'Basic realm="test"')],
+ "Logged out, hopefully")
+
+ session_user = request.auth.username
+ session_pass = request.auth.password
+ expected_user_name = request.headers.get("X-User", None)
+
+ token = expected_user_name
+ if session_user is None and session_pass is None:
+ if token is not None and request.server.stash.take(token) is not None:
+ return 'FAIL (did not authorize)'
+ else:
+ if token is not None:
+ request.server.stash.put(token, "1")
+ status = (401, 'Unauthorized')
+ headers = [('WWW-Authenticate', 'Basic realm="test"'),
+ ('XHR-USER', expected_user_name),
+ ('SES-USER', session_user)]
+ return status, headers, 'FAIL (should be transparent)'
+ else:
+ if request.server.stash.take(token) == "1":
+ challenge = "DID"
+ else:
+ challenge = "DID-NOT"
+ headers = [('XHR-USER', expected_user_name),
+ ('SES-USER', session_user),
+ ("X-challenge", challenge)]
+ return headers, session_user + "\n" + session_pass;
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/chunked.py b/testing/web-platform/tests/XMLHttpRequest/resources/chunked.py
new file mode 100644
index 000000000..7e8433bd8
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/chunked.py
@@ -0,0 +1,18 @@
+def main(request, response):
+ chunks = ["First chunk\r\n",
+ "Second chunk\r\n",
+ "Yet another (third) chunk\r\n",
+ "Yet another (fourth) chunk\r\n",
+ ]
+ response.headers.set("Transfer-Encoding", "chunked");
+ response.headers.set("Trailer", "X-Test-Me");
+ response.headers.set("Content-Type", "text/plain");
+ response.write_status_headers()
+
+ for value in chunks:
+ response.writer.write("%x\r\n" % len(value))
+ response.writer.write(value)
+ response.writer.write("\r\n")
+ response.writer.write("0\r\n")
+ response.writer.write("X-Test-Me: Trailer header value\r\n\r\n")
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/conditional.py b/testing/web-platform/tests/XMLHttpRequest/resources/conditional.py
new file mode 100644
index 000000000..42dfecdfb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/conditional.py
@@ -0,0 +1,17 @@
+def main(request, response):
+ tag = request.GET.first("tag", None)
+ match = request.headers.get("If-None-Match", None)
+ date = request.GET.first("date", "")
+ modified = request.headers.get("If-Modified-Since", None)
+ if tag:
+ response.headers.set("ETag", '"%s"' % tag)
+ elif date:
+ response.headers.set("Last-Modified", date)
+
+ if ((match is not None and match == tag) or
+ (modified is not None and modified == date)):
+ response.status = (304, "SUPERCOOL")
+ return ""
+ else:
+ response.headers.set("Content-Type", "text/plain")
+ return "MAYBE NOT"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/content.py b/testing/web-platform/tests/XMLHttpRequest/resources/content.py
new file mode 100644
index 000000000..d7c62ab6d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/content.py
@@ -0,0 +1,18 @@
+def main(request, response):
+ response_ctype = ''
+
+ if "response_charset_label" in request.GET:
+ response_ctype = ";charset=" + request.GET.first("response_charset_label")
+
+ headers = [("Content-type", "text/plain" + response_ctype),
+ ("X-Request-Method", request.method),
+ ("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"),
+ ("X-Request-Content-Length", request.headers.get("Content-Length", "NO")),
+ ("X-Request-Content-Type", request.headers.get("Content-Type", "NO"))]
+
+ if "content" in request.GET:
+ content = request.GET.first("content")
+ else:
+ content = request.body
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/corsenabled.py b/testing/web-platform/tests/XMLHttpRequest/resources/corsenabled.py
new file mode 100644
index 000000000..1f0f878f4
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/corsenabled.py
@@ -0,0 +1,20 @@
+import time
+
+def main(request, response):
+ headers = [("Access-Control-Allow-Origin", "*"),
+ ("Access-Control-Allow-Credentials", "true"),
+ ("Access-Control-Allow-Methods", "GET, POST, PUT, FOO"),
+ ("Access-Control-Allow-Headers", "x-test, x-foo"),
+ ("Access-Control-Expose-Headers", "x-request-method, x-request-content-type, x-request-query, x-request-content-length, x-request-data")]
+
+ if "delay" in request.GET:
+ delay = int(request.GET.first("delay"))
+ time.sleep(delay)
+
+ headers.append(("X-Request-Method", request.method))
+ headers.append(("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"))
+ headers.append(("X-Request-Content-Length", request.headers.get("Content-Length", "NO")))
+ headers.append(("X-Request-Content-Type", request.headers.get("Content-Type", "NO")))
+ headers.append(("X-Request-Data", request.body))
+
+ return headers, "Test"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/delay.py b/testing/web-platform/tests/XMLHttpRequest/resources/delay.py
new file mode 100644
index 000000000..bdfef9b34
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/delay.py
@@ -0,0 +1,6 @@
+import time
+
+def main(request, response):
+ delay = float(request.GET.first("ms", 500))
+ time.sleep(delay / 1E3);
+ return [("Content-type", "text/plain")], "TEST_DELAY"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/echo-method.py b/testing/web-platform/tests/XMLHttpRequest/resources/echo-method.py
new file mode 100644
index 000000000..5351d1961
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/echo-method.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ response.send_body_for_head_request = True
+ headers = [("Content-type", "text/plain")]
+ content = request.method
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/empty-div-utf8-html.py b/testing/web-platform/tests/XMLHttpRequest/resources/empty-div-utf8-html.py
new file mode 100644
index 000000000..26d54b9d1
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/empty-div-utf8-html.py
@@ -0,0 +1,5 @@
+def main(request, response):
+ headers = [("Content-type", "text/html;charset=utf-8")]
+ content = "<!DOCTYPE html><div></div>"
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/folder.txt b/testing/web-platform/tests/XMLHttpRequest/resources/folder.txt
new file mode 100644
index 000000000..fef12e219
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/folder.txt
@@ -0,0 +1 @@
+bottom
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/form.py b/testing/web-platform/tests/XMLHttpRequest/resources/form.py
new file mode 100644
index 000000000..6b1c49a99
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/form.py
@@ -0,0 +1,2 @@
+def main(request, response):
+ return "id:%s;value:%s;" % (request.POST.first("id"), request.POST.first("value"))
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/gzip.py b/testing/web-platform/tests/XMLHttpRequest/resources/gzip.py
new file mode 100644
index 000000000..87dd5bec0
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/gzip.py
@@ -0,0 +1,23 @@
+import gzip as gzip_module
+from cStringIO import StringIO
+
+def main(request, response):
+ if "content" in request.GET:
+ output = request.GET["content"]
+ else:
+ output = request.body
+
+ out = StringIO()
+ with gzip_module.GzipFile(fileobj=out, mode="w") as f:
+ f.write(output)
+ output = out.getvalue()
+
+ headers = [("Content-type", "text/plain"),
+ ("Content-Encoding", "gzip"),
+ ("X-Request-Method", request.method),
+ ("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"),
+ ("X-Request-Content-Length", request.headers.get("Content-Length", "NO")),
+ ("X-Request-Content-Type", request.headers.get("Content-Type", "NO")),
+ ("Content-Length", len(output))]
+
+ return headers, output
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/headers.py b/testing/web-platform/tests/XMLHttpRequest/resources/headers.py
new file mode 100644
index 000000000..cefa8ee65
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/headers.py
@@ -0,0 +1,12 @@
+ # -*- coding: utf-8 -*-
+
+def main(request, response):
+ response.headers.set("Content-Type", "text/plain")
+ response.headers.set("X-Custom-Header", "test")
+ response.headers.set("Set-Cookie", "test")
+ response.headers.set("Set-Cookie2", "test")
+ response.headers.set("X-Custom-Header-Empty", "")
+ response.headers.set("X-Custom-Header-Comma", "1")
+ response.headers.append("X-Custom-Header-Comma", "2")
+ response.headers.set("X-Custom-Header-Bytes", "…")
+ return "TEST"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/image.gif b/testing/web-platform/tests/XMLHttpRequest/resources/image.gif
new file mode 100644
index 000000000..6d1174af1
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/image.gif
Binary files differ
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/img-utf8-html.py b/testing/web-platform/tests/XMLHttpRequest/resources/img-utf8-html.py
new file mode 100644
index 000000000..085867f95
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/img-utf8-html.py
@@ -0,0 +1,5 @@
+def main(request, response):
+ headers = [("Content-type", "text/html;charset=utf-8")]
+ content = "<img>foo"
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/img.jpg b/testing/web-platform/tests/XMLHttpRequest/resources/img.jpg
new file mode 100644
index 000000000..7aa936252
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/img.jpg
Binary files differ
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/infinite-redirects.py b/testing/web-platform/tests/XMLHttpRequest/resources/infinite-redirects.py
new file mode 100644
index 000000000..b508c5b3c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/infinite-redirects.py
@@ -0,0 +1,24 @@
+def main(request, response):
+ location = "%s://%s:%s/%s" % (request.url_parts.scheme,
+ request.url_parts.netloc,
+ request.url_parts.port,
+ request.url_parts.path)
+ page = "alternate";
+ type = 302;
+ mix = 0;
+ if request.GET.first("page", None) == "alternate":
+ page = "default"
+
+ if request.GET.first("type", None) == "301":
+ type = 301
+
+ if request.GET.first("mix", None) == "1":
+ mix = 1
+ type = 302 if type == 301 else 301
+
+ new_location = "%s?page=%s&type=%s&mix=%s" % (location, page, type, mix)
+ headers = [("Cache-Control", "no-cache"),
+ ("Pragma", "no-cache"),
+ ("Location", new_location)]
+ return 301, headers, "Hello guest. You have been redirected to " + new_location
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/init.htm b/testing/web-platform/tests/XMLHttpRequest/resources/init.htm
new file mode 100644
index 000000000..6f936c4fb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/init.htm
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <title>support init file</title>
+ </head>
+ <body>
+ <script>
+ onload = function() {
+ // Run async, because navigations from inside onload can be a bit weird.
+ setTimeout(function() {
+ if (parent != window) {
+ parent.init()
+ } else {
+ opener.init();
+ }
+ }, 0);
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/inspect-headers.py b/testing/web-platform/tests/XMLHttpRequest/resources/inspect-headers.py
new file mode 100644
index 000000000..ca5960557
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/inspect-headers.py
@@ -0,0 +1,22 @@
+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, x-request-content-type, x-request-query, x-request-content-length"))
+
+ filter_value = request.GET.first("filter_value", "")
+ filter_name = request.GET.first("filter_name", "").lower()
+
+ result = ""
+ for name, value in request.headers.iteritems():
+ if filter_value:
+ if value == filter_value:
+ result += name.lower() + ","
+ elif name.lower() == filter_name:
+ result += name.lower() + ": " + value + "\n";
+
+ headers.append(("content-type", "text/plain"))
+ return headers, result
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/invalid-utf8-html.py b/testing/web-platform/tests/XMLHttpRequest/resources/invalid-utf8-html.py
new file mode 100644
index 000000000..72be41a45
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/invalid-utf8-html.py
@@ -0,0 +1,5 @@
+def main(request, response):
+ headers = [("Content-type", "text/html;charset=utf-8")]
+ content = chr(0xff)
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/last-modified.py b/testing/web-platform/tests/XMLHttpRequest/resources/last-modified.py
new file mode 100644
index 000000000..ef05a6343
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/last-modified.py
@@ -0,0 +1,7 @@
+def main(request, response):
+ import datetime, os
+ srcpath = os.path.join(os.path.dirname(__file__), "well-formed.xml")
+ srcmoddt = datetime.datetime.fromtimestamp(os.path.getmtime(srcpath))
+ response.headers.set("Last-Modified", srcmoddt.strftime("%a, %d %b %Y %H:%M:%S GMT"))
+ response.headers.set("Content-Type", "application/xml")
+ return open(srcpath, "r").read()
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/nocors/folder.txt b/testing/web-platform/tests/XMLHttpRequest/resources/nocors/folder.txt
new file mode 100644
index 000000000..5257b481d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/nocors/folder.txt
@@ -0,0 +1 @@
+not CORS-enabled \ No newline at end of file
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/parse-headers.py b/testing/web-platform/tests/XMLHttpRequest/resources/parse-headers.py
new file mode 100644
index 000000000..fdc626539
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/parse-headers.py
@@ -0,0 +1,10 @@
+import json
+
+def main(request, response):
+
+ content = ""
+ if "my-custom-header" in request.GET:
+ val = request.GET.first("my-custom-header")
+ response.headers.set("My-Custom-Header", val)
+
+ return content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/redirect.py b/testing/web-platform/tests/XMLHttpRequest/resources/redirect.py
new file mode 100644
index 000000000..6ec934956
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/redirect.py
@@ -0,0 +1,8 @@
+def main(request, response):
+ code = int(request.GET.first("code", 302))
+ location = request.GET.first("location", request.url_parts.path +"?followed")
+
+ if request.url.endswith("?followed"):
+ return [("Content:Type", "text/plain")], "MAGIC HAPPENED"
+ else:
+ return (code, "WEBSRT MARKETING"), [("Location", location)], "TEST"
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/requri.py b/testing/web-platform/tests/XMLHttpRequest/resources/requri.py
new file mode 100644
index 000000000..eaa562dff
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/requri.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ if "full" in request.GET:
+ return request.url
+ else:
+ return request.request_path
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-1.htm b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-1.htm
new file mode 100644
index 000000000..4e4c3faff
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-1.htm
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() with document.domain set: loading documents from original origin after setting document.domain</title>
+ <script src="send-after-setting-document-domain-window-helper.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[3]" />
+ </head>
+ <body>
+ <script>
+ run_test(function() {
+ document.domain = document.domain; // this is not a noop, it does actually change the security context
+ var client = new XMLHttpRequest();
+ client.open("GET", "status.py?content=hello", false);
+ client.send(null);
+ assert_equals(client.responseText, "hello");
+ document.domain = document.domain.replace(/^\w+\./, "");
+ client.open("GET", "status.py?content=hello2", false);
+ client.send(null);
+ assert_equals(client.responseText, "hello2");
+ }, "loading documents from original origin after setting document.domain");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-2.htm b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-2.htm
new file mode 100644
index 000000000..073268c21
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-2.htm
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() with document.domain set: loading documents from the origin document.domain was set to should throw</title>
+ <script src="send-after-setting-document-domain-window-helper.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[3]" />
+ </head>
+ <body>
+ <script>
+ run_test(function() {
+ document.domain = document.domain.replace(/^\w+\./, "");
+ var client = new XMLHttpRequest();
+ client.open("GET", location.protocol + "//" + document.domain + location.pathname.replace(/[^\/]*$/, "") + "status.py?content=hello3", false);
+ assert_throws("NetworkError", function() {
+ client.send(null);
+ });
+ }, "loading documents from the origin document.domain was set to should throw");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-helper.js b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-helper.js
new file mode 100644
index 000000000..f5c762b04
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/send-after-setting-document-domain-window-helper.js
@@ -0,0 +1,29 @@
+function assert_equals(value, expected) {
+ if (value != expected) {
+ throw "Got wrong value.\nExpected '" + expected + "',\ngot '" + value + "'";
+ }
+}
+
+function assert_throws(expected_exc, func) {
+ try {
+ func.call(this);
+ } catch(e) {
+ var actual = e.name || e.type;
+ if (actual != expected_exc) {
+ throw "Got wrong exception.\nExpected '" + expected_exc + "',\ngot '" + actual + "'.";
+ }
+ return;
+ }
+ throw "Expected exception, but none was thrown";
+}
+
+function run_test(test, name) {
+ var result = {passed: true, message: null, name: name};
+ try {
+ test();
+ } catch(e) {
+ result.passed = false;
+ result.message = e + "";
+ }
+ opener.postMessage(result, "*");
+}
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/shift-jis-html.py b/testing/web-platform/tests/XMLHttpRequest/resources/shift-jis-html.py
new file mode 100644
index 000000000..92d06ca78
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/shift-jis-html.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ headers = [("Content-type", "text/html;charset=shift-jis")]
+ # Shift-JIS bytes for katakana TE SU TO ('test')
+ content = chr(0x83) + chr(0x65) + chr(0x83) + chr(0x58) + chr(0x83) + chr(0x67);
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/status.py b/testing/web-platform/tests/XMLHttpRequest/resources/status.py
new file mode 100644
index 000000000..5d72e10b2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/status.py
@@ -0,0 +1,9 @@
+def main(request, response):
+ code = int(request.GET.first("code", 200))
+ text = request.GET.first("text", "OMG")
+ content = request.GET.first("content", "")
+ type = request.GET.first("type", "")
+ status = (code, text)
+ headers = [("Content-Type", type),
+ ("X-Request-Method", request.method)]
+ return status, headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/trickle.py b/testing/web-platform/tests/XMLHttpRequest/resources/trickle.py
new file mode 100644
index 000000000..5a46c5e82
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/trickle.py
@@ -0,0 +1,15 @@
+import time
+
+def main(request, response):
+ chunk = "TEST_TRICKLE\n"
+ delay = float(request.GET.first("ms", 500)) / 1E3
+ count = int(request.GET.first("count", 50))
+ if "specifylength" in request.GET:
+ response.headers.set("Content-Length", count * len(chunk))
+ 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(chunk)
+ time.sleep(delay)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/upload.py b/testing/web-platform/tests/XMLHttpRequest/resources/upload.py
new file mode 100644
index 000000000..27cee598b
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/upload.py
@@ -0,0 +1,15 @@
+def main(request, response):
+ content = []
+
+ for key, values in sorted(item for item in request.POST.items() if not hasattr(item[1][0], "filename")):
+ content.append("%s=%s," % (key, values[0]))
+ content.append("\n")
+
+ for key, values in sorted(item for item in request.POST.items() if hasattr(item[1][0], "filename")):
+ value = values[0]
+ content.append("%s=%s:%s:%s," % (key,
+ value.filename,
+ value.headers["Content-Type"],
+ len(value.file.read())))
+
+ return "".join(content)
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/utf16.txt b/testing/web-platform/tests/XMLHttpRequest/resources/utf16.txt
new file mode 100644
index 000000000..0085dfaee
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/utf16.txt
Binary files differ
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/well-formed.xml b/testing/web-platform/tests/XMLHttpRequest/resources/well-formed.xml
new file mode 100644
index 000000000..2f4f12698
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/well-formed.xml
@@ -0,0 +1,4 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <p id="n&#49;">1</p>
+ <p xmlns="namespacesarejuststrings" id="n2">2</p>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/win-1252-xml.py b/testing/web-platform/tests/XMLHttpRequest/resources/win-1252-xml.py
new file mode 100644
index 000000000..09c32e457
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/win-1252-xml.py
@@ -0,0 +1,5 @@
+def main(request, response):
+ headers = [("Content-type", "application/xml;charset=windows-1252")]
+ content = '<' + chr(0xff) + '/>'
+
+ return headers, content
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-origin-referrer.js b/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-origin-referrer.js
new file mode 100644
index 000000000..5e2ef2a8c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-origin-referrer.js
@@ -0,0 +1,34 @@
+// This simply posts a message to the owner page with the contents of the Referer header
+var xhr=new XMLHttpRequest()
+xhr.onreadystatechange = function(){
+ if(xhr.readyState == 4){
+ var obj = {test:'Referer header', result:xhr.responseText}
+ self.postMessage(obj)
+ }
+}
+xhr.open('GET', 'inspect-headers.py?filter_name=referer', true)
+xhr.send()
+
+// This simply posts a message to the owner page with the contents of the Origin header
+var xhr2=new XMLHttpRequest()
+xhr2.onreadystatechange = function(){
+ if(xhr2.readyState == 4){
+ var obj = {test:'Origin header', result:xhr2.responseText}
+ self.postMessage(obj)
+ }
+}
+xhr2.open('GET', location.protocol + '//www2.'+location.hostname+((location.port === "")?"":":"+location.port)+(location.pathname.replace(/[^/]*$/, ''))+'inspect-headers.py?filter_name=origin&cors', true)
+xhr2.send()
+
+// If "origin" / base URL is the origin of this JS file, we can load files
+// from the server it originates from.. and requri.py will be able to tell us
+// what the requested URL was
+var xhr3=new XMLHttpRequest()
+xhr3.onreadystatechange = function(){
+ if(xhr3.readyState == 4){
+ var obj = {test:'Request URL test', result:xhr3.responseText}
+ self.postMessage(obj)
+ }
+}
+xhr3.open('GET', 'requri.py?full', true)
+xhr3.send()
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-simple.js b/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-simple.js
new file mode 100644
index 000000000..f6bcec0be
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/workerxhr-simple.js
@@ -0,0 +1,10 @@
+
+var xhr=new XMLHttpRequest()
+xhr.onreadystatechange = function(){
+ if(xhr.readyState == 4){
+ var status = xhr.responseText === 'bottom\n' ? 'PASSED' : 'FAILED'
+ self.postMessage(status)
+ }
+}
+xhr.open('GET', 'folder.txt', true)
+xhr.send()
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js
new file mode 100644
index 000000000..b6bb6cdf3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js
@@ -0,0 +1,83 @@
+(function(global) {
+ var recorded_xhr_events = [];
+
+ function record_xhr_event(e) {
+ var prefix = e.target instanceof XMLHttpRequestUpload ? "upload." : "";
+ recorded_xhr_events.push((prefix || "") + e.type + "(" + e.loaded + "," + e.total + "," + e.lengthComputable + ")");
+ }
+
+ global.prepare_xhr_for_event_order_test = function(xhr) {
+ xhr.addEventListener("readystatechange", function(e) {
+ recorded_xhr_events.push(xhr.readyState);
+ });
+ var events = ["loadstart", "progress", "abort", "timeout", "error", "load", "loadend"];
+ for(var i=0; i<events.length; ++i) {
+ xhr.addEventListener(events[i], record_xhr_event);
+ }
+ if ("upload" in xhr) {
+ for(var i=0; i<events.length; ++i) {
+ xhr.upload.addEventListener(events[i], record_xhr_event);
+ }
+ }
+ }
+
+ function getNextEvent(arr) {
+ var event = { str: arr.shift() };
+
+ // we can only handle strings, numbers (readystates) and undefined
+ if (event.str === undefined) {
+ return event;
+ }
+
+ if (typeof event.str !== "string") {
+ if (Number.isInteger(event.str)) {
+ event.state = event.str;
+ event.str = "readystatechange(" + event.str + ")";
+ } else {
+ throw "Test error: unexpected event type " + event.str;
+ }
+ }
+
+ // parse out the general type, loaded and total values
+ var type = event.type = event.str.split("(")[0].split(".").pop();
+ var loadedAndTotal = event.str.match(/.*\((\d+),(\d+),(true|false)\)/);
+ if (loadedAndTotal) {
+ event.loaded = parseInt(loadedAndTotal[1]);
+ event.total = parseInt(loadedAndTotal[2]);
+ event.lengthComputable = loadedAndTotal[3] == "true";
+ }
+
+ return event;
+ }
+
+ global.assert_xhr_event_order_matches = function(expected) {
+ var recorded = recorded_xhr_events;
+ var lastRecordedLoaded = -1;
+ while(expected.length && recorded.length) {
+ var currentExpected = getNextEvent(expected),
+ currentRecorded = getNextEvent(recorded);
+
+ // skip to the last progress event if we've hit one (note the next
+ // event after a progress event should be a LOADING readystatechange,
+ // if there are multiple progress events in a row).
+ while (recorded.length && currentRecorded.type == "progress" &&
+ parseInt(recorded) === 3) {
+ assert_greater_than(currentRecorded.loaded, lastRecordedLoaded,
+ "progress event 'loaded' values must only increase");
+ lastRecordedLoaded = currentRecorded.loaded;
+ }
+ if (currentRecorded.type == "loadend") {
+ recordedProgressCount = 0;
+ lastRecordedLoaded = -1;
+ }
+
+ assert_equals(currentRecorded.str, currentExpected.str);
+ }
+ if (recorded.length) {
+ throw "\nUnexpected extra events: " + recorded.join(", ");
+ }
+ if (expected.length) {
+ throw "\nExpected more events: " + expected.join(", ");
+ }
+ }
+}(this));
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-aborted.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-aborted.js
new file mode 100644
index 000000000..056d77c01
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-aborted.js
@@ -0,0 +1,15 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+/*
+This sets up three requests:
+The first request will only be open()ed, not aborted, timeout will be TIME_REGULAR_TIMEOUT but will never triggered because send() isn't called.
+After TIME_NORMAL_LOAD, the test asserts that no load/error/timeout/abort events fired
+
+Second request will be aborted immediately after send(), test asserts that abort fired
+
+Third request is set up to call abort() after TIME_NORMAL_LOAD, but it also has a TIME_REGULAR_TIMEOUT timeout. Asserts that timeout fired.
+(abort() is called later and should not fire an abort event per spec. This is untested!)
+*/
+runTestRequests([ new AbortedRequest(false),
+ new AbortedRequest(true, -1),
+ new AbortedRequest(true, TIME_NORMAL_LOAD) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-abortedonmain.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-abortedonmain.js
new file mode 100644
index 000000000..8dde8ef57
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-abortedonmain.js
@@ -0,0 +1,8 @@
+/*
+This test sets up two requests:
+one that gets abort()ed from a 0ms timeout (0ms will obviously be clamped to whatever the implementation's minimal value is), asserts abort event fires
+one that will be aborted after TIME_DELAY, (with a timeout at TIME_REGULAR_TIMEOUT) asserts abort event fires. Does not assert that the timeout event does *not* fire.
+*/
+
+runTestRequests([ new AbortedRequest(true, 0),
+ new AbortedRequest(true, TIME_DELAY) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overrides.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overrides.js
new file mode 100644
index 000000000..6dc2173b2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overrides.js
@@ -0,0 +1,11 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+/*
+Sets up three requests to a resource that will take 0.6 seconds to load:
+1) timeout first set to TIME_NORMAL_LOAD, after TIME_REGULAR_TIMEOUT timeout is set to 0, asserts load fires
+2) timeout first set to TIME_NORMAL_LOAD, after TIME_DELAY timeout is set to TIME_REGULAR_TIMEOUT, asserts load fires (race condition..?!?)
+3) timeout first set to 0, after TIME_REGULAR_TIMEOUT it is set to TIME_REGULAR_TIMEOUT * 10, asserts load fires
+*/
+runTestRequests([ new RequestTracker(true, "timeout disabled after initially set", TIME_NORMAL_LOAD, TIME_REGULAR_TIMEOUT, 0),
+ new RequestTracker(true, "timeout overrides load after a delay", TIME_NORMAL_LOAD, TIME_DELAY, TIME_REGULAR_TIMEOUT),
+ new RequestTracker(true, "timeout enabled after initially disabled", 0, TIME_REGULAR_TIMEOUT, TIME_NORMAL_LOAD * 10) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overridesexpires.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overridesexpires.js
new file mode 100644
index 000000000..bf251fa80
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-overridesexpires.js
@@ -0,0 +1,12 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+/*
+ Starts three requests:
+ 1) XHR to resource which will take a least TIME_XHR_LOAD ms with timeout initially set to TIME_NORMAL_LOAD ms. After TIME_LATE_TIMEOUT ms timeout is supposedly reset to TIME_DELAY ms,
+ but the resource should have finished loading already. Asserts "load" fires.
+ 2) XHR with initial timeout set to TIME_NORMAL_LOAD, after TIME_REGULAR_TIMEOUT sets timeout to TIME_DELAY+100. Asserts "timeout" fires.
+ 3) XHR with initial timeout set to TIME_DELAY, after TIME_REGULAR_TIMEOUT sets timeout to 500ms. Asserts "timeout" fires (the change happens when timeout already fired and the request is done).
+*/
+runTestRequests([ new RequestTracker(true, "timeout set to expiring value after load fires", TIME_NORMAL_LOAD, TIME_LATE_TIMEOUT, TIME_DELAY),
+ new RequestTracker(true, "timeout set to expired value before load fires", TIME_NORMAL_LOAD, TIME_REGULAR_TIMEOUT, TIME_DELAY+100),
+ new RequestTracker(true, "timeout set to non-expiring value after timeout fires", TIME_DELAY, TIME_REGULAR_TIMEOUT, 500) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-runner.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-runner.js
new file mode 100644
index 000000000..151226a94
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-runner.js
@@ -0,0 +1,21 @@
+
+function testResultCallbackHandler(event) {
+ if (event.data == "done") {
+ done();
+ return;
+ }
+ if (event.data.type == "is") {
+ test(function() { assert_equals(event.data.got, event.data.expected); }, "Timeout test: " + event.data.msg);
+ return;
+ }
+ if (event.data.type == "ok") {
+ test(function() { assert_true(event.data.bool); }, "Timeout test: " + event.data.msg);
+ return;
+ }
+}
+
+window.addEventListener("message", testResultCallbackHandler);
+
+// Setting up testharness.js
+setup({ explicit_done: true });
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-simple.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-simple.js
new file mode 100644
index 000000000..0207cf107
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-simple.js
@@ -0,0 +1,6 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+
+runTestRequests([ new RequestTracker(true, "no time out scheduled, load fires normally", 0),
+ new RequestTracker(true, "load fires normally", TIME_NORMAL_LOAD),
+ new RequestTracker(true, "timeout hit before load", TIME_REGULAR_TIMEOUT) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconmain.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconmain.js
new file mode 100644
index 000000000..c6c5e985d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconmain.js
@@ -0,0 +1,2 @@
+runTestRequests([ SyncRequestSettingTimeoutAfterOpen,
+ SyncRequestSettingTimeoutBeforeOpen ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconworker.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconworker.js
new file mode 100644
index 000000000..5a6c3fc55
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-synconworker.js
@@ -0,0 +1,11 @@
+if (this.document === undefined){
+ importScripts("xmlhttprequest-timeout.js");
+}else{
+ throw "This test expects to be run as a Worker";
+}
+
+/* NOT TESTED: setting timeout before calling open( ... , false) in a worker context. The test code always calls open() first. */
+
+runTestRequests([ new RequestTracker(false, "no time out scheduled, load fires normally", 0),
+ new RequestTracker(false, "load fires normally", TIME_NORMAL_LOAD),
+ new RequestTracker(false, "timeout hit before load", TIME_REGULAR_TIMEOUT) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-twice.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-twice.js
new file mode 100644
index 000000000..0061c7333
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout-twice.js
@@ -0,0 +1,6 @@
+if (this.document === undefined)
+ importScripts("xmlhttprequest-timeout.js");
+
+runTestRequests([ new RequestTracker(true, "load fires normally with no timeout set, twice", 0, TIME_REGULAR_TIMEOUT, 0),
+ new RequestTracker(true, "load fires normally with same timeout set twice", TIME_NORMAL_LOAD, TIME_REGULAR_TIMEOUT, TIME_NORMAL_LOAD),
+ new RequestTracker(true, "timeout fires normally with same timeout set twice", TIME_REGULAR_TIMEOUT, TIME_DELAY, TIME_REGULAR_TIMEOUT) ]);
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout.js b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout.js
new file mode 100644
index 000000000..01e63cde6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-timeout.js
@@ -0,0 +1,325 @@
+/* Test adapted from Alex Vincent's XHR2 timeout tests, written for Mozilla.
+ https://hg.mozilla.org/mozilla-central/file/tip/content/base/test/
+ Released into the public domain or under BSD, according to
+ https://bugzilla.mozilla.org/show_bug.cgi?id=525816#c86
+*/
+
+/* Notes:
+ - All times are expressed in milliseconds in this test suite.
+ - Test harness code is at the end of this file.
+ - We generate only one request at a time, to avoid overloading the HTTP
+ request handlers.
+ */
+
+var TIME_NORMAL_LOAD = 5000;
+var TIME_LATE_TIMEOUT = 4000;
+var TIME_XHR_LOAD = 3000;
+var TIME_REGULAR_TIMEOUT = 2000;
+var TIME_SYNC_TIMEOUT = 1000;
+var TIME_DELAY = 1000;
+
+/*
+ * This should point to a resource that responds with a text/plain resource after a delay of TIME_XHR_LOAD milliseconds.
+ */
+var STALLED_REQUEST_URL = "delay.py?ms=" + (TIME_XHR_LOAD);
+
+var inWorker = false;
+try {
+ inWorker = !(self instanceof Window);
+} catch (e) {
+ inWorker = true;
+}
+
+if (!inWorker)
+ STALLED_REQUEST_URL = "resources/" + STALLED_REQUEST_URL;
+
+function message(obj) {
+ if (inWorker)
+ self.postMessage(obj);
+ else
+ self.postMessage(obj, "*");
+}
+
+function is(got, expected, msg) {
+ var obj = {};
+ obj.type = "is";
+ obj.got = got;
+ obj.expected = expected;
+ obj.msg = msg;
+
+ message(obj);
+}
+
+function ok(bool, msg) {
+ var obj = {};
+ obj.type = "ok";
+ obj.bool = bool;
+ obj.msg = msg;
+
+ message(obj);
+}
+
+/**
+ * Generate and track results from a XMLHttpRequest with regards to timeouts.
+ *
+ * @param {String} id The test description.
+ * @param {Number} timeLimit The initial setting for the request timeout.
+ * @param {Number} resetAfter (Optional) The time after sending the request, to
+ * reset the timeout.
+ * @param {Number} resetTo (Optional) The delay to reset the timeout to.
+ *
+ * @note The actual testing takes place in handleEvent(event).
+ * The requests are generated in startXHR().
+ *
+ * @note If resetAfter and resetTo are omitted, only the initial timeout setting
+ * applies.
+ *
+ * @constructor
+ * @implements DOMEventListener
+ */
+function RequestTracker(async, id, timeLimit /*[, resetAfter, resetTo]*/) {
+ this.async = async;
+ this.id = id;
+ this.timeLimit = timeLimit;
+
+ if (arguments.length > 3) {
+ this.mustReset = true;
+ this.resetAfter = arguments[3];
+ this.resetTo = arguments[4];
+ }
+
+ this.hasFired = false;
+}
+RequestTracker.prototype = {
+ /**
+ * Start the XMLHttpRequest!
+ */
+ startXHR: function() {
+ var req = new XMLHttpRequest();
+ this.request = req;
+ req.open("GET", STALLED_REQUEST_URL, this.async);
+ var me = this;
+ function handleEvent(e) { return me.handleEvent(e); };
+ req.onerror = handleEvent;
+ req.onload = handleEvent;
+ req.onabort = handleEvent;
+ req.ontimeout = handleEvent;
+
+ req.timeout = this.timeLimit;
+
+ if (this.mustReset) {
+ var resetTo = this.resetTo;
+ self.setTimeout(function() {
+ req.timeout = resetTo;
+ }, this.resetAfter);
+ }
+
+ try {
+ req.send(null);
+ }
+ catch (e) {
+ // Synchronous case in workers.
+ ok(!this.async && this.timeLimit < TIME_XHR_LOAD && e.name == "TimeoutError", "Unexpected error: " + e);
+ TestCounter.testComplete();
+ }
+ },
+
+ /**
+ * Get a message describing this test.
+ *
+ * @returns {String} The test description.
+ */
+ getMessage: function() {
+ var rv = this.id + ", ";
+ if (this.mustReset) {
+ rv += "original timeout at " + this.timeLimit + ", ";
+ rv += "reset at " + this.resetAfter + " to " + this.resetTo;
+ }
+ else {
+ rv += "timeout scheduled at " + this.timeLimit;
+ }
+ return rv;
+ },
+
+ /**
+ * Check the event received, and if it's the right (and only) one we get.
+ *
+ * @param {DOMProgressEvent} evt An event of type "load" or "timeout".
+ */
+ handleEvent: function(evt) {
+ if (this.hasFired) {
+ ok(false, "Only one event should fire: " + this.getMessage());
+ return;
+ }
+ this.hasFired = true;
+
+ var type = evt.type, expectedType;
+ // The XHR responds after TIME_XHR_LOAD milliseconds with a load event.
+ var timeLimit = this.mustReset && (this.resetAfter < Math.min(TIME_XHR_LOAD, this.timeLimit)) ?
+ this.resetTo :
+ this.timeLimit;
+ if ((timeLimit == 0) || (timeLimit >= TIME_XHR_LOAD)) {
+ expectedType = "load";
+ }
+ else {
+ expectedType = "timeout";
+ }
+ is(type, expectedType, this.getMessage());
+ TestCounter.testComplete();
+ }
+};
+
+/**
+ * Generate and track XMLHttpRequests which will have abort() called on.
+ *
+ * @param shouldAbort {Boolean} True if we should call abort at all.
+ * @param abortDelay {Number} The time in ms to wait before calling abort().
+ */
+function AbortedRequest(shouldAbort, abortDelay) {
+ this.shouldAbort = shouldAbort;
+ this.abortDelay = abortDelay;
+ this.hasFired = false;
+}
+AbortedRequest.prototype = {
+ /**
+ * Start the XMLHttpRequest!
+ */
+ startXHR: function() {
+ var req = new XMLHttpRequest();
+ this.request = req;
+ req.open("GET", STALLED_REQUEST_URL);
+ var _this = this;
+ function handleEvent(e) { return _this.handleEvent(e); };
+ req.onerror = handleEvent;
+ req.onload = handleEvent;
+ req.onabort = handleEvent;
+ req.ontimeout = handleEvent;
+
+ req.timeout = TIME_REGULAR_TIMEOUT;
+
+ function abortReq() {
+ req.abort();
+ }
+
+ if (!this.shouldAbort) {
+ self.setTimeout(function() {
+ try {
+ _this.noEventsFired();
+ }
+ catch (e) {
+ ok(false, "Unexpected error: " + e);
+ TestCounter.testComplete();
+ }
+ }, TIME_NORMAL_LOAD);
+ }
+ else {
+ // Abort events can only be triggered on sent requests.
+ req.send();
+ if (this.abortDelay == -1) {
+ abortReq();
+ }
+ else {
+ self.setTimeout(abortReq, this.abortDelay);
+ }
+ }
+ },
+
+ /**
+ * Ensure that no events fired at all, especially not our timeout event.
+ */
+ noEventsFired: function() {
+ ok(!this.hasFired, "No events should fire for an unsent, unaborted request");
+ // We're done; if timeout hasn't fired by now, it never will.
+ TestCounter.testComplete();
+ },
+
+ /**
+ * Get a message describing this test.
+ *
+ * @returns {String} The test description.
+ */
+ getMessage: function() {
+ return "time to abort is " + this.abortDelay + ", timeout set at " + TIME_REGULAR_TIMEOUT;
+ },
+
+ /**
+ * Check the event received, and if it's the right (and only) one we get.
+ *
+ * WebKit fires abort events even for DONE and UNSENT states, which is
+ * discussed in http://webkit.org/b/98404
+ * That's why we chose to accept secondary "abort" events in this test.
+ *
+ * @param {DOMProgressEvent} evt An event of type "load" or "timeout".
+ */
+ handleEvent: function(evt) {
+ if (this.hasFired && evt.type != "abort") {
+ ok(false, "Only abort event should fire: " + this.getMessage());
+ return;
+ }
+
+ var expectedEvent = (this.abortDelay >= TIME_REGULAR_TIMEOUT && !this.hasFired) ? "timeout" : "abort";
+ this.hasFired = true;
+ is(evt.type, expectedEvent, this.getMessage());
+ TestCounter.testComplete();
+ }
+};
+
+var SyncRequestSettingTimeoutAfterOpen = {
+ startXHR: function() {
+ var pass = false;
+ var req = new XMLHttpRequest();
+ req.open("GET", STALLED_REQUEST_URL, false);
+ try {
+ req.timeout = TIME_SYNC_TIMEOUT;
+ }
+ catch (e) {
+ pass = true;
+ }
+ ok(pass, "Synchronous XHR must not allow a timeout to be set - setting timeout must throw");
+ TestCounter.testComplete();
+ }
+};
+
+var SyncRequestSettingTimeoutBeforeOpen = {
+ startXHR: function() {
+ var pass = false;
+ var req = new XMLHttpRequest();
+ req.timeout = TIME_SYNC_TIMEOUT;
+ try {
+ req.open("GET", STALLED_REQUEST_URL, false);
+ }
+ catch (e) {
+ pass = true;
+ }
+ ok(pass, "Synchronous XHR must not allow a timeout to be set - calling open() after timeout is set must throw");
+ TestCounter.testComplete();
+ }
+};
+
+var TestRequests = [];
+
+// This code controls moving from one test to another.
+var TestCounter = {
+ testComplete: function() {
+ // Allow for the possibility there are other events coming.
+ self.setTimeout(function() {
+ TestCounter.next();
+ }, TIME_NORMAL_LOAD);
+ },
+
+ next: function() {
+ var test = TestRequests.shift();
+
+ if (test) {
+ test.startXHR();
+ }
+ else {
+ message("done");
+ }
+ }
+};
+
+function runTestRequests(testRequests) {
+ TestRequests = testRequests;
+ TestCounter.next();
+}
diff --git a/testing/web-platform/tests/XMLHttpRequest/resources/zlib.py b/testing/web-platform/tests/XMLHttpRequest/resources/zlib.py
new file mode 100644
index 000000000..49ed69de7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/zlib.py
@@ -0,0 +1,19 @@
+import zlib
+
+def main(request, response):
+ if "content" in request.GET:
+ output = request.GET["content"]
+ else:
+ output = request.body
+
+ output = zlib.compress(output, 9)
+
+ headers = [("Content-type", "text/plain"),
+ ("Content-Encoding", "deflate"),
+ ("X-Request-Method", request.method),
+ ("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"),
+ ("X-Request-Content-Length", request.headers.get("Content-Length", "NO")),
+ ("X-Request-Content-Type", request.headers.get("Content-Type", "NO")),
+ ("Content-Length", len(output))]
+
+ return headers, output
diff --git a/testing/web-platform/tests/XMLHttpRequest/response-data-arraybuffer.htm b/testing/web-platform/tests/XMLHttpRequest/response-data-arraybuffer.htm
new file mode 100644
index 000000000..7eaf7198a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/response-data-arraybuffer.htm
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetype-attribute" data-tested-assertations="following::ol[1]/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::a[contains(@href,'#arraybuffer-response-entity-body')]/.." />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The response attribute: ArrayBuffer data</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.onreadystatechange = function()
+ {
+ if (xhr.readyState == 4)
+ {
+ test.step(function()
+ {
+ assert_equals(xhr.status, 200);
+
+ var buf = xhr.response;
+ assert_true(buf instanceof ArrayBuffer);
+
+ var arr = new Uint8Array(buf);
+ assert_equals(arr.length, 5);
+ assert_equals(arr[0], 0x48, "Expect 'H'");
+ assert_equals(arr[1], 0x65, "Expect 'e'");
+ assert_equals(arr[2], 0x6c, "Expect 'l'");
+ assert_equals(arr[3], 0x6c, "Expect 'l'");
+ assert_equals(arr[4], 0x6f, "Expect 'o'");
+
+ assert_equals(xhr.response, xhr.response,
+ "Response should be cached");
+
+ test.done();
+ });
+ }
+ };
+
+ xhr.open("GET", "./resources/content.py?content=Hello", true);
+ xhr.responseType = "arraybuffer";
+ xhr.send();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/response-data-blob.htm b/testing/web-platform/tests/XMLHttpRequest/response-data-blob.htm
new file mode 100644
index 000000000..19731d3dc
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/response-data-blob.htm
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetype-attribute" data-tested-assertations="following::ol[1]/li[4]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::a[contains(@href,'#blob-response-entity-body')]/.." />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The response attribute: Blob data</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ var content = "Hello";
+ var blob;
+
+ xhr.onreadystatechange = function()
+ {
+ if (xhr.readyState == 4)
+ {
+ test.step(function()
+ {
+ blob = xhr.response;
+ assert_equals(xhr.response, xhr.response,
+ "Response should be cached");
+ assert_true(blob instanceof Blob, 'blob is a Blob');
+
+ var reader = new FileReader();
+ reader.onload = function()
+ {
+ test.step(function()
+ {
+ assert_equals(reader.result, content);
+ test.done();
+ });
+ };
+ reader.readAsText(blob);
+ });
+ }
+ }
+
+ xhr.open("GET", "./resources/content.py?content=" + content, true);
+ xhr.responseType = "blob";
+ xhr.send();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/response-data-deflate.htm b/testing/web-platform/tests/XMLHttpRequest/response-data-deflate.htm
new file mode 100644
index 000000000..bce2745f4
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/response-data-deflate.htm
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: content-encoding:deflate response was correctly inflated</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#the-send()-method" data-tested-assertations="following::p[contains(text(),'content-encodings')]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(input) {
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest()
+
+ client.open("POST", "resources/zlib.py", false);
+
+ client.onreadystatechange = test.step_func(function () {
+ if (client.readyState === 4) {
+ var len = parseInt(client.getResponseHeader('content-length'), 10);
+
+ assert_equals(client.getResponseHeader('content-encoding'), 'deflate');
+ assert_true(len < input.length);
+ assert_equals(client.responseText, input);
+ test.done();
+ }
+ });
+
+ client.send(input);
+ });
+ }
+
+ var wellCompressableData = '';
+ for (var i = 0; i < 500; i++) {
+ wellCompressableData += 'foofoofoofoofoofoofoo';
+ }
+
+ request(wellCompressableData);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/response-data-gzip.htm b/testing/web-platform/tests/XMLHttpRequest/response-data-gzip.htm
new file mode 100644
index 000000000..a3d2713d0
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/response-data-gzip.htm
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: GZIP response was correctly inflated</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#the-send()-method" data-tested-assertations="following::p[contains(text(),'content-encodings')]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(input) {
+ var test = async_test();
+ test.step(function() {
+ var client = new XMLHttpRequest()
+
+ client.open("POST", "resources/gzip.py", false);
+
+ client.onreadystatechange = test.step_func(function () {
+ if (client.readyState === 4) {
+ var len = parseInt(client.getResponseHeader('content-length'), 10);
+
+ assert_equals(client.getResponseHeader('content-encoding'), 'gzip');
+ assert_true(len < input.length);
+ assert_equals(client.responseText, input);
+ test.done();
+ }
+ });
+
+ client.send(input);
+ }, document.title);
+ }
+
+ var wellCompressableData = '';
+ for (var i = 0; i < 500; i++) {
+ wellCompressableData += 'foofoofoofoofoofoofoo';
+ }
+
+ request(wellCompressableData);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/response-data-progress.htm b/testing/web-platform/tests/XMLHttpRequest/response-data-progress.htm
new file mode 100644
index 000000000..94c662c5c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/response-data-progress.htm
@@ -0,0 +1,51 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>XMLHttpRequest: progress events grow response body size</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::a[contains(@href,'#make-progress-notifications')]/.. following::a[contains(@href,'#make-progress-notifications')]/../following:p[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#make-progress-notifications" data-tested-assertations=".." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onprogress" data-tested-assertations="/../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-progress" data-tested-assertations="/../.." />
+</head>
+
+<div id="log"></div>
+
+<script>
+
+function doTest(test, expectedLengthComputable, expectedTotal, url) {
+ var client = new XMLHttpRequest();
+ var lastSize = 0;
+
+ client.onprogress = test.step_func(function(e) {
+ assert_equals(e.total, expectedTotal);
+ assert_equals(e.lengthComputable, expectedLengthComputable);
+
+ var currentSize = client.responseText.length;
+
+ if (lastSize > 0 && currentSize > lastSize) {
+ // growth from a positive size to bigger!
+ test.done();
+ }
+
+ lastSize = currentSize;
+ });
+
+ client.onreadystatechange = test.step_func(function() {
+ if (client.readyState === 4) {
+ assert_unreached("onprogress not called multiple times, or response body did not grow.");
+ }
+ });
+
+ client.open("GET", url);
+ client.send(null);
+ return client;
+}
+
+async_test(function () { doTest(this, false, 0, "resources/trickle.py?count=6&delay=150"); },
+ document.title + ', unknown content-length');
+async_test(function () { doTest(this, true, 78, "resources/trickle.py?count=6&delay=150&specifylength=1"); },
+ document.title + ', known content-length');
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/response-invalid-responsetype.htm b/testing/web-platform/tests/XMLHttpRequest/response-invalid-responsetype.htm
new file mode 100644
index 000000000..603c4cd0e
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/response-invalid-responsetype.htm
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: response is plain text if responseType is set to an invalid string</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::dd[2]/ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetype-attribute" data-tested-assertations="following::ol[1]/li[4]" /><!-- Not quite - but this is handled in WebIDL, not the XHR spec -->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(type) {
+ var test = async_test(document.title+' ('+type+')')
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.responseType = type
+ assert_equals(client.responseType, '')
+ client.open("GET", "resources/folder.txt", true)
+ client.onload = function(){
+ test.step(function(){
+ assert_equals(client.responseType, '')
+ assert_equals(client.response, 'bottom\n')
+ assert_equals(typeof client.response, 'string')
+ test.done()
+ })
+ }
+ client.send(null)
+ })
+ }
+ request("arrayBuffer") // case sensitive
+ request("JSON") // case sensitive
+ request("glob")
+ request("txt")
+ request("text/html")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/response-json.htm b/testing/web-platform/tests/XMLHttpRequest/response-json.htm
new file mode 100644
index 000000000..a694d7fc6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/response-json.htm
@@ -0,0 +1,61 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: responseType json</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetype-attribute" data-tested-assertations="following::OL[1]/LI[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::dt[2]/dt[4] following::dt[2]/dt[4]/following::dd[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#json-response-entity-body" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2] following::ol[1]/li[3]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function setupXHR () {
+ var client = new XMLHttpRequest()
+ client.open('POST', "resources/content.py", true)
+ client.responseType = 'json'
+ return client
+ }
+ function makeTest(data, expectedResponse, description){
+ var test = async_test(description)
+ var xhr = setupXHR()
+ assert_equals(xhr.responseType, 'json')
+ xhr.onreadystatechange = function(){
+ if(xhr.readyState === 4){
+ test.step(function(){
+ assert_equals(xhr.status, 200)
+ assert_equals(xhr.responseType, 'json')
+ assert_equals(typeof xhr.response, 'object')
+ if(expectedResponse){ // if the expectedResponse is not null, we iterate over properties to do a deeper comparison..
+ for(var prop in expectedResponse){
+ if (expectedResponse[prop] instanceof Array) {
+ assert_array_equals(expectedResponse[prop], xhr.response[prop])
+ }else{
+ assert_equals(expectedResponse[prop], xhr.response[prop])
+ }
+ }
+ }else{
+ assert_equals(xhr.response, expectedResponse) // null comparison, basically
+ }
+ assert_equals(xhr.response, xhr.response,
+ "Response should be cached")
+ test.done()
+ })
+ }
+ }
+ xhr.send(data)
+ }
+ // no data
+ makeTest("", null, 'json response with no data: response property is null')
+ // malformed
+ makeTest('{"test":"foo"', null, 'json response with malformed data: response property is null')
+ // real object
+ var obj = {alpha:'a-z', integer:15003, negated:-20, b1:true, b2:false, myAr:['a', 'b', 'c', 1, 2, 3]}
+ makeTest(JSON.stringify(obj), obj, 'JSON object roundtrip')
+ makeTest('{"日本語":"にほんご"}', {"日本語":"にほんご"}, 'JSON roundtrip with Japanese text')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/response-method.htm b/testing/web-platform/tests/XMLHttpRequest/response-method.htm
new file mode 100644
index 000000000..1bf26bac7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/response-method.htm
@@ -0,0 +1,21 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: influence of HTTP method on response</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ ["GET", "HEAD", "POST"].forEach(function(method) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open(method, "resources/echo-method.py", false)
+ client.send()
+ assert_equals(client.responseText, (method === "HEAD" ? "" : method))
+ }, method)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responseText-status.html b/testing/web-platform/tests/XMLHttpRequest/responseText-status.html
new file mode 100644
index 000000000..7d575902d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responseText-status.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>XMLHttpRequest Test: responseText - status</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="Check if XMLHttpRequest.responseText return empty string if state is not LOADING or DONE">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<script>
+
+async_test(function (t) {
+ var client = new XMLHttpRequest();
+ t.step(function () {
+ assert_equals(client.responseText, "");
+ });
+
+ client.onreadystatechange = t.step_func(function () {
+ if (client.readyState == 1 || client.readyState == 2) {
+ assert_equals(client.responseText, "");
+ }
+
+ if (client.readyState == 3) {
+ t.done();
+ }
+ });
+
+ client.open("GET", "resources/headers.py")
+ client.send(null)
+}, document.title);
+
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responsetext-decoding.htm b/testing/web-platform/tests/XMLHttpRequest/responsetext-decoding.htm
new file mode 100644
index 000000000..7f179e6f3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responsetext-decoding.htm
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: responseText decoding</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol[1]/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#text-response-entity-body" data-tested-assertations="following::ol[1]/li[2] following::ol[1]/li[3] following::ol[1]/li[4] following::ol[1]/li[5]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(type, input, output, responseType) {
+ var test = async_test(document.title + " (" + type + " " + input + ")");
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ if (responseType !== undefined) {
+ client.responseType = responseType
+ }
+ client.open("GET", "resources/status.py?content=" + input + "&type=" + encodeURIComponent(type), true)
+ client.onload = function(){
+ test.step(function(){
+ assert_equals(client.responseText, output)
+ test.done()
+ })
+ }
+ client.send(null)
+ })
+ }
+ request("application/xml", encodeURIComponent("<?xml version='1.0' encoding='windows-1252'?><x>")+'%FF'+encodeURIComponent("<\/x>"), "<?xml version='1.0' encoding='windows-1252'?><x>\u00FF<\/x>")
+ request("text/html", encodeURIComponent("<!doctype html><meta charset=windows-1252>")+"%FF", "<!doctype html><meta charset=windows-1252>\u00FF")
+ request("text/plain;charset=windows-1252", "%FF", "\u00FF")
+ request("text/plain", "%FF", "\uFFFD")
+ request("text/plain", "%FE%FF", "")
+ request("text/plain", "%FE%FF%FE%FF", "\uFEFF")
+ request("text/plain", "%EF%BB%BF", "")
+ request("text/plain", "%EF%BB%BF%EF%BB%BF", "\uFEFF")
+ request("text/plain", "%C2", "\uFFFD")
+
+ // XXX might need fixing
+ request("text/xml", "%FE%FF", "")
+ request("text/xml", "%FE%FF%FE%FF", "\uFEFF")
+ request("text/xml", "%EF%BB%BF", "")
+ request("text/xml", "%EF%BB%BF%EF%BB%BF", "\uFEFF")
+ request("text/plain", "%E3%81%B2", "\u3072", 'text')
+ // the point of the following test: setting responseType=text should (per spec #text-response-entity-body point 3)
+ // skip some of the charset detection even for XML resources. The test uses a wilfully mislabelled XMLish response
+ // and the pass condition is that the responseType = text makes the decoder fall back to UTF-8
+ request("text/xml", encodeURIComponent("<?xml version='1.0' encoding='windows-1252'?><x>")+"%E3%81%B2"+encodeURIComponent("<\/x>"), "<?xml version='1.0' encoding='windows-1252'?><x>\u3072<\/x>", 'text')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responsetype.html b/testing/web-platform/tests/XMLHttpRequest/responsetype.html
new file mode 100644
index 000000000..ade604417
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responsetype.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>XMLHttpRequest.responseType</title>
+<link rel="author" title="Mathias Bynens" href="http://mathiasbynens.be/">
+<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
+<link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetype-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var xhr = new XMLHttpRequest();
+ assert_equals(xhr.responseType, '');
+}, 'Initial value of responseType');
+
+var types = ['', 'json', 'document', 'arraybuffer', 'blob', 'text'];
+types.forEach(function(type) {
+ test(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.responseType = type;
+ assert_equals(xhr.responseType, type);
+ }, 'Set responseType to ' + format_value(type) + ' when readyState is UNSENT.');
+
+ test(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('get', '/');
+ xhr.responseType = type;
+ assert_equals(xhr.responseType, type);
+ }, 'Set responseType to ' + format_value(type) + ' when readyState is OPENED.');
+
+ async_test(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('get', '/');
+ xhr.onreadystatechange = this.step_func(function() {
+ if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
+ xhr.responseType = type;
+ assert_equals(xhr.responseType, type);
+ this.done();
+ }
+ });
+ xhr.send();
+ }, 'Set responseType to ' + format_value(type) + ' when readyState is HEADERS_RECEIVED.');
+
+ async_test(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('get', '/');
+ xhr.onreadystatechange = this.step_func(function() {
+ if (xhr.readyState === XMLHttpRequest.LOADING) {
+ assert_throws("InvalidStateError", function() {
+ xhr.responseType = type;
+ });
+ assert_equals(xhr.responseType, "");
+ this.done();
+ }
+ });
+ xhr.send();
+ }, 'Set responseType to ' + format_value(type) + ' when readyState is LOADING.');
+
+ async_test(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('get', '/');
+ xhr.onreadystatechange = this.step_func(function() {
+ if (xhr.readyState === XMLHttpRequest.DONE) {
+ assert_throws("InvalidStateError", function() {
+ xhr.responseType = type;
+ });
+ assert_equals(xhr.responseType, "");
+ this.done();
+ }
+ });
+ xhr.send();
+ }, 'Set responseType to ' + format_value(type) + ' when readyState is DONE.');
+
+ // Note: the case of setting responseType first, and then calling synchronous
+ // open(), is tested in open-method-responsetype-set-sync.htm.
+ test(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('get', '/', false);
+ assert_throws("InvalidAccessError", function() {
+ xhr.responseType = type;
+ });
+ assert_equals(xhr.responseType, "");
+ }, 'Set responseType to ' + format_value(type) + ' when readyState is OPENED and the sync flag is set.');
+
+ test(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('get', '/', false);
+ xhr.send();
+ assert_equals(xhr.readyState, XMLHttpRequest.DONE);
+ assert_throws("InvalidStateError", function() {
+ xhr.responseType = type;
+ });
+ assert_equals(xhr.responseType, "");
+ }, 'Set responseType to ' + format_value(type) + ' when readyState is DONE and the sync flag is set.');
+});
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responseurl.html b/testing/web-platform/tests/XMLHttpRequest/responseurl.html
new file mode 100644
index 000000000..b730e045d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responseurl.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: responseURL test</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responseurl-attribute"/>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ assert_equals(client.responseURL, "")
+
+ client.open("GET", "foo.html", false)
+ client.send()
+
+ expected = location.href.replace(/[^/]*$/, 'foo.html')
+ assert_equals(client.status, 404)
+ assert_equals(client.responseURL, expected)
+ }, "404 response has proper responseURL")
+ test(function() {
+ var client = new XMLHttpRequest()
+ assert_equals(client.responseURL, "")
+
+ target = "image.gif"
+ client.open("GET", "resources/redirect.py?location=" + target, false)
+ client.send()
+
+ expected = location.href.replace(/[^/]*$/, "resources/" + target)
+ assert_equals(client.status, 200)
+ assert_equals(client.responseURL, expected)
+ }, "Redirected response has proper responseURL")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responsexml-basic.htm b/testing/web-platform/tests/XMLHttpRequest/responsexml-basic.htm
new file mode 100644
index 000000000..a3ce7b5b5
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responsexml-basic.htm
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: responseXML basic test</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol[1]/li[2] following::ol[1]/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#document-response-entity-body" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[6] following::ol[1]/li[10]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ assert_equals(client.responseXML, null)
+ client.open("GET", "resources/well-formed.xml", false)
+ assert_equals(client.responseXML, null)
+ client.send(null)
+ assert_equals(client.responseXML.documentElement.localName, "html", 'localName is html')
+ assert_equals(client.responseXML.documentElement.childNodes.length, 5, 'childNodes is 5')
+ assert_equals(client.responseXML.getElementById("n1").localName, client.responseXML.documentElement.childNodes[1].localName)
+ assert_equals(client.responseXML.getElementById("n2"), client.responseXML.documentElement.childNodes[3], 'getElementById("n2")')
+ assert_equals(client.responseXML.getElementsByTagName("p")[1].namespaceURI, "namespacesarejuststrings", 'namespaceURI')
+ })
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/status.py?type=application/xml", false)
+ client.send(null)
+ assert_equals(client.responseXML, null)
+ }, 'responseXML on empty response documents')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responsexml-document-properties.htm b/testing/web-platform/tests/XMLHttpRequest/responsexml-document-properties.htm
new file mode 100644
index 000000000..18e3fb2f2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responsexml-document-properties.htm
@@ -0,0 +1,74 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: responseXML document properties</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol[1]/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#document-response-entity-body" data-tested-assertations="following::ol[1]/li[6] following::ol[1]/li[7] following::ol[1]/li[8] following::ol[1]/li[10]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var timePreXHR = Math.floor(new Date().getTime(new Date().getTime() - 3000) / 1000); // three seconds ago, in case there's clock drift
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/well-formed.xml", false)
+ client.send(null)
+ var expected = {
+ domain:undefined,
+ URL:location.href.replace(/[^/]*$/, 'resources/well-formed.xml'),
+ documentURI:location.href.replace(/[^/]*$/, 'resources/well-formed.xml'),
+ referrer:'',
+ title:'',
+ contentType:'application/xml',
+ readyState:'complete',
+ location:null,
+ defaultView:null,
+ body:undefined,
+ images: undefined,
+ doctype:null,
+ forms:undefined,
+ all:undefined,
+ links: undefined,
+ cookie:''
+ }
+
+ for (var name in expected) {
+ runTest(name, expected[name])
+ }
+
+ function runTest(name, value){
+ test(function(){
+ assert_equals(client.responseXML[name], value)
+ }, name)
+ }
+
+ test(function() {
+ var lastModified = Math.floor(new Date(client.responseXML.lastModified).getTime() / 1000);
+ var now = Math.floor(new Date().getTime(new Date().getTime() + 3000) / 1000); // three seconds from now, in case there's clock drift
+ assert_greater_than_equal(lastModified, timePreXHR);
+ assert_less_than_equal(lastModified, now);
+ }, 'lastModified set to time of response if no HTTP header provided')
+
+ test(function() {
+ var client2 = new XMLHttpRequest()
+ client2.open("GET", "resources/last-modified.py", false)
+ client2.send(null)
+ assert_equals((new Date(client2.getResponseHeader('Last-Modified'))).getTime(), (new Date(client2.responseXML.lastModified)).getTime())
+ }, 'lastModified set to related HTTP header if provided')
+
+ test(function() {
+ client.responseXML.cookie = "thisshouldbeignored"
+ assert_equals(client.responseXML.cookie, "")
+ }, 'cookie (after setting it)')
+
+ test(function() {
+ assert_equals(typeof(client.responseXML.styleSheets), "object")
+ }, 'styleSheets')
+
+ test(function() {
+ assert_equals(typeof(client.responseXML.implementation), "object")
+ }, 'implementation')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responsexml-get-twice.htm b/testing/web-platform/tests/XMLHttpRequest/responsexml-get-twice.htm
new file mode 100644
index 000000000..e86a6d59e
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responsexml-get-twice.htm
@@ -0,0 +1,66 @@
+<!doctype html>
+<meta charset="utf-8">
+<title></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ async_test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/well-formed.xml")
+ client.responseType = "document"
+ assert_equals(client.responseType, "document")
+ client.send()
+ client.onload = this.step_func_done(function() {
+ var first = client.response
+ var second = client.response
+ assert_not_equals(first, null)
+ assert_not_equals(second, null)
+ assert_equals(first, second)
+ })
+ }, "Getting response, then response")
+
+ async_test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/well-formed.xml")
+ client.responseType = "document"
+ assert_equals(client.responseType, "document")
+ client.send()
+ client.onload = this.step_func_done(function() {
+ var first = client.responseXML
+ var second = client.responseXML
+ assert_not_equals(first, null)
+ assert_not_equals(second, null)
+ assert_equals(first, second)
+ })
+ }, "Getting responseXML, then responseXML")
+
+ async_test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/well-formed.xml")
+ client.responseType = "document"
+ assert_equals(client.responseType, "document")
+ client.send()
+ client.onload = this.step_func_done(function() {
+ var first = client.responseXML
+ var second = client.response
+ assert_not_equals(first, null)
+ assert_not_equals(second, null)
+ assert_equals(first, second)
+ })
+ }, "Getting responseXML, then response")
+
+ async_test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/well-formed.xml")
+ client.responseType = "document"
+ assert_equals(client.responseType, "document")
+ client.send()
+ client.onload = this.step_func_done(function() {
+ var first = client.response
+ var second = client.responseXML
+ assert_not_equals(first, null)
+ assert_not_equals(second, null)
+ assert_equals(first, second)
+ })
+ }, "Getting response, then responseXML")
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responsexml-media-type.htm b/testing/web-platform/tests/XMLHttpRequest/responsexml-media-type.htm
new file mode 100644
index 000000000..ece413d51
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responsexml-media-type.htm
@@ -0,0 +1,41 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: responseXML MIME type tests</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol[1]/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#document-response-entity-body" data-tested-assertations="following::ol[1]/li[3] following::ol[1]/li[4] following::ol[1]/li[6] following::ol[1]/li[10]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(type, succeed) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/status.py?content=<x><\/x>&type=" + encodeURIComponent(type), false)
+ client.send(null)
+ if(!succeed)
+ assert_equals(client.responseXML, null)
+ else
+ assert_equals(client.responseXML.documentElement.localName, "x")
+ }, document.title + " ('" + type + "', should "+(succeed?'':'not')+" parse)")
+ }
+ request("", true)
+ request("text/html", false)
+ request("bogus", true)
+ request("bogus+xml", true)
+ request("text/plain;+xml", false)
+ request("text/plainxml", false)
+ request("video/x-awesome+xml", true)
+ request("video/x-awesome", false)
+ request("text/xml", true)
+ request("application", true)
+ request("text/xsl", false)
+ request("text/plain", false)
+ request("application/rdf", false)
+ request("application/xhtml+xml", true)
+ request("image/svg+xml", true)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responsexml-non-document-types.htm b/testing/web-platform/tests/XMLHttpRequest/responsexml-non-document-types.htm
new file mode 100644
index 000000000..84d90a8d3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responsexml-non-document-types.htm
@@ -0,0 +1,45 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: responseXML/responseText on other responseType</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol[1]/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol[1]/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetype-attribute" data-tested-assertations="following::ol[1]/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(type) {
+ var test = async_test(document.title+' ('+type+')')
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.responseType = type
+ client.open("GET", "resources/well-formed.xml", true)
+ client.onload = function(){
+ test.step(function(){
+ if(type !== 'document'){
+ assert_throws("InvalidStateError", function() {
+ var x = client.responseXML;
+ }, 'responseXML throw for '+type)
+ }
+ if(type !== 'text'){
+ assert_throws("InvalidStateError", function() {
+ var x = client.responseText;
+ }, 'responseText throws for '+type)
+ }
+ test.done()
+ })
+ }
+ client.send(null)
+ })
+ }
+ request("arraybuffer")
+ request("blob")
+ request("json")
+ request("text")
+ request("document")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/responsexml-non-well-formed.htm b/testing/web-platform/tests/XMLHttpRequest/responsexml-non-well-formed.htm
new file mode 100644
index 000000000..216da8170
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/responsexml-non-well-formed.htm
@@ -0,0 +1,30 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: responseXML non well-formed tests</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol[1]/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#document-response-entity-body" data-tested-assertations="following::ol[1]/li[6] following::ol[1]/li[10]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(content) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/status.py?type=text/xml&content=" + encodeURIComponent(content), false)
+ client.send(null)
+ assert_equals(client.responseXML, null)
+ })
+ }
+ request("<x")
+ request("<x></x")
+ request("<x>&amp</x>")
+ request("<x><y></x></y>") // misnested tags
+ request("<x></x><y></y>") // two root elements is not allowed
+ request("<x> <![CDATA[ foobar ]></x>") // CDATA should end with ]]>
+ request("<x> <!CDATA[ foobar ]]></x>") // CDATA should start with <![
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/security-consideration.sub.html b/testing/web-platform/tests/XMLHttpRequest/security-consideration.sub.html
new file mode 100644
index 000000000..5eb7110d4
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/security-consideration.sub.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>ProgressEvent: security consideration</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#security-considerations" data-tested-assertations="/following-sibling::p" />
+ <link rel="help" href="https://fetch.spec.whatwg.org/#http-fetch" data-tested-assertations="/following-sibling::ol[1]/li[3]/ol[1]/li[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ async_test(function() {
+ var xhr = new XMLHttpRequest();
+
+ xhr.onprogress = this.unreached_func("MUST NOT dispatch progress event.");
+ xhr.onload = this.unreached_func("MUST NOT dispatch load event.");
+ xhr.onerror = this.step_func(function(pe) {
+ assert_equals(pe.type, "error");
+ assert_equals(pe.loaded, 0, "loaded is zero.");
+ assert_false(pe.lengthComputable, "lengthComputable is false.");
+ assert_equals(pe.total, 0, "total is zero.");
+ });
+ xhr.onloadend = this.step_func(function(pe) {
+ assert_equals(pe.type, "loadend");
+ assert_equals(pe.loaded, 0, "loaded is zero.");
+ assert_false(pe.lengthComputable, "lengthComputable is false.");
+ assert_equals(pe.total, 0, "total is zero.");
+ this.done();
+ });
+ xhr.open("GET", "http://{{host}}:{{ports[http][1]}}/XMLHttpRequest/resources/img.jpg", true);
+ xhr.send(null);
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-accept-language.htm b/testing/web-platform/tests/XMLHttpRequest/send-accept-language.htm
new file mode 100644
index 000000000..c798cd548
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-accept-language.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Accept-Language</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(text(),'Accept-Language')]/.. following::code[contains(text(),'Accept-Language')]/../following::ul[1]/li[1] following::code[contains(text(),'Accept-Language')]/../following::ul[1]/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open('GET', 'resources/inspect-headers.py?filter_name=accept-language', false)
+ client.send(null)
+ assert_regexp_match(client.responseText, /accept-language:\s.+/)
+ }, 'Send "sensible" default value, whatever that means')
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/inspect-headers.py?filter_name=accept-language", false)
+ client.setRequestHeader("Accept-Language", "x-GameSpeak")
+ client.send(null)
+ assert_equals(client.responseText, "accept-language: x-GameSpeak\n")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-accept.htm b/testing/web-platform/tests/XMLHttpRequest/send-accept.htm
new file mode 100644
index 000000000..2731eb6be
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-accept.htm
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Accept</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(text(),'*/*')]/.. following::code[contains(text(),'Accept')]/.. following::code[contains(text(),'Accept')]/../following::ul[1]/li[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/accept.py", false)
+ client.send(null)
+ assert_equals(client.responseText, "*/*")
+ client.open("GET", "resources/accept.py", false)
+ client.setRequestHeader("Accept", "x-something/vague, text/html5")
+ client.send(null)
+ assert_equals(client.responseText, "x-something/vague, text/html5")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-after-setting-document-domain.htm b/testing/web-platform/tests/XMLHttpRequest/send-after-setting-document-domain.htm
new file mode 100644
index 000000000..30b6c713c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-after-setting-document-domain.htm
@@ -0,0 +1,39 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() with document.domain set</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[2]/ol[1]/li[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test_base_url = location.protocol+'//www2.'+location.host+"/XMLHttpRequest/resources/",
+ test_windows = [
+ window.open(test_base_url + "send-after-setting-document-domain-window-1.htm"),
+ window.open(test_base_url + "send-after-setting-document-domain-window-2.htm"),
+ ],
+ num_tests_left = test_windows.length;
+
+ async_test(function(wrapper_test) {
+ window.addEventListener("message", function(evt) {
+ // run a shadow test that just forwards the results
+ async_test(function(test) {
+ assert_true(evt.data.passed, evt.data.message);
+ test.done();
+ }, evt.data.name);
+
+ // after last result comes in, close all test
+ // windows and complete the wrapper test.
+ if (--num_tests_left == 0) {
+ for (var i=0; i<test_windows.length; ++i) {
+ test_windows[i].close();
+ }
+ wrapper_test.done();
+ }
+ }, false);
+ }, "All tests ran");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-cors-not-enabled.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-cors-not-enabled.htm
new file mode 100644
index 000000000..070b2ba32
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-cors-not-enabled.htm
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated CORS requests with user name and password passed to open() (asserts failure)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[9]/ol[1]/li[1] following::ol[1]/li[9]/ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = 'www1.'+location.host + location.pathname.replace(/\/[^\/]*$/, '/')
+ client.withCredentials = true
+ user = token()
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth1/auth.py", false, user, 'pass')
+ client.setRequestHeader("x-user", user)
+ assert_throws("NetworkError", function(){ client.send(null) })
+ assert_equals(client.responseText, '')
+ assert_equals(client.status, 0)
+ assert_equals(client.getResponseHeader('x-challenge'), null)
+ }, document.title)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-cors.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-cors.htm
new file mode 100644
index 000000000..fcacdd5fe
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-cors.htm
@@ -0,0 +1,35 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated CORS requests with user name and password passed to open() (asserts failure)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[9]/ol[1]/li[1] following::ol[1]/li[9]/ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = 'www1.'+location.host + location.pathname.replace(/\/[^\/]*$/, '/')
+ client.withCredentials = true
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth1/corsenabled.py", true, 'user', 'pass')
+ client.setRequestHeader("x-user", 'user')
+ client.setRequestHeader("x-pass", 'pass')
+ client.onreadystatechange = function(){
+ if (client.readyState === 4) {
+ test.step(function(){
+ assert_equals(client.responseText, '')
+ assert_equals(client.status, 0)
+ assert_equals(client.getResponseHeader('x-challenge'), null)
+ test.done()
+ })
+ }
+ }
+ client.send(null)
+ }, document.title)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-repeat-no-args.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-repeat-no-args.htm
new file mode 100644
index 000000000..464d69cf7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-repeat-no-args.htm
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated requests with user name and password passed to open() in first request, without in second</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[9]/ol[1]/li[1] following::ol[1]/li[9]/ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
+ user = token()
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth1/auth.py", false, user, 'pass')
+ client.setRequestHeader("x-user", user)
+ client.send(null)
+ // Repeat request but *without* credentials in the open() call.
+ // Is the UA supposed to cache credentials from above request and use them? Yes.
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth1/auth.py", false)
+ client.setRequestHeader("x-user", user)
+ client.send(null)
+
+ assert_equals(client.responseText, user + "\n" + 'pass')
+ //assert_equals(client.getResponseHeader('x-challenge'), 'DID-NOT')
+
+ }, document.title)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader-and-arguments.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader-and-arguments.htm
new file mode 100644
index 000000000..9915e8821
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader-and-arguments.htm
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated request using setRequestHeader() and open() arguments (asserts header wins)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <!-- These spec references do not make much sense simply because the spec doesn't say very much about this.. -->
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="following::ol[1]/li[6]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
+ user = token()
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth9/auth.py", false, 'open-' + user, 'open-pass')
+ client.setRequestHeader("x-user", user)
+ client.setRequestHeader('Authorization', 'Basic ' + btoa(user + ":pass"))
+ client.onreadystatechange = function () {
+ if (client.readyState < 4) {return}
+ test.step( function () {
+ assert_equals(client.responseText, user + '\npass')
+ assert_equals(client.status, 200)
+ assert_equals(client.getResponseHeader('x-challenge'), 'DID-NOT')
+ test.done()
+ })
+ }
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader-existing-session.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader-existing-session.htm
new file mode 100644
index 000000000..6e68f098c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader-existing-session.htm
@@ -0,0 +1,53 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated request using setRequestHeader() when there is an existing session</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <!-- These spec references do not make much sense simply because the spec doesn't say very much about this.. -->
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="following::ol[1]/li[6]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/')
+ // Initial request: no information is known to the UA about whether resources/auth4/auth.py requires authentication,
+ // hence it first sends a normal request, gets a 401 response that will not be passed on to the JS, and sends a new
+ // request with an Authorization header before returning
+ // (Note: this test will only work as expected if run once per browsing session)
+ var open_user = token()
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth4/auth.py", false, open_user, 'open-pass')
+ client.setRequestHeader('X-User', open_user)
+ // initial request - this will get a 401 response and re-try with HTTP auth
+ client.send(null)
+ assert_true(client.responseText == (open_user + '\nopen-pass'), 'responseText should contain the right user and password')
+ assert_equals(client.status, 200)
+ assert_equals(client.getResponseHeader('x-challenge'), 'DID')
+ // Another request, this time user,pass is omitted and an Authorization header set explicitly
+ // Here the URL is known to require authentication (from the request above), and the UA has cached open-user:open-pass credentials
+ // However, these session credentials should now be overridden by the setRequestHeader() call so the UA should immediately
+ // send basic Authorization header with credentials user:pass. (This part is perhaps not well specified anywhere)
+ var user = token();
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth4/auth.py", true)
+ client.setRequestHeader("x-user", user)
+ client.setRequestHeader('Authorization', 'Basic ' + btoa(user + ":pass"))
+ client.onreadystatechange = function () {
+ if (client.readyState < 4) {return}
+ test.step( function () {
+ assert_equals(client.responseText, user + '\npass')
+ assert_equals(client.status, 200)
+ assert_equals(client.getResponseHeader('x-challenge'), 'DID-NOT')
+ test.done()
+ } )
+ }
+ client.send(null)
+ })
+ </script>
+ <p>Note: this test will only work as expected once per browsing session. Restart browser to re-test.</p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader.htm
new file mode 100644
index 000000000..84d0dd6b2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic-setrequestheader.htm
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated request using setRequestHeader()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <!-- These spec references do not make much sense simply because the spec doesn't say very much about this.. -->
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="following::ol[1]/li[6]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
+ user = token()
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth2/auth.py", false)
+ client.setRequestHeader("x-user", user)
+ client.setRequestHeader('Authorization', 'Basic ' + btoa(user + ":pass"))
+ client.onreadystatechange = function () {
+ if (client.readyState < 4) {return}
+ test.step( function () {
+ assert_equals(client.responseText, user + '\npass')
+ assert_equals(client.status, 200)
+ assert_equals(client.getResponseHeader('x-challenge'), 'DID-NOT')
+ test.done()
+ } )
+ }
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic.htm
new file mode 100644
index 000000000..ae3ee5711
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-basic.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated requests with user name and password passed to open()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[9]/ol[1]/li[1] following::ol[1]/li[9]/ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
+ user = token();
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth1/auth.py", false, user, 'pass')
+ client.setRequestHeader("x-user", user)
+ client.send(null)
+ assert_equals(client.responseText, user + "\n" + 'pass')
+ assert_equals(client.getResponseHeader('x-challenge'), 'DID')
+ }, document.title)
+ </script>
+ <p>Note: this test will only work as expected once per browsing session. Restart browser to re-test.</p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-competing-names-passwords.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-competing-names-passwords.htm
new file mode 100644
index 000000000..ba7ea7e35
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-competing-names-passwords.htm
@@ -0,0 +1,54 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated requests with competing user name/password options</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[9]/ol[1]/li[1] following::ol[1]/li[9]/ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." /> </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(user1, pass1, user2, pass2, name) {
+ // user1, pass1 will if given become userinfo part of URL
+ // user2, pass2 will if given be passed to open() call
+ test(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = "", userwin, passwin
+ // if user2 is set, winning user name and password is 2
+ if(user2)
+ userwin = user2, passwin = pass2
+ // if user1 is set, and user2 is not set, user1 and pass1 win
+ if(user1 && ! user2)
+ userwin = user1, passwin = pass1
+ // if neither user name is set, pass 2 wins (there will be no userinfo in URL)
+ if (!(user1 || user2))
+ passwin = pass2
+ if(user1) { // should add userinfo to URL (there is no way to create userinfo part of URL with only password in)
+ urlstart = "http://" + user1
+ if(pass1)
+ urlstart += ":" + pass1
+ urlstart += "@" + location.host + location.pathname.replace(/\/[^\/]*$/, '/')
+ }
+ client.open("GET", urlstart + "resources/authentication.py", false, user2, pass2)
+ client.setRequestHeader("x-user", userwin)
+ client.send(null)
+ assert_true(client.responseText == ((userwin||'') + "\n" + (passwin||'')), 'responseText should contain the right user and password')
+
+ // We want to send multiple requests to the same realm here, so we try to make the UA forget its (cached) credentials between each test..
+ // forcing a 401 response to (hopefully) "log out"
+ // NOTE: This is commented out because it causes authentication prompts while running the test
+ //client.open('GET', "resources/authentication.py?logout=1", false)
+ //client.send()
+ }, document.title+' '+name)
+ }
+ request(null, null, token(), token(), 'user/pass in open() call')
+ request(null, null, token(), token(), 'another user/pass in open() call - must override cached credentials from previous test')
+ request("userinfo-user", "userinfo-pass", token(), token(), 'user/pass both in URL userinfo AND open() call - expexted that open() wins')
+ request(token(), token(), null, null, 'user/pass *only* in URL userinfo')
+ request(token(), null, null, token(), 'user name in URL userinfo, password in open() call: user name wins and password is thrown away')
+ request("1", token(), token(), null, 'user name and password in URL userinfo, only user name in open() call: user name in open() wins')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-cors-basic-setrequestheader.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-cors-basic-setrequestheader.htm
new file mode 100644
index 000000000..85911d78d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-cors-basic-setrequestheader.htm
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated CORS request using setRequestHeader() (expects to succeed)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <!-- These spec references do not make much sense simply because the spec doesn't say very much about this.. -->
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="following::ol[1]/li[6]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
+ user = token()
+ client.open("GET", location.protocol+'//www1.'+urlstart + "resources/auth2/corsenabled.py", false)
+ client.withCredentials = true
+ client.setRequestHeader("x-user", user)
+ client.setRequestHeader("x-pass", 'pass')
+ client.setRequestHeader('Authorization', 'Basic ' + btoa(user + ":pass"))
+ client.onreadystatechange = function () {
+ if (client.readyState < 4) {return}
+ test.step( function () {
+ assert_true(client.responseText == (user + '\npass'), 'responseText should contain the right user and password')
+ assert_equals(client.status, 200)
+ assert_equals(client.getResponseHeader('x-challenge'), 'DID-NOT')
+ test.done()
+ } )
+ }
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-cors-setrequestheader-no-cred.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-cors-setrequestheader-no-cred.htm
new file mode 100644
index 000000000..14edf5bd7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-cors-setrequestheader-no-cred.htm
@@ -0,0 +1,61 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated CORS request using setRequestHeader() but not setting withCredentials (expects to succeed)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <!-- These spec references do not make much sense simply because the spec doesn't say very much about this.. -->
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="following::ol[1]/li[6]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function doTest(desc, pathsuffix, conditionsFunc, errorFunc, endFunc) {
+ var test = async_test(desc)
+ test.step(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
+ user = token()
+ client.open("GET", location.protocol + "//www1." + urlstart + "resources/" + pathsuffix, false)
+ client.setRequestHeader("x-user", user)
+ client.setRequestHeader("x-pass", 'pass')
+ client.setRequestHeader("Authorization", "Basic " + btoa(user + ":pass"))
+ client.onerror = test.step_func(errorFunc)
+ client.onreadystatechange = test.step_func(function () {
+ if(client.readyState < 4) {return}
+ conditionsFunc(client, test, user)
+ })
+ if(endFunc) {
+ client.onloadend = test.step_func(endFunc)
+ }
+ client.send(null)
+ })
+ }
+
+ doTest("CORS request with setRequestHeader auth to URL accepting Authorization header", "auth7/corsenabled.py", function (client, test, user) {
+ assert_true(client.responseText == (user + "\npass"), "responseText should contain the right user and password")
+ assert_equals(client.status, 200)
+ assert_equals(client.getResponseHeader("x-challenge"), "DID-NOT")
+ test.done()
+ }, function(){
+ assert_unreached("Cross-domain request is permitted and should not cause an error")
+ this.done()
+ })
+
+ var errorFired = false;
+ doTest("CORS request with setRequestHeader auth to URL NOT accepting Authorization header", "auth8/corsenabled-no-authorize.py", function (client, test, user) {
+ assert_equals(client.responseText, '')
+ assert_equals(client.status, 0)
+ }, function(e){
+ errorFired = true
+ assert_equals(e.type, 'error', 'Error event fires when Authorize is a user-set header but not allowed by the CORS endpoint')
+ }, function() {
+ assert_true(errorFired, 'The error event should fire')
+ this.done()
+ })
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-existing-session-manual.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-existing-session-manual.htm
new file mode 100644
index 000000000..a80efd6e8
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-existing-session-manual.htm
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authenticated requests with user name and password from interactive session</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <p>Please follow these steps to complete the test:</p>
+ <script>var user = token();</script>
+ <ol>
+ <li>Load <a href="resources/auth3/auth.py">page</a> and authenticate with username "<script>document.write(user)</script>" and password "pass"</li>
+ <li>Go back</li>
+ <li>Click <button onclick="location.href = location.href + '?dotest&user=' + user">complete test</button></li>
+ </ol>
+ <div id="log"></div>
+ <script>
+ if (location.search.indexOf('?dotest') != -1) {
+ test(function() {
+ var user = location.search.slice(location.search.indexOf('&user=') + 6),
+ client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/')
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth3/auth.py", false)
+ client.send(null)
+ assert_equals(client.responseText, user + "\n" + 'pass')
+ assert_equals(client.getResponseHeader('x-challenge'), 'DID-NOT')
+ }, document.title)
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-prompt-2-manual.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-prompt-2-manual.htm
new file mode 100644
index 000000000..023a40a63
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-prompt-2-manual.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: WWW-Authenticate challenge when user,pass are not passed to open()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <p>Please follow these steps to complete the test:</p>
+ <ol>
+ <li>If you are prompted for user name and password, type in 'usr' and 'secret'</li>
+ </ol>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/')
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth6/auth.py", false)
+ client.send(null)
+ assert_equals(client.responseText, 'usr' + "\n" + 'secret')
+ }, document.title)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-authentication-prompt-manual.htm b/testing/web-platform/tests/XMLHttpRequest/send-authentication-prompt-manual.htm
new file mode 100644
index 000000000..a836c59e2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-authentication-prompt-manual.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - "Basic" authentication gets 401 response</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
+ </head>
+ <body>
+ <p>Please follow these steps to complete the test:</p>
+ <ol>
+ <li>If you are prompted for user name and password, type in 'usr' and 'secret'</li>
+ </ol>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest(),
+ urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/')
+ client.open("GET", location.protocol+'//'+urlstart + "resources/auth5/auth.py", false, 'usr', 'wrongpassword')
+ client.send(null)
+ assert_equals(client.responseText, 'usr' + "\n" + 'secret')
+ }, document.title)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-blob-with-no-mime-type.html b/testing/web-platform/tests/XMLHttpRequest/send-blob-with-no-mime-type.html
new file mode 100644
index 000000000..98fef6592
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-blob-with-no-mime-type.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[4]/dl[1]/dd[2]/p[3]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol[1]/li[3]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetype-attribute" data-tested-assertations="following::ol[1]/li[4]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::a[contains(@href,'#blob-response-entity-body')]/.."/>
+
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: Blob data with no mime type</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var blobTests = [
+ ["no mime type", new Blob(["data"])],
+ ["invalid mime type", new Blob(["data"], {type: "Invalid \r\n mime \r\n type"})]
+ ];
+
+ blobTests.forEach(function(item){
+ test(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.open("POST", "./resources/content.py", false);
+ xhr.send(item[1]);
+
+ assert_equals(xhr.getResponseHeader("X-Request-Content-Length"), "4");
+ assert_equals(xhr.getResponseHeader("X-Request-Content-Type"), "NO");
+ }, "Synchronous blob loading with " + item[0]);
+
+ var atest = async_test("Asynchronous blob loading with " + item[0]);
+ atest.step(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ atest.step(function() {
+ assert_equals(xhr.getResponseHeader("X-Request-Content-Length"), "4");
+ assert_equals(xhr.getResponseHeader("X-Request-Content-Type"), "NO");
+ });
+ atest.done();
+ }
+ }
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send(item[1]);
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-conditional.htm b/testing/web-platform/tests/XMLHttpRequest/send-conditional.htm
new file mode 100644
index 000000000..cbe3e94a4
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-conditional.htm
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - conditional requests</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(text(),'Modified')]/.." />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(type) {
+ test(function() {
+ var client = new XMLHttpRequest,
+ identifier = type == "tag" ? Math.random() : new Date().toGMTString(),
+ url = "resources/conditional.py?" + type + "=" + identifier
+ client.open("GET", url, false)
+ client.send(null)
+ assert_equals(client.status, 200)
+ assert_equals(client.statusText, "OK")
+ assert_equals(client.responseText, "MAYBE NOT")
+ client.open("GET", url, false)
+ client.setRequestHeader(type == "tag" ? "If-None-Match" : "If-Modified-Since", identifier)
+ client.send(null)
+ assert_equals(client.status, 304)
+ assert_equals(client.statusText, "SUPERCOOL")
+ assert_equals(client.responseText, "")
+ }, document.title + " (" + type + ")")
+ }
+ request("tag")
+ request("date")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-content-type-charset.htm b/testing/web-platform/tests/XMLHttpRequest/send-content-type-charset.htm
new file mode 100755
index 000000000..9e93279d6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-content-type-charset.htm
@@ -0,0 +1,83 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - charset parameter of Content-Type</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[4]/p/code[contains(text(),'Content-Type')]/.. following::ol[1]/li[4]/p/code[contains(text(),'Content-Type')]/../following-sibling::p" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-a-string" data-tested-assertations="following::p[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(input, output, title) {
+ title = title || document.title + ' - ' + input;
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/content.py", false)
+ if(input)
+ client.setRequestHeader("Content-Type", input)
+ client.send("TEST")
+ assert_equals(client.responseText, "TEST")
+ assert_equals(client.getResponseHeader("x-request-content-type"), output)
+ }, title)
+ }
+
+ request(
+ "text; charset=ascii",
+ "text; charset=ascii",
+ "header with invalid MIME type is not changed"
+ )
+ request(
+ "charset=ascii",
+ "charset=ascii",
+ "known charset but bogus header - missing MIME type"
+ )
+ request(
+ "charset=bogus",
+ "charset=bogus",
+ "bogus charset and bogus header - missing MIME type"
+ )
+ request(
+ "text/plain;charset=utf-8",
+ "text/plain;charset=utf-8",
+ "Correct text/plain MIME with charset"
+ )
+ request(
+ "text/x-pink-unicorn",
+ "text/x-pink-unicorn",
+ "If no charset= param is given, implementation should not add one - unknown MIME"
+ )
+ request(
+ "text/plain",
+ "text/plain",
+ "If no charset= param is given, implementation should not add one - known MIME"
+ )
+ request(
+ "text/x-thepiano;charset= waddup",
+ "text/x-thepiano;charset=UTF-8",
+ "charset given but wrong, fix it (unknown MIME, bogus charset)"
+ )
+ request(
+ "text/plain;charset=utf-8;charset=waddup",
+ "text/plain;charset=utf-8;charset=UTF-8",
+ "charset given but wrong, fix it (known MIME, bogus charset)"
+ )
+ request(
+ "text/plain;charset=shift-jis",
+ "text/plain;charset=UTF-8",
+ "charset given but wrong, fix it (known MIME, actual charset)"
+ )
+ request(
+ "text/x-pink-unicorn; charset=windows-1252; charset=bogus; notrelated; charset=ascii",
+ "text/x-pink-unicorn; charset=UTF-8; charset=UTF-8; notrelated; charset=UTF-8",
+ "If multiple charset parameters are given, all should be rewritten"
+ )
+ request(
+ null,
+ "text/plain;charset=UTF-8",
+ "No content type set, give MIME and charset"
+ )
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-content-type-string.htm b/testing/web-platform/tests/XMLHttpRequest/send-content-type-string.htm
new file mode 100644
index 000000000..0391ed8b3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-content-type-string.htm
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Content-Type</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-document" data-tested-assertations="following::p[1] following::p[2] following::p[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(data, expected_type) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/content.py", false)
+ client.send(data)
+ assert_equals(client.getResponseHeader("x-request-content-type"), expected_type)
+ })
+ }
+ request("TEST", "text/plain;charset=UTF-8")
+ function init(fr) { request(fr.contentDocument, fr.getAttribute("data-t")) }
+ </script>
+ <iframe src='data:text/xml;charset=windows-1252,<%FF/>' onload="init(this)" data-t="application/xml;charset=UTF-8"></iframe>
+ <iframe src='data:text/html;charset=windows-1252,%FF' onload="init(this)" data-t="text/html;charset=UTF-8"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-data-arraybuffer.htm b/testing/web-platform/tests/XMLHttpRequest/send-data-arraybuffer.htm
new file mode 100644
index 000000000..25c5d2407
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-data-arraybuffer.htm
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[4]/dl[1]/dd[1]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol[1]/li[3]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::ol[1]/li[3]"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: ArrayBuffer data</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ var buf = new ArrayBuffer(5);
+ var arr = new Uint8Array(buf);
+ arr[0] = 0x48;
+ arr[1] = 0x65;
+ arr[2] = 0x6c;
+ arr[3] = 0x6c;
+ arr[4] = 0x6f;
+
+ xhr.onreadystatechange = function()
+ {
+ if (xhr.readyState == 4)
+ {
+ test.step(function()
+ {
+ assert_equals(xhr.status, 200);
+ assert_equals(xhr.response, "Hello");
+
+ test.done();
+ });
+ }
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send(buf);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-data-blob.htm b/testing/web-platform/tests/XMLHttpRequest/send-data-blob.htm
new file mode 100644
index 000000000..5285fc180
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-data-blob.htm
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[4]/dl[1]/dd[2]/p[3]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol[1]/li[3]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetype-attribute" data-tested-assertations="following::ol[1]/li[4]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::a[contains(@href,'#blob-response-entity-body')]/.."/>
+
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: Blob data</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ var xhr2 = new XMLHttpRequest();
+
+ var content = "Hello";
+ var blob;
+
+ xhr.onreadystatechange = function()
+ {
+ if (xhr.readyState == 4)
+ {
+ test.step(function()
+ {
+ blob = xhr.response;
+ assert_true(blob instanceof Blob, "Blob from XHR Response");
+
+ xhr2.open("POST", "./resources/content.py", true);
+ xhr2.send(blob);
+ });
+ }
+ }
+
+ xhr2.onreadystatechange = function()
+ {
+ if (xhr2.readyState == 4)
+ {
+ test.step(function()
+ {
+ assert_equals(xhr2.status, 200);
+ assert_equals(xhr2.response, content);
+ test.done();
+ });
+ }
+ };
+
+ xhr.open("GET", "./resources/content.py?content=" + content, true);
+ xhr.responseType = "blob";
+ xhr.send();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-data-es-object.htm b/testing/web-platform/tests/XMLHttpRequest/send-data-es-object.htm
new file mode 100644
index 000000000..6f7743286
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-data-es-object.htm
@@ -0,0 +1,61 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>XMLHttpRequest: passing objects to send()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol/li[4]" />
+<link rel="help" href="https://heycam.github.io/webidl/#es-union" data-tested-assertations="following::ol/li[16]" />
+
+<div id="log"></div>
+
+<script>
+ function do_test(obj, expected, name) {
+ var test = async_test(name)
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onload = test.step_func(function () {
+ assert_equals(client.responseText, expected)
+ test.done()
+ });
+ client.open('POST', 'resources/content.py')
+ if (expected.exception) {
+ assert_throws(expected.exception, function(){client.send(obj)})
+ test.done()
+ } else {
+ client.send(obj)
+ }
+ });
+ }
+
+ do_test({}, '[object Object]', 'sending a plain empty object')
+ do_test(Math, '[object Math]', 'sending the ES Math object')
+ do_test(new XMLHttpRequest, '[object XMLHttpRequest]', 'sending a new XHR instance')
+ do_test({toString:function(){}}, 'undefined', 'sending object that stringifies to undefined')
+ do_test({toString:function(){return null}}, 'null', 'sending object that stringifies to null')
+ var ancestor = {toString: function(){
+ var ar=[]
+ for (var prop in this) {
+ if (this.hasOwnProperty(prop)) {
+ ar.push(prop+'='+this[prop])
+ }
+ };
+ return ar.join('&')
+ }};
+
+ var myObj = Object.create(ancestor, {foo:{value:1, enumerable: true}, bar:{value:'foo', enumerable:true}})
+ do_test(myObj, 'foo=1&bar=foo', 'object that stringifies to query string')
+
+ var myFakeJSON = {a:'a', b:'b', toString:function(){ return JSON.stringify(this, function(key, val){ return key ==='toString'?undefined:val; }) }}
+ do_test(myFakeJSON, '{"a":"a","b":"b"}', 'object that stringifies to JSON string')
+
+ var myFakeDoc1 = {valueOf:function(){return document}}
+ do_test(myFakeDoc1, '[object Object]', 'object whose valueOf() returns a document - ignore valueOf(), stringify')
+
+ var myFakeDoc2 = {toString:function(){return document}}
+ do_test(myFakeDoc2, {exception:new TypeError()}, 'object whose toString() returns a document, expected to throw')
+
+ var myThrower = {toString:function(){throw {name:'FooError', message:'bar'}}}
+ do_test(myThrower, {exception:{name:'FooError'}}, 'object whose toString() throws, expected to throw')
+
+
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-data-formdata.htm b/testing/web-platform/tests/XMLHttpRequest/send-data-formdata.htm
new file mode 100644
index 000000000..e49762e95
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-data-formdata.htm
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[4]/dl[1]/dd[5]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#interface-formdata" data-tested-assertations="following::*[contains(@id,'dom-formdata')]/following::ol[1]/li[1] following::*[contains(@id,'dom-formdata')]/following::ol[1]/li[3] following::*[contains(@id,'dom-formdata-append')]/following::ul[1]/li[1] following::*[contains(@id,'dom-formdata-append')]/following::ul[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::ol[1]/li[3]"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XmlHttpRequest: The send() method: FormData data</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ var form = new FormData();
+ form.append("id", "0");
+ form.append("value", "zero");
+
+ xhr.onreadystatechange = function()
+ {
+ test.step(function ()
+ {
+ if (xhr.readyState == 4)
+ {
+ assert_equals(xhr.status, 200);
+ assert_equals(xhr.response, "id:0;value:zero;");
+ test.done();
+ }
+ });
+ };
+
+ xhr.open("POST", "./resources/form.py", true);
+ xhr.send(form);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-data-unexpected-tostring.htm b/testing/web-platform/tests/XMLHttpRequest/send-data-unexpected-tostring.htm
new file mode 100644
index 000000000..357a9cff9
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-data-unexpected-tostring.htm
@@ -0,0 +1,57 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>XMLHttpRequest: passing objects that interfere with the XHR instance to send()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol/li[4]" />
+<link rel="help" href="https://heycam.github.io/webidl/#es-union" data-tested-assertations="following::ol/li[16]" />
+
+
+<div id="log"></div>
+
+<script>
+ var test1 = async_test('abort() called from data stringification')
+ test1.step(function() {
+ var client = new XMLHttpRequest()
+ var objAbortsOnStringification = {toString:function(){
+ client.abort();
+ }}
+ client.open('POST', 'resources/content.py')
+ assert_throws("InvalidStateError", function(){
+ client.send(objAbortsOnStringification)
+ })
+ test1.done()
+ });
+
+ var test2 = async_test('open() called from data stringification')
+ test2.step(function() {
+ var client = new XMLHttpRequest()
+ var objOpensOnStringification = {toString:function(){
+ client.open('POST', 'resources/status.py?text=second_open_wins');
+ }}
+ client.onloadend = test2.step_func(function(){
+ assert_equals(client.statusText, 'second_open_wins')
+ test2.done()
+ })
+ client.open('POST', 'resources/status.py?text=first_open_wins')
+ client.send(objOpensOnStringification)
+ });
+
+ var test3 = async_test('send() called from data stringification')
+ test3.step(function() {
+ var client = new XMLHttpRequest()
+ var objSendsOnStringification = {toString:function(){
+ client.send('bomb!');
+ }}
+ client.onload = test3.step_func(function(){
+ assert_equals(client.responseText, 'bomb!')
+ test3.done()
+ })
+ client.open('POST', 'resources/content.py')
+ assert_throws('InvalidStateError', function(){
+ client.send(objSendsOnStringification)
+ })
+ });
+
+
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-entity-body-basic.htm b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-basic.htm
new file mode 100644
index 000000000..41c9ddec4
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-basic.htm
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - data argument</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="/following::ol/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-a-string" data-tested-assertations="/following::dd" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(input, output) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/content.py", false)
+ client.send(input)
+ assert_equals(client.responseText, output)
+ }, document.title + " (" + output + ")")
+ }
+ request(1, "1")
+ request(10000000, "10000000")
+ request([2,2], "2,2")
+ request(false, "false")
+ request("A\0A", "A\0A")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-entity-body-document-bogus.htm b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-document-bogus.htm
new file mode 100644
index 000000000..e834b6105
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-document-bogus.htm
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - unserializable Document</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-document" data-tested-assertations="following::p[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request_throws(input) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/content.py", false)
+ assert_throws("InvalidStateError", function() { client.send(input) })
+ })
+ }
+ var doc = document.implementation.createDocument(null, null, null)
+ while(doc.childNodes.length) {
+ doc.removeChild(doc.childNodes[0])
+ }
+ request_throws(doc)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-entity-body-document.htm b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-document.htm
new file mode 100644
index 000000000..5f1cb68dc
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-document.htm
@@ -0,0 +1,61 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Document</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="/following::ol/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-document" data-tested-assertations="/following::dd" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var expectations = [
+ { contentType: 'application/xml;charset=UTF-8', responseText : '<\u00FF\/>' },
+ { contentType: 'text/html;charset=UTF-8', responseText : '<body>\uFFFD<\/body>' }, /*invalid character code in document turns into FFFD*/
+ { contentType: 'text/html;charset=UTF-8', responseText : '<body>\u30C6\u30b9\u30c8<\/body>' } /* correctly serialized Shift-JIS */,
+ { contentType: 'text/html;charset=UTF-8', responseText: 'top' }, /* There's some markup included, but it's not really relevant for this test suite, so we do an indexOf() test */
+ { contentType: 'text/html;charset=UTF-8' },
+ { contentType: 'text/html;charset=UTF-8', responseText: '<img>foo' },
+ { contentType: 'text/html;charset=UTF-8', responseText: '<!DOCTYPE html><html><head></head><body><div></div></body></html>' }
+ ]
+
+
+ function request(input, number, title) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/content.py?response_charset_label=UTF-8", false)
+ client.send(input)
+ var exp = expectations[number]
+ assert_equals(client.getResponseHeader('X-Request-Content-Type'), exp.contentType, 'document should be serialized and sent as '+exp.contentType+' (TEST#'+number+')')
+ // The indexOf() assertation will overlook some stuff, i.e. XML prologues that shouldn't be there (looking at you, Presto).
+ // However, arguably these things have little to do with the XHR functionality we're testing.
+ if(exp.responseText){ // This test does not want to assert anything about what markup a standalone IMG should be wrapped in. Hence the GIF test lacks a responseText expectation.
+ assert_true(client.responseText.indexOf(exp.responseText) != -1,
+ JSON.stringify(exp.responseText) + " not in " +
+ JSON.stringify(client.responseText));
+ }
+ assert_equals(client.responseXML, null)
+ }, title)
+ }
+ function init(fr, number, title) { request(fr.contentDocument, number, title) }
+ </script>
+ <!--
+ This test also tests how documents in various encodings are serialized.
+ The below IFRAMEs contain:
+ * one XML document parsed from a windows-1252 source - content is <ÿ/>
+ * one HTML-document parsed from an invalid UTF-8 source, will contain a basic HTML DOM
+ with a U+FFFD replacement character for the invalid char
+ * one HTML document parsed from a valid Shift-JIS source
+ -->
+ <iframe src='resources/win-1252-xml.py' onload="init(this, 0, 'XML document, windows-1252')"></iframe>
+ <iframe src='resources/invalid-utf8-html.py' onload="init(this, 1, 'HTML document, invalid UTF-8')"></iframe>
+ <iframe src='resources/shift-jis-html.py' onload="init(this, 2, 'HTML document, shift-jis')"></iframe>
+ <iframe src='folder.txt' onload="init(this, 3, 'plain text file')"></iframe>
+ <iframe src='resources/image.gif' onload="init(this, 4, 'image file')"></iframe>
+ <iframe src='resources/img-utf8-html.py' onload="init(this, 5, 'img tag')"></iframe>
+ <iframe src='resources/empty-div-utf8-html.py' onload="init(this, 6, 'empty div')"></iframe>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-entity-body-empty.htm b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-empty.htm
new file mode 100644
index 000000000..f307e7780
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-empty.htm
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send("") - empty entity body</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[7]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-a-string" data-tested-assertations="following::p[1] following::p[2] following::p[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(method) {
+ var client = new XMLHttpRequest()
+ client.open(method, "resources/content.py", false)
+ client.upload.onloadstart = function(){assert_unreached('this event should not fire for empty strings')}
+ client.send("")
+ var expectedLength = method == "HEAD" ? "NO" : "0";
+ assert_equals(client.getResponseHeader("x-request-content-length"), expectedLength)
+ }
+ test(function() { request("POST"); }, document.title + " (POST)");
+ test(function() { request("PUT"); }, document.title + " (PUT)");
+ test(function() { request("HEAD"); }, document.title + " (HEAD)");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-entity-body-get-head-async.htm b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-get-head-async.htm
new file mode 100644
index 000000000..ff4c4b4ca
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-get-head-async.htm
@@ -0,0 +1,39 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - non-empty data argument and GET/HEAD - async, no upload events should fire</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::OL[1]/LI[3] following::OL[1]/LI[7] following::OL[1]/LI[8]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(method) {
+ var test = async_test( document.title + " (" + method + ")")
+ var events=[]
+ var logEvt = function (e) {
+ events.push(e.type)
+ }
+ var client = new XMLHttpRequest()
+ client.open(method, "resources/content.py")
+ client.upload.addEventListener('progress', logEvt)
+ client.upload.addEventListener('loadend', logEvt)
+ client.upload.addEventListener('loadstart', logEvt)
+ client.addEventListener('loadend', function(){
+ test.step(function(){
+ assert_equals(client.getResponseHeader("x-request-content-length"), "NO")
+ assert_equals(client.getResponseHeader("x-request-method"), method)
+ assert_equals(client.responseText, "")
+ assert_array_equals(events, [])
+ test.done()
+ })
+ })
+ client.send("TEST")
+ }
+ request("GET")
+ request("HEAD")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-entity-body-get-head.htm b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-get-head.htm
new file mode 100644
index 000000000..f3b8cef35
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-get-head.htm
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - non-empty data argument and GET/HEAD</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::OL[1]/LI[3] following::OL[1]/LI[7]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(method) {
+ test(function() {
+ var events=[]
+ var logEvt = function (e) {
+ events.push(e.type)
+ }
+ var client = new XMLHttpRequest()
+ client.open(method, "resources/content.py", false)
+ client.send("TEST")
+ client.upload.addEventListener('progress', logEvt)
+ client.upload.addEventListener('loadend', logEvt)
+ client.upload.addEventListener('loadstart', logEvt)
+
+ assert_equals(client.getResponseHeader("x-request-content-length"), "NO")
+ assert_equals(client.getResponseHeader("x-request-method"), method)
+ assert_equals(client.responseText, "")
+ assert_array_equals(events, [])
+ }, document.title + " (" + method + ")")
+ }
+ request("GET")
+ request("HEAD")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-entity-body-none.htm b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-none.htm
new file mode 100644
index 000000000..d757cb30a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-entity-body-none.htm
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send(null) - no entity body</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[7]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function noContentTypeTest(method) {
+ var client = new XMLHttpRequest()
+ client.open(method, "resources/content.py", false)
+ client.upload.onloadstart = function(){assert_unreached('this event should not fire for null')}
+ client.send(null)
+ var expectedLength = method == "HEAD" ? "NO" : "0";
+ assert_equals(client.getResponseHeader("x-request-content-length"), expectedLength)
+ assert_equals(client.getResponseHeader("x-request-content-type"), "NO")
+ }
+ test(function() { noContentTypeTest("POST"); }, "No content type (POST)");
+ test(function() { noContentTypeTest("PUT"); }, "No content type (PUT)");
+ test(function() { noContentTypeTest("HEAD"); }, "No content type (HEAD)");
+
+ function explicitContentTypeTest(method) {
+ var client = new XMLHttpRequest()
+ client.open(method, "resources/content.py", false)
+ var content_type = 'application/x-foo'
+ client.setRequestHeader('Content-Type', content_type)
+ client.send(null)
+ var expectedLength = method == "HEAD" ? "NO" : "0";
+ assert_equals(client.getResponseHeader("x-request-content-length"), expectedLength)
+ assert_equals(client.getResponseHeader("x-request-content-type"), content_type)
+ }
+ test(function() { explicitContentTypeTest("POST"); }, "Explicit content type (POST)");
+ test(function() { explicitContentTypeTest("PUT"); }, "Explicit content type (PUT)");
+ test(function() { explicitContentTypeTest("HEAD"); }, "Explicit content type (HEAD)");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-network-error-async-events.sub.htm b/testing/web-platform/tests/XMLHttpRequest/send-network-error-async-events.sub.htm
new file mode 100644
index 000000000..76e5e3478
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-network-error-async-events.sub.htm
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onerror" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[9]/ol/li[2] following::ol[1]/li[9]/ol/li[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[4] following::dd[4]/p" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#network-error" data-tested-assertations=".." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[6] following::ol[1]/li[7] following::ol[1]/li[7]/ol/li[3] following::ol[1]/li[7]/ol/li[4] following::ol[1]/li[9] following::ol[1]/li[10]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XmlHttpRequest: The send() method: Fire a progress event named error when Network error happens (synchronous flag is unset)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function(){
+ var xhr = new XMLHttpRequest();
+ var expect = ["loadstart", "upload.loadstart", 4, "upload.error", "upload.loadend", "error", "loadend"];
+ var actual = [];
+
+ xhr.onreadystatechange = function()
+ {
+ test.step(function()
+ {
+ if (xhr.readyState == 4)
+ {
+ actual.push(xhr.readyState);
+ }
+ });
+ };
+
+ xhr.onloadstart = function(e){ actual.push(e.type); };
+ xhr.onloadend = function(e){ actual.push(e.type); VerifyResult()};
+ xhr.onerror = function(e){ actual.push(e.type); };
+
+ xhr.upload.onloadstart = function(e){ actual.push("upload." + e.type);};
+ xhr.upload.onloadend = function(e){ actual.push("upload." + e.type);};
+ xhr.upload.onerror = function(e){ actual.push("upload." + e.type); };
+
+ function VerifyResult()
+ {
+ test.step(function()
+ {
+ assert_array_equals(actual, expect);
+ test.done();
+ });
+ };
+
+ xhr.open("POST", "http://nonexistent-origin.{{host}}:{{ports[http][0]}}", true);
+ xhr.send("Test Message");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-network-error-sync-events.sub.htm b/testing/web-platform/tests/XMLHttpRequest/send-network-error-sync-events.sub.htm
new file mode 100644
index 000000000..cefa80ad5
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-network-error-sync-events.sub.htm
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[4] following::dd[4]/p" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#network-error" data-tested-assertations=".." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[5]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XmlHttpRequest: The send() method: Throw a "throw an "NetworkError" exception when Network error happens (synchronous flag is set)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ test(function()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.open("POST", "http://nonexistent-origin.{{host}}}:{{ports[http][0]}}", false);
+
+ assert_throws("NetworkError", function()
+ {
+ xhr.send("Test Message");
+ });
+ assert_equals(xhr.readyState, 4)
+
+ xhr.open("GET", "data:text/html;charset=utf-8;base64,PT0NUWVBFIGh0bWw%2BDQo8", false);
+
+ assert_throws("NetworkError", function()
+ {
+ xhr.send("Test Message");
+ });
+ assert_equals(xhr.readyState, 4)
+
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-loadend.htm b/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-loadend.htm
new file mode 100644
index 000000000..0a1eda537
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-loadend.htm
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: Fire a progress event named loadend (no response entity body)</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadend" data-tested-assertations="/../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="/../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[10] /following-sibling::ol/li[10]" />
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function ()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.onreadystatechange = function()
+ {
+ test.step(function()
+ {
+ if (xhr.readyState == 4)
+ {
+ assert_equals(xhr.response, "");
+ }
+ });
+ };
+
+ xhr.onloadend = function(e)
+ {
+ test.step(function()
+ {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "loadend");
+ test.step(function() { test.done(); });
+ });
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-loadstart.htm b/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-loadstart.htm
new file mode 100644
index 000000000..cd4a0683e
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-loadstart.htm
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadstart" data-tested-assertations="/../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadstart" data-tested-assertations="/../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="/following-sibling::ol/li[9]/ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="/following-sibling::ol/li[1]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: Fire a progress event named loadstart (no response entity body and the state is LOADING)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.onreadystatechange = function()
+ {
+ test.step(function()
+ {
+ if (xhr.readyState == 3)
+ {
+ assert_equals(xhr.response, "");
+ }
+ else if (xhr.readyState == 4)
+ {
+ assert_unreached("loadstart event did not fire in LOADING state!");
+ }
+ });
+ };
+
+ xhr.onloadstart = function()
+ {
+ test.step(function() { test.done("Test done!"); });
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-order.htm b/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-order.htm
new file mode 100644
index 000000000..44c1d7797
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-order.htm
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol/li[9]/ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[10] following::a[contains(@href,'#switch-done')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::ol[1]/li[3] following::ol[1]/li[4] following::ol[1]/li[6] following::ol[1]/li[7]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following-sibling::ol/li[1]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-event-order.js"></script>
+ <title>XMLHttpRequest: The send() method: event order when there is no response entity body</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ prepare_xhr_for_event_order_test(xhr);
+
+ xhr.addEventListener("readystatechange", test.step_func(function() {
+ if (xhr.readyState == 3) {
+ assert_equals(xhr.response, "");
+ }
+ }));
+
+ xhr.addEventListener("loadend", test.step_func(function(e) {
+ assert_xhr_event_order_matches([1, "loadstart(0,0,false)", 2, "progress(0,0,false)", 4,"load(0,0,false)", "loadend(0,0,false)"]);
+ test.done();
+ }));
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-non-same-origin.sub.htm b/testing/web-platform/tests/XMLHttpRequest/send-non-same-origin.sub.htm
new file mode 100644
index 000000000..91c384561
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-non-same-origin.sub.htm
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - non same-origin</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <base>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#cross-origin-request-steps" data-tested-assertations="/following::DL[2]/DT[1] /following::DL[2]/DD[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#cross-origin-request-event-rules" data-tested-assertations="/following::DL[1]/DT[2] /following::DL[1]/DD[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script>
+ // Setting base URL before running the tests
+ var host_info = get_host_info();
+ document.getElementsByTagName("base")[0].setAttribute("href", host_info.HTTP_REMOTE_ORIGIN);
+
+ function url(url) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", url, false)
+ assert_throws("NetworkError", function() { client.send() })
+ }, document.title + " (" + url + ")")
+ }
+ url("mailto:test@example.org")
+ url("tel:+31600000000")
+ url(host_info.HTTP_REMOTE_ORIGIN)
+ url("javascript:alert('FAIL')")
+ url("folder.txt")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-receive-utf16.htm b/testing/web-platform/tests/XMLHttpRequest/send-receive-utf16.htm
new file mode 100644
index 000000000..6d6fb90a1
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-receive-utf16.htm
@@ -0,0 +1,37 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>XMLHttpRequest: The send() method: receive data which is UTF-16 encoded</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#text-response" data-tested-assertations="following::ol/li[9]" />
+<div id="log"></div>
+
+<script>
+ async_test(function() {
+ var client = new XMLHttpRequest();
+ client.onload = this.step_func_done(function(e) {
+ assert_equals(client.responseText, 'æøå\nテスト\n')
+ });
+ client.open("GET", "resources/utf16.txt");
+ client.send(null);
+ }, 'UTF-16 with BOM, no encoding in content-type');
+
+ async_test(function() {
+ var client = new XMLHttpRequest();
+ client.onload = this.step_func_done(function(e) {
+ assert_equals(client.responseText, 'æøå\nテスト\n')
+ });
+ client.open("GET", "resources/status.py?code=200&type=text%2Fplain%3Bcharset%3DUTF-16&content=%E6%00%F8%00%E5%00%0A%00%C6%30%B9%30%C8%30%0A%00");
+ client.send(null);
+ }, 'UTF-16 without BOM, with charset label in content-type');
+
+ async_test(function() {
+ var client = new XMLHttpRequest();
+ client.onload = this.step_func_done(function(e) {
+ // plenty of EF BF BD Replacement Character in this invalid input..
+ assert_equals(client.responseText, "\ufffd\u0000\ufffd\u0000\ufffd\u0000\u000a\u0000\ufffd\u0030\ufffd\u0030\ufffd\u0030\u000a\u0000")
+ });
+ client.open("GET", "resources/status.py?code=200&type=text%2Fplain%3Bcharset%3DUTF-8&content=%E6%00%F8%00%E5%00%0A%00%C6%30%B9%30%C8%30%0A%00");
+ client.send(null);
+ }, 'UTF-16 without BOM, mislabelled as UTF-8 in content-type');
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-redirect-bogus-sync.htm b/testing/web-platform/tests/XMLHttpRequest/send-redirect-bogus-sync.htm
new file mode 100644
index 000000000..89e6ff0eb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-redirect-bogus-sync.htm
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Redirects (bogus Location header; sync)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/ol/li[1] following::dl[1]/dd[2]/ol/li[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function redirect(code, location) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/redirect.py?location=" + location + "&code=" + code, false)
+ assert_throws("NetworkError", function() { client.send(null) })
+ }, document.title + " (" + code + ": " + location + ")")
+ }
+ redirect("301", "foobar://abcd")
+ redirect("302", "http://z")
+ redirect("302", "mailto:someone@example.org")
+ redirect("303", "http://z")
+ redirect("303", "tel:1234567890")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-redirect-bogus.htm b/testing/web-platform/tests/XMLHttpRequest/send-redirect-bogus.htm
new file mode 100644
index 000000000..a46fc1d33
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-redirect-bogus.htm
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Redirects (bogus Location header)</title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/ol/li[1] following::dl[1]/dd[2]/ol/li[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function redirect(code, location) {
+ var test = async_test(document.title + " (" + code + ": " + location + ")", {timeout: 20000})
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.status, 0)
+ assert_equals(client.statusText, "")
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/redirect.py?location=" + location + "&code=" + code)
+ client.send(null)
+ })
+ }
+ redirect("302", "http://example.not")
+ redirect("302", "mailto:someone@example.org")
+ redirect("303", "http://example.not")
+ redirect("303", "foobar:someone@example.org")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-redirect-infinite-sync.htm b/testing/web-platform/tests/XMLHttpRequest/send-redirect-infinite-sync.htm
new file mode 100644
index 000000000..6e9e47e55
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-redirect-infinite-sync.htm
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Redirects (infinite loop; sync)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/p[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#network-error" data-tested-assertations=".." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[5]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function redirect(code) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/infinite-redirects.py?type="+code, false)
+ assert_throws("NetworkError", function() { client.send(null) })
+ }, document.title + " (" + code + ")")
+ }
+ redirect("301")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-redirect-infinite.htm b/testing/web-platform/tests/XMLHttpRequest/send-redirect-infinite.htm
new file mode 100644
index 000000000..414e4107e
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-redirect-infinite.htm
@@ -0,0 +1,35 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Redirects (infinite loop)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onerror" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/p[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#network-error" data-tested-assertations=".." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[9] following::ol[1]/li[10]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol[1]/li[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ var client = new XMLHttpRequest(),
+ errorEventFired = false,
+ code = 301
+ client.open("GET", "resources/infinite-redirects.py?type="+code)
+ client.onerror = function(){
+ errorEventFired = true
+ }
+ client.onloadend = function(){
+ test.step(function() {
+ assert_equals(errorEventFired, true)
+ assert_equals(client.responseText, '')
+ assert_equals(client.readyState, 4)
+ test.done()
+ })
+ }
+ client.send(null)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-redirect-no-location.htm b/testing/web-platform/tests/XMLHttpRequest/send-redirect-no-location.htm
new file mode 100644
index 000000000..85ae963f4
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-redirect-no-location.htm
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Redirects (no Location header)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2]" />
+ <!--
+ NOTE: the XHR spec does not really handle this scenario. It's handled in the Fetch spec:
+ "If response's headers do not contain a header whose name is Location, return response."
+ -->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function redirect(code) {
+ var test = async_test(document.title + " (" + code + ")")
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.status + "", code)
+ assert_equals(client.statusText, "ABE ODDYSSEE")
+ assert_equals(client.responseXML.documentElement.localName, "x")
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/status.py?content=<x>x<\/x>&type=text/xml&text=ABE ODDYSSEE&code=" + code)
+ client.send(null)
+ })
+ }
+ redirect("301")
+ redirect("302")
+ redirect("303")
+ redirect("307")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-redirect-post-upload.htm b/testing/web-platform/tests/XMLHttpRequest/send-redirect-post-upload.htm
new file mode 100644
index 000000000..1e705cada
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-redirect-post-upload.htm
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onprogress" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-progress" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::dt[@id="dom-xmlhttprequest-send-bodyinit"]/following::dd[1]/p[2] following::ol[1]/li[9]//li[1] following::ol[1]/li[9]//li[2]" />
+ <link rel="help" href="https://fetch.spec.whatwg.org/#http-fetch" data-tested-assertations="following::ol[1]/li[6]/dl/dd[1]//dd[3]" />
+ <link rel="help" href="https://fetch.spec.whatwg.org/#concept-http-redirect-fetch" data-tested-assertations="following::li[16]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: POSTing to URL that redirects</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ function testRedirectPost(code, shouldResendPost) {
+ var test = async_test(document.title + " (" + code + ")");
+ var actual = [];
+ // We check upload.onprogress with a boolean because it *might* fire more than once
+ var progressFiredReadyState1 = false;
+
+ var expectedHeaders, expectedEvents;
+
+ // 307 redirects should resend the POST data, and events and headers will be a little different..
+ if(shouldResendPost) {
+ expectedHeaders = {
+ "X-Request-Content-Length": "11988",
+ "X-Request-Content-Type": "text/plain;charset=UTF-8",
+ "X-Request-Method": "POST",
+ "X-Request-Query": "NO",
+ "Content-Length": "11988"
+ }
+ expectedEvents = [
+ "xhr onreadystatechange 1",
+ "xhr loadstart 1",
+ "upload loadstart 1",
+ "upload loadend 1",
+ "xhr onreadystatechange 2",
+ "xhr onreadystatechange 3",
+ "xhr onreadystatechange 4",
+ "xhr load 4",
+ "xhr loadend 4"
+ ];
+ } else {
+ // setting the right expectations for POST resent as GET without request body
+ expectedHeaders = {
+ "X-Request-Content-Length": "NO",
+ "X-Request-Content-Type": "NO",
+ "X-Request-Method": "GET",
+ "X-Request-Query": "NO"
+ }
+ expectedEvents = [
+ "xhr onreadystatechange 1",
+ "xhr loadstart 1",
+ "upload loadstart 1",
+ "upload loadend 1",
+ "xhr onreadystatechange 2",
+ /* we expect no onreadystatechange readyState=3 event because there is no loading content */
+ "xhr onreadystatechange 4",
+ "xhr load 4",
+ "xhr loadend 4"
+ ];
+ }
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.upload.onloadstart = test.step_func(function(e) {
+ actual.push("upload loadstart " + xhr.readyState);
+ });
+ xhr.upload.onprogress = test.step_func(function(e) {
+ // events every 50ms, one final when uploading is done
+ if(xhr.readyState >= xhr.HEADERS_RECEIVED) {
+ assert_equals(xhr.status, 200, "JS never gets to see the 30x status code");
+ }
+ progressFiredReadyState1 = xhr.readyState === xhr.OPENED;
+ });
+ xhr.upload.onloadend = test.step_func(function() {
+ actual.push("upload loadend " + xhr.readyState);
+ });
+ xhr.onloadstart = test.step_func(function() {
+ actual.push("xhr loadstart " + xhr.readyState);
+ });
+ xhr.onreadystatechange = test.step_func(function() {
+ if(xhr.readyState >= xhr.HEADERS_RECEIVED) {
+ assert_equals(xhr.status, 200, "JS never gets to see the 30x status code");
+ }
+ actual.push("xhr onreadystatechange " + xhr.readyState);
+ });
+ xhr.onload = test.step_func(function(e)
+ {
+ actual.push("xhr load " + xhr.readyState);
+ });
+ xhr.onloadend = test.step_func(function(e)
+ {
+ actual.push("xhr loadend " + xhr.readyState);
+
+ assert_true(progressFiredReadyState1, "One progress event should fire on xhr.upload when readyState is 1");
+
+ // Headers will tell us if data was sent when expected
+ for(var header in expectedHeaders) {
+ assert_equals(xhr.getResponseHeader(header), expectedHeaders[header], header);
+ }
+
+ assert_array_equals(actual, expectedEvents, "events firing in expected order and states");
+ test.done();
+ });
+
+ xhr.open("POST", "./resources/redirect.py?location=content.py&code=" + code, true);
+ xhr.send((new Array(1000)).join("Test Message"));
+ });
+ }
+
+
+ testRedirectPost(301, false);
+ testRedirectPost(302, false);
+ testRedirectPost(303, false);
+ testRedirectPost(307, true);
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-redirect-to-cors.htm b/testing/web-platform/tests/XMLHttpRequest/send-redirect-to-cors.htm
new file mode 100644
index 000000000..b879ec66a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-redirect-to-cors.htm
@@ -0,0 +1,68 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Redirect to CORS-enabled resource</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/ol/li[1] following::dl[1]/dd[2]/ol/li[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function extractBody(body) {
+ if (body === null) {
+ return { body: "", type: "NO" };
+ }
+
+ if (typeof body == "string") {
+ return { body: body, type: "text/plain;charset=UTF-8" };
+ }
+
+ if (body instanceof Uint8Array) {
+ var arr = Array.prototype.slice.call(body);
+ return { body: String.fromCharCode.apply(null, arr), type: "NO" }
+ }
+
+ return { body: "EXTRACT NOT IMPLEMENTED",
+ type: "EXTRACT NOT IMPLEMENTED" }
+ }
+
+ function redirect(code, method = "GET", body = null, setExplicitType = true) {
+ var test = async_test(document.title + " (" + code + ")")
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if (client.readyState == 4) {
+ assert_equals(client.status, 200);
+ assert_equals(client.getResponseHeader("x-request-method"),
+ method);
+ var { body: expectedBody, type: expectedType } = extractBody(body);
+ if (setExplicitType) {
+ expectedType = "application/x-pony";
+ }
+ assert_equals(client.getResponseHeader("x-request-content-type"),
+ expectedType);
+ assert_equals(client.getResponseHeader("x-request-data"),
+ expectedBody);
+ test.done();
+ }
+ })
+ }
+ client.open(method, "resources/redirect.py?location="+encodeURIComponent("http://www2."+location.host+(location.pathname.replace(/[^\/]+$/, ''))+'resources/corsenabled.py')+"&code=" + code)
+ if (setExplicitType) {
+ client.setRequestHeader("Content-Type", "application/x-pony")
+ }
+ client.send(body)
+ })
+ }
+ redirect("301")
+ redirect("302")
+ redirect("303")
+ redirect("307")
+ redirect("307", "POST", null, false);
+ redirect("307", "POST", "hello", false);
+ redirect("307", "POST", new Uint8Array([65, 66, 67]), false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-redirect-to-non-cors.htm b/testing/web-platform/tests/XMLHttpRequest/send-redirect-to-non-cors.htm
new file mode 100644
index 000000000..c6886a57b
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-redirect-to-non-cors.htm
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Redirect to cross-origin resource, not CORS-enabled</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/ol/li[1] following::dl[1]/dd[2]/ol/li[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function redirect(code) {
+ var test = async_test(document.title + " (" + code + ")")
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.getResponseHeader("x-request-method"), null)
+ assert_equals(client.getResponseHeader("x-request-content-type"), null)
+ assert_equals(client.responseText, '')
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/redirect.py?location="+encodeURIComponent("http://www2."+location.host+(location.pathname.replace(/[^\/]+$/, ''))+'resources/content.py')+"&code=" + code)
+ client.setRequestHeader("Content-Type", "application/x-pony")
+ client.send(null)
+ })
+ }
+ redirect("301")
+ redirect("302")
+ redirect("303")
+ redirect("307")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-redirect.htm b/testing/web-platform/tests/XMLHttpRequest/send-redirect.htm
new file mode 100644
index 000000000..16b3231e2
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-redirect.htm
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - Redirects (basics)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/ol/li[1] following::dl[1]/dd[2]/ol/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function redirect(code) {
+ var test = async_test(document.title + " (" + code + ")")
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ if(client.readyState == 4) {
+ assert_equals(client.getResponseHeader("x-request-method"), "GET")
+ assert_equals(client.getResponseHeader("x-request-content-type"), "application/x-pony")
+ test.done()
+ }
+ })
+ }
+ client.open("GET", "resources/redirect.py?location=content.py&code=" + code)
+ client.setRequestHeader("Content-Type", "application/x-pony")
+ client.send(null)
+ })
+ }
+ redirect("301")
+ redirect("302")
+ redirect("303")
+ redirect("307")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-response-event-order.htm b/testing/web-platform/tests/XMLHttpRequest/send-response-event-order.htm
new file mode 100644
index 000000000..041cb23c6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-response-event-order.htm
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol/li[9]/ol/li[2] following-sibling::ol/li[9]/ol/li[3] following::a[contains(@href,'#make-upload-progress-notifications')]/.. following::a[contains(@href,'#make-progress-notifications')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#make-upload-progress-notifications" data-tested-assertations="following::ul[1]/li[1] following::ul[1]/li[2]/ol[1]/li[2] following::ul[1]/li[2]/ol[1]/li[3] following::ul[1]/li[2]/ol[1]/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#make-progress-notifications" data-tested-assertations=".." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::a[contains(@href,'#switch-done')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::ol[1]/li[3] following::ol[1]/li[4] following::ol[1]/li[5] following::ol[1]/li[6] following::ol[1]/li[7]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-event-order.js"></script>
+ <title>XMLHttpRequest: The send() method: event order when synchronous flag is unset</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ prepare_xhr_for_event_order_test(xhr);
+
+ xhr.addEventListener("loadend", test.step_func(function() {
+ assert_xhr_event_order_matches([1, "loadstart(0,0,false)", "upload.loadstart(0,12,true)", "upload.progress(12,12,true)", "upload.load(12,12,true)", "upload.loadend(12,12,true)", 2, 3, "progress(12,12,true)", 4, "load(12,12,true)", "loadend(12,12,true)"]);
+ test.done();
+ }));
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send("Test Message");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-loadend.htm b/testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-loadend.htm
new file mode 100644
index 000000000..99a239ab1
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-loadend.htm
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::a[contains(@href,'#make-upload-progress-notifications')]/.. following::ol[1]/li[8]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#make-upload-progress-notifications" data-tested-assertations="following::ul[1]/li[2]/ol[1]/li[4]" />
+
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: Fire a progress event named loadend on the XMLHttpRequestUpload (synchronous flag is unset)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.upload.onloadend = function(e)
+ {
+ test.step(function()
+ {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "loadend");
+ assert_equals(e.target, xhr.upload);
+ test.done();
+ });
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send("Test Message");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-loadstart.htm b/testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-loadstart.htm
new file mode 100644
index 000000000..7a9be9f8c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-loadstart.htm
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[8] following-sibling::ol/li[9]/ol/li[3]" />
+
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: Fire a progress event named loadstart on the XMLHttpRequestUpload (synchronous flag is unset)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.upload.onloadstart = function(e)
+ {
+ test.step(function()
+ {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "loadstart");
+ assert_equals(e.target, xhr.upload);
+ test.done();
+ });
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send("Test Message");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-progress.htm b/testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-progress.htm
new file mode 100644
index 000000000..914aed725
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-response-upload-event-progress.htm
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onprogress" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-progress" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::a[contains(@href,'#make-upload-progress-notifications')]/.. following::ol[1]/li[8]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#make-upload-progress-notifications" data-tested-assertations="following::ul[1]/li[2]/ol[1]/li[2]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: Fire a progress event named progress on the XMLHttpRequestUpload (synchronous flag is unset)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+
+ xhr.upload.onprogress = function(e)
+ {
+ test.step(function()
+ {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "progress");
+ assert_equals(e.target, xhr.upload);
+ test.done();
+ });
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send("Test Message");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-send.htm b/testing/web-platform/tests/XMLHttpRequest/send-send.htm
new file mode 100644
index 000000000..cbcbdb44e
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-send.htm
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: send() - send()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script src="send-send.js"></script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-send.js b/testing/web-platform/tests/XMLHttpRequest/send-send.js
new file mode 100644
index 000000000..2e7fe865f
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-send.js
@@ -0,0 +1,7 @@
+test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/well-formed.xml")
+ client.send(null)
+ assert_throws("InvalidStateError", function() { client.send(null) })
+ client.abort()
+})
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-send.worker.js b/testing/web-platform/tests/XMLHttpRequest/send-send.worker.js
new file mode 100644
index 000000000..9d34ce63d
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-send.worker.js
@@ -0,0 +1,3 @@
+importScripts("/resources/testharness.js");
+importScripts("send-send.js");
+done();
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-sync-blocks-async.htm b/testing/web-platform/tests/XMLHttpRequest/send-sync-blocks-async.htm
new file mode 100644
index 000000000..87caa0f78
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-sync-blocks-async.htm
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <!-- This behaviour is not explicitly spelled out in the spec.
+ It does say "queue tasks" under the "if the synchronous flag is unset" header in point 10 of the "send" algorithm.. -->
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol/li[10]/dl/dd/dl/dd[2]/p[3]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: sync requests should block events on pending async requests</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ var expect = ['sync 4', 'async 2', 'async 3', 'async 4']
+ var actual = []
+
+ test.step(function()
+ {
+ var xhr_async = new XMLHttpRequest()
+ xhr_async.open('GET', 'resources/delay.py?ms=1000', true) // first launch an async request, completes in 1 second
+ xhr_async.onreadystatechange = function()
+ {
+ test.step(function()
+ {
+ actual.push('async ' + xhr_async.readyState)
+ if(xhr_async.readyState === 4 && actual.indexOf('sync 4')>-1){
+ VerifyResult()
+ }
+
+ });
+ };
+ xhr_async.send()
+
+ setTimeout(function(){
+ var xhr_sync = new XMLHttpRequest();
+ xhr_sync.open('GET', 'resources/delay.py?ms=2000', false) // here's a sync request that will take 2 seconds to finish
+ xhr_sync.onreadystatechange = function()
+ {
+ test.step(function()
+ {
+ actual.push('sync ' + xhr_sync.readyState)
+ if(xhr_sync.readyState === 4 && actual.indexOf('async 4')>-1){
+ VerifyResult()
+ }
+ });
+ };
+ xhr_sync.send()
+
+ }, 10);
+
+ function VerifyResult()
+ {
+ test.step(function()
+ {
+ assert_array_equals(actual, expect);
+ test.done();
+ });
+ };
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-load.htm b/testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-load.htm
new file mode 100644
index 000000000..a2a551658
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-load.htm
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onload" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-load" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[11] following::a[contains(@href,'#switch-done')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::ol/li[1] following::ol/li[6]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="/following::ol/li[3]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: Fire an event named load (no response entity body and the synchronous flag is set)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ test(function()
+ {
+ var xhr = new XMLHttpRequest();
+ var pass = false;
+
+ xhr.onload = function(e)
+ {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "load");
+ pass = true;
+ };
+
+ xhr.open("POST", "./resources/content.py", false);
+ xhr.send();
+
+ assert_equals(xhr.response, "");
+ assert_true(pass);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-loadend.htm b/testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-loadend.htm
new file mode 100644
index 000000000..7da2a3118
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-loadend.htm
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[11] following::a[contains(@href,'#switch-done')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::ol/li[1] following::ol/li[7]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="/following::ol/li[3]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: Fire an event named loadend (no response entity body and the synchronous flag is set)</title>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ test(function()
+ {
+ var xhr = new XMLHttpRequest();
+ var pass = false;
+
+ xhr.onloadend = function(e)
+ {
+ assert_true(e instanceof ProgressEvent);
+ assert_equals(e.type, "loadend");
+ pass = true;
+ };
+
+ xhr.open("POST", "./resources/content.py", false);
+ xhr.send();
+
+ assert_equals(xhr.response, "");
+ assert_true(pass);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-order.htm b/testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-order.htm
new file mode 100644
index 000000000..c7e3172cb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-sync-no-response-event-order.htm
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>XMLHttpRequest: The send() method: event order when synchronous flag is set and there is no response entity body</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol[1]/li[9]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#same-origin-request-steps" data-tested-assertations="following::DL[1]/DT[1]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[11] following::a[contains(@href,'#switch-done')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[3] following::ol[1]/li[4] following::ol[1]/li[6] following::ol[1]/li[7]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::ol/li[3]" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ test(function () {
+ var xhr = new XMLHttpRequest();
+ var expect = [4, "load", "loadend"];
+ var actual = [];
+
+ xhr.onreadystatechange = function()
+ {
+ if (xhr.readyState == 4)
+ {
+ actual.push(xhr.readyState);
+ }
+ };
+
+ xhr.onloadstart = function(e){ actual.push(e.type); };
+ xhr.onload = function(e){ actual.push(e.type); };
+ xhr.onloadend = function(e){ actual.push(e.type); };
+
+ xhr.upload.onload = function(e){ actual.push("upload." + e.type); };
+ xhr.upload.onloadstart = function(e){ actual.push("upload." + e.type); };
+ xhr.upload.onloadend = function(e){ actual.push("upload." + e.type);};
+
+ xhr.open("POST", "./resources/content.py", false);
+ xhr.send();
+
+ assert_equals(xhr.response, "");
+ assert_array_equals(actual, expect);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-sync-response-event-order.htm b/testing/web-platform/tests/XMLHttpRequest/send-sync-response-event-order.htm
new file mode 100644
index 000000000..f7e4b0b21
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-sync-response-event-order.htm
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-event-order.js"></script>
+ <title>XMLHttpRequest: The send() method: event order when synchronous flag is set</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadstart" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol/li[9]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#same-origin-request-steps" data-tested-assertations="following::DL[1]/DT[1]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[11] following::a[contains(@href,'#switch-done')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[3] following::ol[1]/li[4] following::ol[1]/li[6] following::ol[1]/li[7]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following::ol/li[3]" />
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ test(function () {
+ var xhr = new XMLHttpRequest();
+ prepare_xhr_for_event_order_test(xhr);
+
+ xhr.open("POST", "./resources/content.py", false);
+ xhr.send("Test Message");
+
+ assert_equals(xhr.response, "Test Message");
+ assert_xhr_event_order_matches([1, 4, "load(12,12,true)", "loadend(12,12,true)"]);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-sync-timeout.htm b/testing/web-platform/tests/XMLHttpRequest/send-sync-timeout.htm
new file mode 100644
index 000000000..08ce7e9b9
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-sync-timeout.htm
@@ -0,0 +1,30 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: timeout during sync send() should not run</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#same-origin-request-steps" data-tested-assertations="following::DL[1]/DT[1]"/>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test(),
+ hasrun = false
+ test.step(function() {
+ client = new XMLHttpRequest()
+ client.open("GET", "folder.txt", false)
+ setTimeout(function() { test.step(function() { hasrun = true }) }, 0)
+ client.onreadystatechange = function() {
+ test.step(function() {
+ assert_equals(client.readyState, 4)
+ assert_false(hasrun)
+ })
+ }
+ client.send(null)
+ test.done()
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-timeout-events.htm b/testing/web-platform/tests/XMLHttpRequest/send-timeout-events.htm
new file mode 100644
index 000000000..6aea627d6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-timeout-events.htm
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>XMLHttpRequest: The send() method: timeout is not 0 </title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[5] following::a[contains(@href,'#timeout-error')]/.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[6] following::ol[1]/li[7]/ol/li[3] following::ol[1]/li[7]/ol/li[4] following::ol[1]/li[9] following::ol[1]/li[10]" />
+</head>
+
+<body>
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ var test = async_test();
+
+ test.step(function()
+ {
+ var xhr = new XMLHttpRequest();
+ var expect = [4, "", "upload.timeout", "upload.loadend", "timeout", "loadend"];
+ var actual = [];
+
+ xhr.onreadystatechange = test.step_func(function()
+ {
+ if (xhr.readyState == 4)
+ {
+ actual.push(xhr.readyState, xhr.response);
+ }
+ });
+
+ xhr.onloadend = test.step_func_done(function(e)
+ {
+ assert_equals(e.loaded, 0);
+ assert_equals(e.total, 0);
+ actual.push(e.type);
+ assert_array_equals(actual, expect);
+ });
+
+ xhr.ontimeout = test.step_func(function(e)
+ {
+ assert_equals(e.loaded, 0);
+ assert_equals(e.total, 0);
+ actual.push(e.type);
+ });
+
+
+ xhr.upload.onloadend = test.step_func(function(e)
+ {
+ assert_equals(e.loaded, 0);
+ assert_equals(e.total, 0);
+ actual.push("upload." + e.type);
+ });
+
+ xhr.upload.ontimeout = test.step_func(function(e)
+ {
+ assert_equals(e.loaded, 0);
+ assert_equals(e.total, 0);
+ actual.push("upload." + e.type);
+ });
+
+
+ var content = "";
+ for (var i = 0; i < 121026; i++)
+ {
+ content += "[" + i + "]";
+ }
+
+ xhr.open("POST", "./resources/trickle.py", true);
+ xhr.timeout = 1;
+ xhr.send(content);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-usp.html b/testing/web-platform/tests/XMLHttpRequest/send-usp.html
new file mode 100644
index 000000000..1753e5f3a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-usp.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>XMLHttpRequest.send(URLSearchParams)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="send-usp.js"></script>
+<div id="log"></div>
+<script>
+run_test();
+</script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-usp.js b/testing/web-platform/tests/XMLHttpRequest/send-usp.js
new file mode 100644
index 000000000..c00b2e0e0
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-usp.js
@@ -0,0 +1,48 @@
+const NUM_TESTS = 128;
+
+function encode(n) {
+ if (n === 0x20) {
+ return "\x2B";
+ }
+
+ if (n === 0x2A || n === 0x2D || n === 0x2E ||
+ (0x30 <= n && n <= 0x39) || (0x41 <= n && n <= 0x5A) ||
+ n === 0x5F || (0x61 <= n && n <= 0x7A)) {
+ return String.fromCharCode(n);
+ }
+
+ var s = n.toString(16).toUpperCase();
+ return "%" + (s.length === 2 ? s : '0' + s);
+}
+
+function run_test() {
+ var tests = [];
+ var overall_test = async_test("Overall fetch with URLSearchParams");
+ for (var i = 0; i < NUM_TESTS; i++) {
+ // Multiple subtests so that failures can be fine-grained
+ tests[i] = async_test("XMLHttpRequest.send(URLSearchParams) (" + i + ")");
+ }
+
+ // We use a single XHR since this test tends to time out
+ // with 128 consecutive fetches when run in parallel
+ // with many other WPT tests.
+ var x = new XMLHttpRequest();
+ x.onload = overall_test.step_func(function() {
+ var response_split = x.response.split("&");
+ overall_test.done();
+ for (var i = 0; i < NUM_TESTS; i++) {
+ tests[i].step(function() {
+ assert_equals(response_split[i], "a" + i + "="+encode(i));
+ tests[i].done();
+ });
+ }
+ });
+ x.onerror = overall_test.unreached_func();
+
+ x.open("POST", "resources/content.py");
+ var usp = new URLSearchParams();
+ for (var i = 0; i < NUM_TESTS; i++) {
+ usp.append("a" + i, String.fromCharCode(i));
+ }
+ x.send(usp)
+}
diff --git a/testing/web-platform/tests/XMLHttpRequest/send-usp.worker.js b/testing/web-platform/tests/XMLHttpRequest/send-usp.worker.js
new file mode 100644
index 000000000..456b7e7e3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/send-usp.worker.js
@@ -0,0 +1,4 @@
+importScripts("/resources/testharness.js");
+importScripts("send-usp.js");
+run_test();
+done();
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-after-send.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-after-send.htm
new file mode 100644
index 000000000..595214471
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-after-send.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: setRequestHeader() after send()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="/following::ol/li[2]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/delay.py?ms=0")
+ client.onreadystatechange = function() {
+ test.step(function() {
+ assert_throws("InvalidStateError", function() { client.setRequestHeader("x-test", "test") })
+ if(client.readyState == 4)
+ test.done()
+ })
+ }
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-allow-empty-value.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-allow-empty-value.htm
new file mode 100644
index 000000000..bd8709417
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-allow-empty-value.htm
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: setRequestHeader() - empty header</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="/following::ol/li[4]/p[contains(@class,'note')] /following::ol/li[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(value) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/inspect-headers.py?filter_name=X-Empty", false)
+ client.setRequestHeader('X-Empty', value)
+ client.send(null)
+ assert_equals(client.responseText, 'x-empty: '+ String(value).toLowerCase()+'\n' )
+ }, document.title + " (" + value + ")")
+ }
+ request("")
+ request(null)
+ request(undefined)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-allow-whitespace-in-value.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-allow-whitespace-in-value.htm
new file mode 100644
index 000000000..ac54dbddb
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-allow-whitespace-in-value.htm
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: setRequestHeader() - header value with whitespace</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="/following::ol/li[4]/p[contains(@class,'note')] /following::ol/li[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(value) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/inspect-headers.py?filter_name=X-Empty", false)
+ client.setRequestHeader('X-Empty', value)
+ client.send(null)
+ assert_equals(client.responseText, 'x-empty: '+ String(value.trim()).toLowerCase()+'\n' )
+ }, document.title + " (" + value + ")")
+ }
+ request(" ")
+ request(" t")
+ request("t ")
+ request(" t ")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-before-open.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-before-open.htm
new file mode 100644
index 000000000..d90b02eaf
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-before-open.htm
@@ -0,0 +1,18 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: setRequestHeader() before open()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="following::ol/li[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ assert_throws("InvalidStateError", function() { client.setRequestHeader("x-test", "test") })
+ }, 'setRequestHeader invoked before open()')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-bogus-name.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-bogus-name.htm
new file mode 100644
index 000000000..86e55f33a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-bogus-name.htm
@@ -0,0 +1,59 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: setRequestHeader() name argument checks</title>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="/following::ol/li[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+<!--
+ CHAR = <any US-ASCII character (octets 0 - 127)>
+ CTL = <any US-ASCII control character
+ (octets 0 - 31) and DEL (127)>
+ SP = <US-ASCII SP, space (32)>
+ HT = <US-ASCII HT, horizontal-tab (9)>
+ token = 1*<any CHAR except CTLs or separators>
+ separators = "(" | ")" | "<" | ">" | "@"
+ | "," | ";" | ":" | "\" | <">
+ | "/" | "[" | "]" | "?" | "="
+ | "{" | "}" | SP | HT
+ field-name = token
+-->
+ <script>
+ function try_name(name) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "...")
+ assert_throws("SyntaxError", function() { client.setRequestHeader(name, 'x-value') })
+ }, "setRequestHeader should throw with header name " + format_value(invalid_headers[i]) + ".")
+ }
+ function try_byte_string(name) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "...")
+ assert_throws(new TypeError(), function() { client.setRequestHeader(name, 'x-value') })
+ }, "setRequestHeader should throw with header name " + format_value(invalid_byte_strings[i]) + ".")
+ }
+ var invalid_headers = ["(", ")", "<", ">", "@", ",", ";", ":", "\\",
+ "\"", "/", "[", "]", "?", "=", "{", "}", " ",
+ /* HT already tested in the loop below */
+ "\u007f", "", "t\rt", "t\nt", "t: t", "t:t",
+ "t<t", "t t", " tt", ":tt", "\ttt", "\vtt", "t\0t",
+ "t\"t", "t,t", "t;t", "()[]{}", "a?B", "a=B"]
+ var invalid_byte_strings = ["テスト", "X-テスト"]
+ for (var i = 0; i < 32; ++i) {
+ invalid_headers.push(String.fromCharCode(i))
+ }
+ for (var i = 0; i < invalid_headers.length; ++i) {
+ try_name(invalid_headers[i])
+ }
+ for (var i = 0; i < invalid_byte_strings.length; ++i) {
+ try_byte_string(invalid_byte_strings[i])
+ }
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-bogus-value.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-bogus-value.htm
new file mode 100644
index 000000000..c3aa076c9
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-bogus-value.htm
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>XMLHttpRequest: setRequestHeader() value argument checks</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="/following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function try_value(value) {
+ test(function() {
+ var client = new XMLHttpRequest();
+ client.open("GET", "...");
+ assert_throws("SyntaxError", function() { client.setRequestHeader("x-test", value) }, ' given value ' + value+', ');
+ });
+ }
+ try_value("t\rt");
+ try_value("t\nt");
+ try_value("t\bt");
+ try_value("\x7f");
+ test(function() {
+ var client = new XMLHttpRequest();
+ client.open("GET", "...");
+ assert_throws(new TypeError(), function() { client.setRequestHeader("x-test", "テスト") }, ' given value テスト,');
+ });
+
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "...")
+ assert_throws(new TypeError(), function() { client.setRequestHeader("x-test") })
+ }, 'Omitted value argument')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-case-insensitive.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-case-insensitive.htm
new file mode 100644
index 000000000..248306fce
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-case-insensitive.htm
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: setRequestHeader() - headers that differ in case</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="/following::ol/li[6] /following::ol/li[7]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/inspect-headers.py?filter_value=t1,t2,t3", false)
+ client.setRequestHeader("x-test", "t1")
+ client.setRequestHeader("X-TEST", "t2")
+ client.setRequestHeader("X-teST", "t3")
+ client.send(null)
+ assert_equals(client.responseText, "x-test,")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-content-type.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-content-type.htm
new file mode 100644
index 000000000..64a72927a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-content-type.htm
@@ -0,0 +1,237 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: setRequestHeader() - Content-Type header</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="/following::ol/li[4]/p[contains(@class,'note')] /following::ol/li[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(inputGenerator, headersToSend, expectedType, title) {
+ test(function() {
+ try {
+ var toSend = inputGenerator();
+ } catch(e) {
+ assert_unreached("Skipping test as could not create a " + inputGenerator.name.replace("_", "") + "; ");
+ }
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/inspect-headers.py?filter_name=Content-Type", false)
+ for(header in headersToSend) {
+ if (headersToSend.hasOwnProperty(header)) {
+ client.setRequestHeader(header, headersToSend[header]);
+ }
+ }
+ client.send(toSend)
+
+ var responseType = client.responseText.replace("\n", "").replace("; ", ";").toLowerCase(); // don't care about case or space after semicolon for charset
+ if (expectedType === undefined || expectedType === null) {
+ assert_equals(responseType, "");
+ } else if (expectedType instanceof RegExp) {
+ if (!expectedType.ignoreCase) expectedType = new RegExp(expectedType, "i"); // always ignore case; the regex itself will have to remember to handle the optional space after the semicolon for charset
+ assert_regexp_match(responseType, expectedType);
+ } else {
+ expectedType = "content-type: " + String(expectedType ? expectedType.trim().replace("; ", ";") : expectedType).toLowerCase()
+ assert_equals(responseType, expectedType);
+ }
+ }, title)
+ }
+ request(
+ function _String() { return ""; },
+ {"Content-Type": ""},
+ "",
+ 'setRequestHeader("") sends a blank string'
+ )
+ request(
+ function _String() { return ""; },
+ {"Content-Type": " "},
+ " ",
+ 'setRequestHeader(" ") sends the string " "'
+ )
+ request(
+ function _String() { return ""; },
+ {"Content-Type": null},
+ "null",
+ 'setRequestHeader(null) sends the string "null"'
+ )
+ request(
+ function _String() { return ""; },
+ {"Content-Type": undefined},
+ "undefined",
+ 'setRequestHeader(undefined) sends the string "undefined"'
+ )
+ request(
+ function _String() { return "test"; },
+ {},
+ "text/plain;charset=UTF-8",
+ 'String request has correct default Content-Type of "text/plain;charset=UTF-8"'
+ )
+ request(
+ function _String() { return "test()"; },
+ {"Content-Type": "text/javascript;charset=ASCII"},
+ "text/javascript;charset=UTF-8",
+ "String request keeps setRequestHeader() Content-Type, with charset adjusted to UTF-8"
+ )
+ request(
+ function _XMLDocument() { return new DOMParser().parseFromString("<xml/>", "application/xml"); },
+ {"Content-Type": ""},
+ "",
+ 'XML Document request respects setRequestHeader("")'
+ )
+ request(
+ function _XMLDocument() { return new DOMParser().parseFromString("<xml/>", "application/xml"); },
+ {},
+ "application/xml;charset=UTF-8",
+ 'XML Document request has correct default Content-Type of "application/xml;charset=UTF-8"'
+ )
+ request(
+ function _XMLDocument() { return new DOMParser().parseFromString("<xml/>", "application/xml"); },
+ {"Content-Type": "application/xhtml+xml;charset=ASCII"},
+ "application/xhtml+xml;charset=UTF-8",
+ "XML Document request keeps setRequestHeader() Content-Type, with charset adjusted to UTF-8"
+ )
+ request(
+ function _HTMLDocument() { return new DOMParser().parseFromString("<html></html>", "text/html"); },
+ {"Content-Type": ""},
+ "",
+ 'HTML Document request respects setRequestHeader("")'
+ )
+ request(
+ function _HTMLDocument() { return new DOMParser().parseFromString("<html></html>", "text/html"); },
+ {},
+ "text/html;charset=UTF-8",
+ 'HTML Document request has correct default Content-Type of "text/html;charset=UTF-8"'
+ )
+ request(
+ function _HTMLDocument() { return new DOMParser().parseFromString("<html></html>", "text/html"); },
+ {"Content-Type": "text/html+junk;charset=ASCII"},
+ "text/html+junk;charset=UTF-8",
+ "HTML Document request keeps setRequestHeader() Content-Type, with charset adjusted to UTF-8"
+ )
+ request(
+ function _Blob() { return new Blob(["test"]); },
+ {"Content-Type": ""},
+ "",
+ 'Blob request respects setRequestHeader("") to be specified'
+ )
+ request(
+ function _Blob() { return new Blob(["test"]); },
+ {},
+ undefined,
+ "Blob request with unset type sends no Content-Type without setRequestHeader() call"
+ )
+ request(
+ function _Blob() { return new Blob(["test"]); },
+ {"Content-Type": "application/xml;charset=ASCII"},
+ "application/xml;charset=ASCII",
+ "Blob request with unset type keeps setRequestHeader() Content-Type and charset"
+ )
+ request(
+ function _Blob() { return new Blob(["<xml/>"], {type : "application/xml;charset=ASCII"}); },
+ {},
+ "application/xml;charset=ASCII",
+ "Blob request with set type uses that it for Content-Type unless setRequestHeader()"
+ )
+ request(
+ function _Blob() { return new Blob(["<xml/>"], {type : "application/xml;charset=UTF8"}); },
+ {"Content-Type": "application/xml+junk;charset=ASCII"},
+ "application/xml+junk;charset=ASCII",
+ "Blob request with set type keeps setRequestHeader() Content-Type and charset"
+ )
+ request(
+ function _ArrayBuffer() { return new ArrayBuffer(10); },
+ {"Content-Type": ""},
+ "",
+ 'ArrayBuffer request respects setRequestHeader("")'
+ )
+ request(
+ function _ArrayBuffer() { return new ArrayBuffer(10); },
+ {},
+ undefined,
+ "ArrayBuffer request sends no Content-Type without setRequestHeader() call"
+ )
+ request(
+ function _ArrayBuffer() { return new ArrayBuffer(10); },
+ {"Content-Type": "application/xml;charset=ASCII"},
+ "application/xml;charset=ASCII",
+ "ArrayBuffer request keeps setRequestHeader() Content-Type and charset"
+ )
+ request(
+ function _Uint8Array() { return new Uint8Array(new ArrayBuffer(10)); },
+ {"Content-Type": ""},
+ "",
+ 'ArrayBufferView request respects setRequestHeader("")'
+ )
+ request(
+ function _Uint8Array() { return new Uint8Array(new ArrayBuffer(10)); },
+ {},
+ undefined,
+ "ArrayBufferView request sends no Content-Type without setRequestHeader() call"
+ )
+ request(
+ function _Uint8Array() { return new Uint8Array(new ArrayBuffer(10)); },
+ {"Content-Type": "application/xml;charset=ASCII"},
+ "application/xml;charset=ASCII",
+ "ArrayBufferView request keeps setRequestHeader() Content-Type and charset"
+ )
+ request(
+ function _FormData() { return new FormData(); },
+ {"Content-Type": ""},
+ "",
+ 'FormData request respects setRequestHeader("")'
+ )
+ request(
+ function _FormData() { return new FormData(); },
+ {},
+ /multipart\/form-data;boundary=(.*)/,
+ 'FormData request has correct default Content-Type of "multipart\/form-data;boundary=_"'
+ )
+ request(
+ function _FormData() { return new FormData(); },
+ {"Content-Type": "application/xml;charset=ASCII"},
+ "application/xml;charset=ASCII",
+ "FormData request keeps setRequestHeader() Content-Type and charset"
+ )
+ request(
+ function _URLSearchParams() { return new URLSearchParams("q=testQ&topic=testTopic") },
+ {"Content-Type": ""},
+ "",
+ 'URLSearchParams respects setRequestHeader("")'
+ )
+ request(
+ function _URLSearchParams() { return new URLSearchParams("q=testQ&topic=testTopic") },
+ {},
+ "application/x-www-form-urlencoded;charset=UTF-8",
+ 'URLSearchParams request has correct default Content-Type of "application/x-www-form-urlencoded;charset=UTF-8"'
+ )
+ request(
+ function _URLSearchParams() { return new URLSearchParams("q=testQ&topic=testTopic") },
+ {"Content-Type": "application/xml;charset=ASCII"},
+ "application/xml;charset=UTF-8",
+ "URLSearchParams request keeps setRequestHeader() Content-Type, with charset adjusted to UTF-8"
+ // the default Content-Type for URLSearchParams has a charset specified (utf-8) in
+ // https://fetch.spec.whatwg.org/#bodyinit, so the user's must be changed to match it
+ // as per https://xhr.spec.whatwg.org/#the-send%28%29-method step 4.
+ )
+ request(
+ function _ReadableStream() { return new ReadableStream() },
+ {"Content-Type": ""},
+ "",
+ 'ReadableStream request respects setRequestHeader("")'
+ )
+ request(
+ function _ReadableStream() { return new ReadableStream() },
+ {},
+ undefined,
+ "ReadableStream request with under type sends no Content-Type without setRequestHeader() call"
+ )
+ request(
+ function _ReadableStream() { return new ReadableStream() },
+ {"Content-Type": "application/xml;charset=ASCII"},
+ "application/xml;charset=ASCII",
+ "ReadableStream request keeps setRequestHeader() Content-Type and charset"
+ )
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-header-allowed.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-header-allowed.htm
new file mode 100644
index 000000000..31e40df16
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-header-allowed.htm
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: setRequestHeader() - headers that are allowed</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="/following::ol/li[6] /following::ol/li[7]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function request(header) {
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/inspect-headers.py?filter_value=t1,t2", false)
+ client.setRequestHeader(header, "t1")
+ client.setRequestHeader(header, "t2")
+ client.send(null)
+ assert_equals(client.responseText, header.toLowerCase() + ",")
+ }, document.title + " (" + header + ")")
+ }
+ request("Authorization")
+ request("Pragma")
+ request("User-Agent")
+ request("Content-Transfer-Encoding")
+ request("Content-Type")
+ request("Overwrite")
+ request("If")
+ request("Status-URI")
+ request("X-Pink-Unicorn")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-header-forbidden.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-header-forbidden.htm
new file mode 100644
index 000000000..b6873216f
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-header-forbidden.htm
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: setRequestHeader() - headers that are forbidden</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="/following::ol/li[5]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("POST", "resources/inspect-headers.py?filter_value=TEST", false)
+ client.setRequestHeader("Accept-Charset", "TEST")
+ client.setRequestHeader("Accept-Encoding", "TEST")
+ client.setRequestHeader("Connection", "TEST")
+ client.setRequestHeader("Content-Length", "TEST")
+ client.setRequestHeader("Cookie", "TEST")
+ client.setRequestHeader("Cookie2", "TEST")
+ client.setRequestHeader("Date", "TEST")
+ client.setRequestHeader("DNT", "TEST")
+ client.setRequestHeader("Expect", "TEST")
+ client.setRequestHeader("Host", "TEST")
+ client.setRequestHeader("Keep-Alive", "TEST")
+ client.setRequestHeader("Referer", "TEST")
+ client.setRequestHeader("TE", "TEST")
+ client.setRequestHeader("Trailer", "TEST")
+ client.setRequestHeader("Transfer-Encoding", "TEST")
+ client.setRequestHeader("Upgrade", "TEST")
+ client.setRequestHeader("Via", "TEST")
+ client.setRequestHeader("Proxy-", "TEST")
+ client.setRequestHeader("Proxy-Authorization", "TEST")
+ client.setRequestHeader("Sec-", "TEST")
+ client.setRequestHeader("Sec-X", "TEST")
+ client.send(null)
+ assert_equals(client.responseText, "")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/setrequestheader-open-setrequestheader.htm b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-open-setrequestheader.htm
new file mode 100644
index 000000000..564819044
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/setrequestheader-open-setrequestheader.htm
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!--
+Test from https://bugzilla.mozilla.org/show_bug.cgi?id=819051
+-->
+<head>
+ <title>XMLHttpRequest: setRequestHeader() and open()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::OL[1]/LI[14]/ul[1]/li[4]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="following::OL[1]/LI[6] following::ol[1]/li[7]" />
+</head>
+<body>
+ <p id="log"></p>
+<script type="text/javascript">
+var test = async_test();
+
+var url = "resources/inspect-headers.py";
+
+var xhr = new XMLHttpRequest();
+xhr.open("GET", url + "?filter_name=x-appended-to-this");
+xhr.setRequestHeader("X-appended-to-this", "False");
+xhr.open("GET", url + "?filter_name=x-appended-to-this");
+xhr.setRequestHeader("X-appended-to-this", "True");
+
+xhr.onreadystatechange = function() {
+ if (this.readyState == 4) {
+ test.step(function (){
+ assert_equals(xhr.responseText, "x-appended-to-this: True\n", "Set headers record should have been cleared by open.");
+ test_standard_header();
+ });
+ }
+}
+
+xhr.send();
+
+function test_standard_header () {
+ var header_tested = "Accept";
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url + "?filter_name=accept");
+ xhr.setRequestHeader("Accept", "foo/bar");
+ xhr.open("GET", url + "?filter_name=accept");
+ xhr.setRequestHeader("Accept", "bar/foo");
+
+ xhr.onreadystatechange = function() {
+ if (this.readyState == 4) {
+ test.step(function (){
+ assert_equals(xhr.responseText, "accept: bar/foo\n", "Set headers record should have been cleared by open.");
+ test.done();
+ });
+ }
+ }
+
+ xhr.send();
+}
+
+
+</script>
+</pre>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/XMLHttpRequest/status-async.htm b/testing/web-platform/tests/XMLHttpRequest/status-async.htm
new file mode 100644
index 000000000..dcf7d6246
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/status-async.htm
@@ -0,0 +1,62 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: status/statusText - various responses</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol/li[1] following::ol/li[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-statustext-attribute" data-tested-assertations="following::ol/li[1] following::ol/li[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-getresponseheader()-method" data-tested-assertations="following::ol/li[5]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var counter=0
+ function statusRequest(method, code, text, content, type) {
+ counter++
+ var test = async_test(document.title +' '+ counter+" (" + method + " " + code + ")")
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function(e) {
+ test.step(function() {
+ if(client.readyState > 1) {
+ assert_equals(client.status, code)
+ assert_equals(client.statusText, text)
+ assert_equals(client.getResponseHeader("X-Request-Method"), method)
+ if(client.readyState == 4) {
+ if(method != "HEAD") {
+ if(type == "text/xml") {
+ assert_equals(client.responseXML.documentElement.localName, "x")
+ }
+ assert_equals(client.responseText, content)
+ }
+ test.done()
+ }
+ }else{
+ assert_equals(client.status, 0)
+ assert_equals(client.statusText, "")
+ }
+ }, this)
+ }
+ client.open(method, "resources/status.py?code=" + encodeURIComponent(code) + "&text=" + text + "&content=" + encodeURIComponent(content) + "&type=" + encodeURIComponent(type))
+ client.send(null)
+ })
+ }
+ function status(code, text, content, type) {
+ statusRequest("GET", code, text, content, type)
+ statusRequest("HEAD", code, text, content, type)
+ statusRequest("CHICKEN", code, text, content, type)
+ }
+ status(204, "UNICORNSWIN", "", "")
+ status(401, "OH HELLO", "Not today.", "")
+ status(402, "FIVE BUCKS", "<x>402<\/x>", "text/xml")
+ status(402, "FREE", "Nice!", "text/doesnotmatter")
+ status(402, "402 TEH AWESOME", "", "")
+ status(502, "YO", "", "")
+ status(502, "lowercase", "SWEET POTATO", "text/plain")
+ status(503, "HOUSTON WE HAVE A", "503", "text/plain")
+ status(699, "WAY OUTTA RANGE", "699", "text/plain")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/status-basic.htm b/testing/web-platform/tests/XMLHttpRequest/status-basic.htm
new file mode 100644
index 000000000..fed7cabec
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/status-basic.htm
@@ -0,0 +1,51 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: status/statusText - various responses</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol/li[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-statustext-attribute" data-tested-assertations="following::ol/li[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-getresponseheader()-method" data-tested-assertations="following::ol/li[5]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol/li[4]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var counter = 0
+ function statusRequest(method, code, text, content, type) {
+ counter++
+ test(function() {
+ var client = new XMLHttpRequest()
+ assert_equals(client.status, 0);
+ client.open(method, "resources/status.py?code=" + code + "&text=" + encodeURIComponent(text) + "&content=" + encodeURIComponent(content) + "&type=" + encodeURIComponent(type), false)
+ assert_equals(client.status, 0);
+ client.send(null)
+ assert_equals(client.status, code)
+ assert_equals(client.statusText, text)
+ assert_equals(client.getResponseHeader("X-Request-Method"), method)
+ if(method != "HEAD") {
+ if(type == "text/xml") {
+ assert_equals(client.responseXML.documentElement.localName, "x")
+ }
+ assert_equals(client.responseText, content)
+ }
+ }, document.title + " " + counter + " (" + method + " " + code + ")")
+ }
+ function status(code, text, content, type) {
+ statusRequest("GET", code, text, content, type)
+ statusRequest("HEAD", code, text, content, type)
+ statusRequest("CHICKEN", code, text, content, type)
+ }
+ status(204, "UNICORNSWIN", "", "")
+ status(401, "OH HELLO", "Not today.", "")
+ status(402, "FIVE BUCKS", "<x>402<\/x>", "text/xml")
+ status(402, "FREE", "Nice!", "text/doesnotmatter")
+ status(402, "402 TEH AWESOME", "", "")
+ status(502, "YO", "", "")
+ status(502, "lowercase", "SWEET POTATO", "text/plain")
+ status(503, "HOUSTON WE HAVE A", "503", "text/plain")
+ status(699, "WAY OUTTA RANGE", "699", "text/plain")
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/status-error.htm b/testing/web-platform/tests/XMLHttpRequest/status-error.htm
new file mode 100644
index 000000000..fbcb7fd75
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/status-error.htm
@@ -0,0 +1,60 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: status error handling</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onerror" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="/following::ol/li[3]" />
+ </head>
+ <body>
+ <p>This shouldn't be tested inside a tunnel.</p>
+ <div id="log"></div>
+ <script>
+ function noError(method, code) {
+ var test = async_test(document.title + " " + method + " " + code)
+
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.open(method, "resources/status.py?code=" + code, true)
+
+ client.onreadystatechange = test.step_func(function() {
+ assert_equals(client.response, "", "response data")
+ assert_equals(client.status, code, "response status")
+
+ if (client.readyState == client.DONE)
+ /* Give extra time for a bogus error event to pop up */
+ setTimeout(test.step_func(function() { test.done() } ), 100)
+ })
+ client.onerror = test.step_func(function() {
+ assert_unreached("HTTP error should not throw error event")
+ })
+ client.send()
+ })
+ }
+
+ noError('GET', 200)
+ noError('GET', 400)
+ noError('GET', 401)
+ noError('GET', 404)
+ noError('GET', 410)
+ noError('GET', 500)
+ noError('GET', 699)
+
+ noError('HEAD', 200)
+ noError('HEAD', 404)
+ noError('HEAD', 500)
+ noError('HEAD', 699)
+
+ noError('POST', 200)
+ noError('POST', 404)
+ noError('POST', 500)
+ noError('POST', 699)
+
+ noError('PUT', 200)
+ noError('PUT', 404)
+ noError('PUT', 500)
+ noError('PUT', 699)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/timeout-cors-async.htm b/testing/web-platform/tests/XMLHttpRequest/timeout-cors-async.htm
new file mode 100644
index 000000000..35e2a30ba
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/timeout-cors-async.htm
@@ -0,0 +1,43 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: timeout event and cross-origin request</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[4] following::ol[1]/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#cross-origin-request-event-rules" data-tested-assertations="following::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test(document.title)
+ var client = new XMLHttpRequest()
+ var gotTimeout = false
+ client.open("GET", "http://www2." + location.hostname + (location.port ? ":" + location.port : "") +(location.pathname.replace(/[^\/]+$/, '')+'resources/corsenabled.py')+"?delay=2&code=200")
+ client.timeout = 100
+ client.addEventListener('timeout', function (e) {
+ test.step(function() {
+ assert_equals(e.type, 'timeout')
+ assert_equals(client.status, 0)
+ gotTimeout = true
+ })
+ })
+ client.addEventListener('load', function (e) {
+ test.step(function() {
+ assert_unreached('load event should not fire')
+ })
+ })
+ client.addEventListener('loadend', function (e) {
+ test.step(function() {
+ assert_true(gotTimeout, "timeout event should fire")
+ test.done()
+ })
+ })
+
+ client.send(null)
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/timeout-sync.htm b/testing/web-platform/tests/XMLHttpRequest/timeout-sync.htm
new file mode 100644
index 000000000..9815532c7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/timeout-sync.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: timeout not allowed for sync requests</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[10]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open('GET', 'folder.txt', false)
+ assert_throws("InvalidAccessError", function() { client.timeout = 1000 })
+ }, 'setting timeout attribute on sync request')
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.timeout = 1000
+ assert_throws("InvalidAccessError", function() { client.open('GET', 'folder.txt', false) })
+ }, 'open() with async false when timeout is set')
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-basic.htm b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-basic.htm
new file mode 100644
index 000000000..c48b610ff
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-basic.htm
@@ -0,0 +1,45 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: prototype and members</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest" data-tested-assertations="following::ol/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#xmlhttprequest" data-tested-assertations="." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#states" data-tested-assertations="following::dfn[2] following::dfn[3] following::dfn[4] following::dfn[5] following::dfn[6]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ XMLHttpRequest.prototype.test = function() { return "TEH" }
+ var client = new XMLHttpRequest()
+ assert_equals(client.test(), "TEH")
+ var members = ["onreadystatechange",
+ "open",
+ "setRequestHeader",
+ "send",
+ "abort",
+ "status",
+ "statusText",
+ "getResponseHeader",
+ "getAllResponseHeaders",
+ "responseText",
+ "responseXML"]
+ for(var x in members)
+ assert_true(members[x] in client, members[x])
+ var constants = ["UNSENT",
+ "OPENED",
+ "HEADERS_RECEIVED",
+ "LOADING",
+ "DONE"],
+ i = 0
+ for(var x in constants) {
+ assert_equals(client[constants[x]], i, constants[x])
+ assert_equals(XMLHttpRequest[constants[x]], i, "XHR " + constants[x])
+ i++
+ }
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-eventtarget.htm b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-eventtarget.htm
new file mode 100644
index 000000000..ea58fd4dc
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-eventtarget.htm
@@ -0,0 +1,48 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: implements EventTarget</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#xmlhttprequesteventtarget" data-tested-assertations=".." />
+ <!-- Obviously, most of the stuff actually being tested here is covered in the DOM events spec, not in the XHR spec -->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test(),
+ x = null,
+ expected = ["a1", "b1", "c1", "a2", "b2", "c2", "a3", "c3", "a4", "c4"],
+ result = []
+ function callback(e) {
+ result.push("b" + x.readyState)
+ test.step(function() {
+ if(x.readyState == 3)
+ assert_unreached()
+ })
+ }
+ test.step(function() {
+ x = new XMLHttpRequest()
+ x.onreadystatechange = function() {
+ test.step(function() {
+ result.push("a" + x.readyState)
+ })
+ }
+ x.addEventListener("readystatechange", callback, false)
+ x.addEventListener("readystatechange", function() {
+ test.step(function() {
+ result.push("c" + x.readyState)
+ if(x.readyState == 2)
+ x.removeEventListener("readystatechange", callback, false)
+ if(x.readyState == 4) {
+ assert_array_equals(result, expected)
+ test.done()
+ }
+ })
+ }, false)
+ x.open("GET", "folder.txt")
+ x.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-network-error-sync.htm b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-network-error-sync.htm
new file mode 100644
index 000000000..c4a887a1e
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-network-error-sync.htm
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: members during network errors (sync)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/p[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#network-error" data-tested-assertations=".." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[5]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-statustext-attribute" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-getresponseheader()-method" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-getallresponseheaders()-method" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol[1]/li[2] following::ol[1]/li[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol[1]/li[2] following::ol[1]/li[3]" />
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ client.open("GET", "resources/infinite-redirects.py", false)
+ assert_throws("NetworkError", function() { client.send(null) }, "send")
+ assert_equals(client.status, 0, "status")
+ assert_equals(client.statusText, "", "statusText")
+ assert_equals(client.getAllResponseHeaders(), "", "getAllResponseHeaders")
+ assert_equals(client.getResponseHeader("content-type"), null, "getResponseHeader")
+ assert_equals(client.responseText, "", "responseText")
+ assert_equals(client.responseXML, null, "responseXML")
+ assert_equals(client.readyState, client.DONE, "readyState")
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-network-error.htm b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-network-error.htm
new file mode 100644
index 000000000..c8e320080
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-network-error.htm
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>XMLHttpRequest: members during network errors</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/ol/li[1] following::dl[1]/dd[2]/ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-statustext-attribute" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-getresponseheader()-method" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-getallresponseheaders()-method" data-tested-assertations="following::ol[1]/li[1] following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol[1]/li[2] following::ol[1]/li[3]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol[1]/li[2] following::ol[1]/li[3]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onreadystatechange = function() {
+ test.step(function() {
+ assert_equals(client.status, 0, "status")
+ assert_equals(client.statusText, "", "statusText")
+ assert_equals(client.getAllResponseHeaders(), "", "getAllResponseHeaders")
+ assert_equals(client.getResponseHeader("content-type"), null, "getResponseHeader")
+ assert_equals(client.responseText, "", "responseText")
+ assert_equals(client.responseXML, null, "responseXML")
+ if(client.readyState == 4)
+ test.done()
+ })
+ }
+ client.open("GET", "resources/infinite-redirects.py")
+ client.send(null)
+ })
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-defer-scripts-subframe.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-defer-scripts-subframe.html
new file mode 100644
index 000000000..be46a12b6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-defer-scripts-subframe.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script>
+ var x = 0;
+</script>
+<!-- This script's URI is:
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'data:text/plain,aaa', false);
+ xhr.send();
+ x=1;
+ -->
+<script defer src="data:application/javascript,var%20x%20=%200;%20var%20xhr%20=%20new%20XMLHttpRequest();%20xhr.open('GET',%20'data:text/plain,aaa',%20false);%20xhr.send();%20x=1"></script>
+
+<!-- This script's URI is:
+ parent.postMessage(x, '*');
+-->
+<script defer src="data:application/javascript,parent.postMessage(x, '*');"></script>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-defer-scripts.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-defer-scripts.html
new file mode 100644
index 000000000..0aabdd4b3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-defer-scripts.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check that a sync XHR in a defer script blocks later defer scripts from running</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<!--
+ We run the test in a subframe, because something in the testharness stuff
+ interferes with defer scripts -->
+<script>
+ var t = async_test();
+ onmessage = t.step_func_done(function(e) {
+ assert_equals(e.data, 1);
+ });
+</script>
+<iframe src="xmlhttprequest-sync-block-defer-scripts-subframe.html"></iframe>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-scripts.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-scripts.html
new file mode 100644
index 000000000..d6714ac75
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-block-scripts.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check that while a sync XHR is in flight async script loads don't complete and run script</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<body>
+<script>
+var scriptRan = false;
+var onloadFired = false;
+test(function() {
+ var s = document.createElement("script");
+ s.src = "data:application/javascript,scriptRan = true;";
+ s.onload = function() { onloadFired = true; }
+ document.body.appendChild(s);
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", "data:,", false);
+ xhr.send();
+ assert_false(scriptRan, "Script should not have run");
+ assert_false(onloadFired, "load event for <script> should not have fired");
+});
+</script>
+</body>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader-subframe.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader-subframe.html
new file mode 100644
index 000000000..aeff2af97
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader-subframe.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script>
+ function secondScriptRan() {
+ parent.postMessage("done", "*");
+ }
+
+ function createSecondScript() {
+ var script = document.createElement("script");
+ script.src = "data:application/javascript,secondScriptRan()";
+ document.head.appendChild(script);
+
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", "data:,", false);
+ xhr.send();
+ }
+</script>
+<script src="data:application/javascript,createSecondScript()" defer></script>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader.html
new file mode 100644
index 000000000..bbec1eddc
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Ensure that an async script added during a defer script that then does a
+ sync XHR still runs</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<!--
+ We run the test in a subframe, because something in the testharness stuff
+ interferes with defer scripts -->
+<script>
+ var t = async_test();
+ onmessage = t.step_func_done(function(e) {
+ assert_equals(e.data, "done");
+ });
+</script>
+<iframe src="xmlhttprequest-sync-not-hang-scriptloader-subframe.html"></iframe>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-aborted.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-aborted.html
new file mode 100644
index 000000000..0af6d9cf6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-aborted.html
@@ -0,0 +1,26 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4] following-sibling::ol/li[4]/ol/li[5]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following-sibling::ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#abort-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-abort" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-timeout" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in async cases in document (i.e. non-worker) context.</p>
+ <div id="log"></div>
+ <script src="resources/xmlhttprequest-timeout-aborted.js" type="text/javascript"></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-abortedonmain.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-abortedonmain.html
new file mode 100644
index 000000000..70cba4980
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-abortedonmain.html
@@ -0,0 +1,23 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4] following-sibling::ol/li[4]/ol/li[5]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#abort-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-abort" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol/li[9]"/>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in async cases in document (i.e. non-worker) context.</p>
+ <div id="log"></div>
+ <script src="resources/xmlhttprequest-timeout-abortedonmain.js" type="text/javascript"></script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-overrides.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-overrides.html
new file mode 100644
index 000000000..61a32bb1a
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-overrides.html
@@ -0,0 +1,23 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[9]"/>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in async cases in document (i.e. non-worker) context.</p>
+ <div id="log"></div>
+ <script src="resources/xmlhttprequest-timeout-overrides.js"></script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-overridesexpires.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-overridesexpires.html
new file mode 100644
index 000000000..d29cbbbff
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-overridesexpires.html
@@ -0,0 +1,23 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in async cases in document (i.e. non-worker) context.</p>
+ <div id="log"></div>
+ <script src="resources/xmlhttprequest-timeout-overridesexpires.js" type="text/javascript"></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-simple.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-simple.html
new file mode 100644
index 000000000..982cf5529
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-simple.html
@@ -0,0 +1,24 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in async cases in document (i.e. non-worker) context.</p>
+ <div id="log"></div>
+ <script src="resources/xmlhttprequest-timeout-simple.js"></script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-synconmain.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-synconmain.html
new file mode 100644
index 000000000..79430a9d3
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-synconmain.html
@@ -0,0 +1,21 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol[1]/li[10]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in async cases in document (i.e. non-worker) context.</p>
+ <div id="log"></div>
+ <script src="resources/xmlhttprequest-timeout-synconmain.js" type="text/javascript"></script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-twice.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-twice.html
new file mode 100644
index 000000000..1423fd5db
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-twice.html
@@ -0,0 +1,25 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in async cases in document (i.e. non-worker) context.</p>
+ <div id="log"></div>
+ <script src="resources/xmlhttprequest-timeout-twice.js" type="text/javascript"></script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-aborted.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-aborted.html
new file mode 100644
index 000000000..c3a4581f7
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-aborted.html
@@ -0,0 +1,28 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests in Worker</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4] following-sibling::ol/li[4]/ol/li[5]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following-sibling::ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#abort-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-abort" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-timeout" data-tested-assertations="../.." />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in in a worker context.</p>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var worker = new Worker("resources/xmlhttprequest-timeout-aborted.js");
+ worker.addEventListener("message", testResultCallbackHandler);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-overrides.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-overrides.html
new file mode 100644
index 000000000..bf77d859c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-overrides.html
@@ -0,0 +1,24 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests in Worker</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[9]"/>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in in a worker context.</p>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var worker = new Worker("resources/xmlhttprequest-timeout-overrides.js");
+ worker.addEventListener("message", testResultCallbackHandler);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-overridesexpires.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-overridesexpires.html
new file mode 100644
index 000000000..180db52ea
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-overridesexpires.html
@@ -0,0 +1,25 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests in Worker</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in in a worker context.</p>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var worker = new Worker("resources/xmlhttprequest-timeout-overridesexpires.js");
+ worker.addEventListener("message", testResultCallbackHandler);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-simple.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-simple.html
new file mode 100644
index 000000000..135691fbd
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-simple.html
@@ -0,0 +1,26 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests in Worker</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in in a worker context.</p>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var worker = new Worker("resources/xmlhttprequest-timeout-simple.js");
+ worker.onmessage = testResultCallbackHandler;
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-synconworker.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-synconworker.html
new file mode 100644
index 000000000..423dcc93c
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-synconworker.html
@@ -0,0 +1,25 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests in Worker</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in in a worker context.</p>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var worker = new Worker("resources/xmlhttprequest-timeout-synconworker.js");
+ worker.addEventListener("message", testResultCallbackHandler);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-twice.html b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-twice.html
new file mode 100644
index 000000000..7e7107d4b
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-timeout-worker-twice.html
@@ -0,0 +1,26 @@
+ <!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>XHR2 Timeout Property Tests in Worker</title>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-timeout-attribute" data-tested-assertations="following::ol[1]/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-ontimeout" data-tested-assertations="../.."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#timeout-error" data-tested-assertations=".."/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#request-error" data-tested-assertations="following::ol[1]/li[9]"/>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/.. following-sibling::dl//code[contains(@title,'dom-XMLHttpRequest-timeout')]/../following-sibling::dd following::dt[1] following::dd[1]" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/xmlhttprequest-timeout-runner.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates that the XHR2 timeout property behaves as expected in in a worker context.</p>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var worker = new Worker("resources/xmlhttprequest-timeout-twice.js");
+ worker.addEventListener("message", testResultCallbackHandler);
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-unsent.htm b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-unsent.htm
new file mode 100644
index 000000000..a343b76e6
--- /dev/null
+++ b/testing/web-platform/tests/XMLHttpRequest/xmlhttprequest-unsent.htm
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>XMLHttpRequest: members during UNSENT</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-unsent" data-tested-assertations=".. following::dd" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-xmlhttprequest-setrequestheader" data-tested-assertations="following::ol/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-status-attribute" data-tested-assertations="following::ol/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-statustext-attribute" data-tested-assertations="following::ol/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-getresponseheader()-method" data-tested-assertations="following::ol/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-getallresponseheaders()-method" data-tested-assertations="following::ol/li[1]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetext-attribute" data-tested-assertations="following::ol/li[2]" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol/li[2]" />
+
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var client = new XMLHttpRequest()
+ assert_throws("InvalidStateError", function() { client.setRequestHeader("x-test", "test") }, "setRequestHeader")
+ assert_throws("InvalidStateError", function() { client.send(null) }, "send")
+ assert_equals(client.status, 0, "status")
+ assert_equals(client.statusText, "", "statusText")
+ assert_equals(client.getAllResponseHeaders(), "", "getAllResponseHeaders")
+ assert_equals(client.getResponseHeader("x-test"), null, "getResponseHeader")
+ assert_equals(client.responseText, "", "responseText")
+ assert_equals(client.responseXML, null, "responseXML")
+
+ assert_equals(client.readyState, client.UNSENT, "readyState")
+ })
+ </script>
+ </body>
+</html>