summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/eventsource
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/eventsource
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/eventsource')
-rw-r--r--testing/web-platform/tests/eventsource/META.yml6
-rw-r--r--testing/web-platform/tests/eventsource/README.md4
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close.htm24
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close.js9
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close2.htm23
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close2.js3
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-no-new.any.js7
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm34
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.js10
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-url-bogus.js7
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-eventtarget.worker.js11
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onmesage.js9
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onmessage.htm24
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onopen.htm27
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onopen.js9
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-prototype.htm25
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-prototype.js8
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-url.htm25
-rw-r--r--testing/web-platform/tests/eventsource/dedicated-worker/eventsource-url.js7
-rw-r--r--testing/web-platform/tests/eventsource/event-data.any.js21
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-close.window.js70
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-constructor-document-domain.window.js18
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-constructor-empty-url.any.js6
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-constructor-non-same-origin.window.js21
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-constructor-stringify.window.js28
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-constructor-url-bogus.any.js8
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-constructor-url-multi-window.htm37
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-cross-origin.window.js51
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-eventtarget.any.js16
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-onmessage-realm.htm25
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-onmessage-trusted.any.js12
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-onmessage.any.js14
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-onopen.any.js17
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-prototype.any.js10
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-reconnect.window.js47
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-request-cancellation.any.window.js21
-rw-r--r--testing/web-platform/tests/eventsource/eventsource-url.any.js8
-rw-r--r--testing/web-platform/tests/eventsource/format-bom-2.any.js24
-rw-r--r--testing/web-platform/tests/eventsource/format-bom.any.js24
-rw-r--r--testing/web-platform/tests/eventsource/format-comments.any.js16
-rw-r--r--testing/web-platform/tests/eventsource/format-data-before-final-empty-line.any.js17
-rw-r--r--testing/web-platform/tests/eventsource/format-field-data.any.js23
-rw-r--r--testing/web-platform/tests/eventsource/format-field-event-empty.any.js13
-rw-r--r--testing/web-platform/tests/eventsource/format-field-event.any.js15
-rw-r--r--testing/web-platform/tests/eventsource/format-field-id-2.any.js25
-rw-r--r--testing/web-platform/tests/eventsource/format-field-id-3.window.js56
-rw-r--r--testing/web-platform/tests/eventsource/format-field-id-null.window.js25
-rw-r--r--testing/web-platform/tests/eventsource/format-field-id.any.js21
-rw-r--r--testing/web-platform/tests/eventsource/format-field-parsing.any.js14
-rw-r--r--testing/web-platform/tests/eventsource/format-field-retry-bogus.any.js19
-rw-r--r--testing/web-platform/tests/eventsource/format-field-retry-empty.any.js13
-rw-r--r--testing/web-platform/tests/eventsource/format-field-retry.any.js21
-rw-r--r--testing/web-platform/tests/eventsource/format-field-unknown.any.js13
-rw-r--r--testing/web-platform/tests/eventsource/format-leading-space.any.js14
-rw-r--r--testing/web-platform/tests/eventsource/format-mime-bogus.any.js25
-rw-r--r--testing/web-platform/tests/eventsource/format-mime-trailing-semicolon.any.js20
-rw-r--r--testing/web-platform/tests/eventsource/format-mime-valid-bogus.any.js24
-rw-r--r--testing/web-platform/tests/eventsource/format-newlines.any.js13
-rw-r--r--testing/web-platform/tests/eventsource/format-null-character.any.js17
-rw-r--r--testing/web-platform/tests/eventsource/format-utf-8.any.js12
-rw-r--r--testing/web-platform/tests/eventsource/request-accept.any.js13
-rw-r--r--testing/web-platform/tests/eventsource/request-cache-control.any.js35
-rw-r--r--testing/web-platform/tests/eventsource/request-credentials.any.window.js37
-rw-r--r--testing/web-platform/tests/eventsource/request-redirect.any.window.js24
-rw-r--r--testing/web-platform/tests/eventsource/request-status-error.window.js27
-rw-r--r--testing/web-platform/tests/eventsource/resources/accept.event_stream2
-rw-r--r--testing/web-platform/tests/eventsource/resources/cache-control.event_stream2
-rw-r--r--testing/web-platform/tests/eventsource/resources/cors-cookie.py31
-rw-r--r--testing/web-platform/tests/eventsource/resources/cors.py36
-rw-r--r--testing/web-platform/tests/eventsource/resources/eventsource-onmessage-realm.htm2
-rw-r--r--testing/web-platform/tests/eventsource/resources/init.htm9
-rw-r--r--testing/web-platform/tests/eventsource/resources/last-event-id.py9
-rw-r--r--testing/web-platform/tests/eventsource/resources/last-event-id2.py23
-rw-r--r--testing/web-platform/tests/eventsource/resources/message.py14
-rw-r--r--testing/web-platform/tests/eventsource/resources/message2.py33
-rw-r--r--testing/web-platform/tests/eventsource/resources/reconnect-fail.py24
-rw-r--r--testing/web-platform/tests/eventsource/resources/status-error.py15
-rw-r--r--testing/web-platform/tests/eventsource/resources/status-reconnect.py21
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-close.htm24
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-close.js12
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.htm34
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.js13
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-url-bogus.js10
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-eventtarget.htm24
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-eventtarget.js13
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-onmesage.js12
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-onmessage.htm24
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-onopen.htm27
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-onopen.js12
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-prototype.htm25
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-prototype.js11
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-url.htm25
-rw-r--r--testing/web-platform/tests/eventsource/shared-worker/eventsource-url.js10
93 files changed, 1799 insertions, 0 deletions
diff --git a/testing/web-platform/tests/eventsource/META.yml b/testing/web-platform/tests/eventsource/META.yml
new file mode 100644
index 0000000000..92f1036338
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/META.yml
@@ -0,0 +1,6 @@
+spec: https://html.spec.whatwg.org/multipage/server-sent-events.html
+suggested_reviewers:
+ - zqzhang
+ - odinho
+ - Yaffle
+ - annevk
diff --git a/testing/web-platform/tests/eventsource/README.md b/testing/web-platform/tests/eventsource/README.md
new file mode 100644
index 0000000000..e19a0ba6c7
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/README.md
@@ -0,0 +1,4 @@
+These are the Server-sent events (`EventSource`) tests for the
+[Server-sent events chapter of the HTML Standard](https://html.spec.whatwg.org/multipage/comms.html#server-sent-events).
+
+IDL tests are part of the `/html/dom/idlharness.*` resources.
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close.htm b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close.htm
new file mode 100644
index 0000000000..f26aaaa4a9
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close.htm
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>dedicated worker - EventSource: close()</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 worker = new Worker('eventsource-close.js')
+ worker.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_equals(e.data[1], EventSource.CLOSED, 'this.readyState')
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close.js
new file mode 100644
index 0000000000..875c9098ba
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close.js
@@ -0,0 +1,9 @@
+try {
+ var source = new EventSource("../resources/message.py")
+ source.onopen = function(e) {
+ this.close()
+ postMessage([true, this.readyState])
+ }
+} catch(e) {
+ postMessage([false, String(e)])
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close2.htm b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close2.htm
new file mode 100644
index 0000000000..34e07a2694
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close2.htm
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+ <head>
+ <title>dedicated worker - EventSource created after: worker.close()</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 worker = new Worker('eventsource-close2.js')
+ worker.onmessage = function(e) {
+ test.step(function() {
+ assert_equals(e.data, EventSource.CONNECTING, 'this.readyState')
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close2.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close2.js
new file mode 100644
index 0000000000..4a9cbd20b8
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-close2.js
@@ -0,0 +1,3 @@
+self.close()
+var source = new EventSource("../resources/message.py")
+postMessage(source.readyState) \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-no-new.any.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-no-new.any.js
new file mode 100644
index 0000000000..48bc551130
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-no-new.any.js
@@ -0,0 +1,7 @@
+test(function() {
+ assert_throws_js(TypeError,
+ function() {
+ EventSource('');
+ },
+ "Calling EventSource constructor without 'new' must throw");
+})
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm
new file mode 100644
index 0000000000..b49d7ed609
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>dedicated worker - EventSource: constructor (act as if there is a network error)</title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function fetchFail(url) {
+ var test = async_test(document.title + " (" + url + ")")
+ test.step(function() {
+ var worker = new Worker('eventsource-constructor-non-same-origin.js#'+encodeURIComponent(url))
+ worker.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_equals(e.data[1], EventSource.CLOSED, 'source.readyState')
+ assert_false(e.data[2], "'data' in e");
+ })
+ test.done()
+ }
+ })
+ }
+ fetchFail("ftp://example.not/")
+ fetchFail("about:blank")
+ fetchFail("mailto:whatwg@awesome.example")
+ fetchFail("javascript:alert('FAIL')")
+ </script>
+ <!-- This tests "fails the connection" as well as making sure a simple
+ event is dispatched and not a MessageEvent -->
+ </body>
+</html>
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.js
new file mode 100644
index 0000000000..5ec25a0678
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.js
@@ -0,0 +1,10 @@
+try {
+ var url = decodeURIComponent(location.hash.substr(1))
+ var source = new EventSource(url)
+ source.onerror = function(e) {
+ postMessage([true, this.readyState, 'data' in e])
+ this.close();
+ }
+} catch(e) {
+ postMessage([false, String(e)])
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-url-bogus.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-url-bogus.js
new file mode 100644
index 0000000000..2a450a3463
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-constructor-url-bogus.js
@@ -0,0 +1,7 @@
+try {
+ var source = new EventSource("http://this is invalid/")
+ postMessage([false, 'no exception thrown'])
+ source.close()
+} catch(e) {
+ postMessage([true, e.code])
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-eventtarget.worker.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-eventtarget.worker.js
new file mode 100644
index 0000000000..73b30556c4
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-eventtarget.worker.js
@@ -0,0 +1,11 @@
+importScripts("/resources/testharness.js");
+
+async_test(function() {
+ var source = new EventSource("../resources/message.py")
+ source.addEventListener("message", this.step_func_done(function(e) {
+ assert_equals(e.data, 'data');
+ source.close();
+ }), false)
+}, "dedicated worker - EventSource: addEventListener()");
+
+done();
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onmesage.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onmesage.js
new file mode 100644
index 0000000000..9629f5e793
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onmesage.js
@@ -0,0 +1,9 @@
+try {
+ var source = new EventSource("../resources/message.py")
+ source.onmessage = function(e) {
+ postMessage([true, e.data])
+ this.close()
+ }
+} catch(e) {
+ postMessage([false, String(e)])
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onmessage.htm b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onmessage.htm
new file mode 100644
index 0000000000..c61855f524
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onmessage.htm
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>dedicated worker - EventSource: onmessage</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 worker = new Worker('eventsource-onmesage.js')
+ worker.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_equals(e.data[1], "data", 'e.data')
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onopen.htm b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onopen.htm
new file mode 100644
index 0000000000..010b0c66a8
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onopen.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+ <head>
+ <title>dedicated worker - EventSource: onopen (announcing the connection)</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 worker = new Worker('eventsource-onopen.js')
+ worker.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_equals(e.data[1], EventSource.OPEN, 'source.readyState')
+ assert_false(e.data[2], "'data' in e")
+ assert_false(e.data[3], 'e.bubbles')
+ assert_false(e.data[4], 'e.calcelable')
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onopen.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onopen.js
new file mode 100644
index 0000000000..72a1053263
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-onopen.js
@@ -0,0 +1,9 @@
+try {
+ var source = new EventSource("../resources/message.py")
+ source.onopen = function(e) {
+ postMessage([true, source.readyState, 'data' in e, e.bubbles, e.cancelable])
+ this.close()
+ }
+} catch(e) {
+ postMessage([false, String(e)])
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-prototype.htm b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-prototype.htm
new file mode 100644
index 0000000000..5a5ac4ec2a
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-prototype.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <heAd>
+ <title>dedicated worker - EventSource: prototype et al</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 worker = new Worker('eventsource-prototype.js')
+ worker.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_true(e.data[1], 'source.ReturnTrue()')
+ assert_true(e.data[2], "'EventSource' in self")
+ })
+ test.done()
+ }
+ })
+ </scrIpt>
+ </bOdy>
+</htMl> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-prototype.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-prototype.js
new file mode 100644
index 0000000000..26993cb4ef
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-prototype.js
@@ -0,0 +1,8 @@
+try {
+ EventSource.prototype.ReturnTrue = function() { return true }
+ var source = new EventSource("../resources/message.py")
+ postMessage([true, source.ReturnTrue(), 'EventSource' in self])
+ source.close()
+} catch(e) {
+ postMessage([false, String(e)])
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-url.htm b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-url.htm
new file mode 100644
index 0000000000..59e77cba57
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-url.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>dedicated worker - EventSource: url</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 url = "resources/message.py"
+ var worker = new Worker('eventsource-url.js')
+ worker.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1]);
+ assert_equals(e.data[1].substr(-(url.length)), url)
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-url.js b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-url.js
new file mode 100644
index 0000000000..7a3c8030d2
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/dedicated-worker/eventsource-url.js
@@ -0,0 +1,7 @@
+try {
+ var source = new EventSource("../resources/message.py")
+ postMessage([true, source.url])
+ source.close()
+} catch(e) {
+ postMessage([false, String(e)])
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/event-data.any.js b/testing/web-platform/tests/eventsource/event-data.any.js
new file mode 100644
index 0000000000..12867694f8
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/event-data.any.js
@@ -0,0 +1,21 @@
+// META: title=EventSource: lines and data parsing
+
+ var test = async_test();
+ test.step(function() {
+ var source = new EventSource("resources/message2.py"),
+ counter = 0;
+ source.onmessage = test.step_func(function(e) {
+ if(counter == 0) {
+ assert_equals(e.data,"msg\nmsg");
+ } else if(counter == 1) {
+ assert_equals(e.data,"");
+ } else if(counter == 2) {
+ assert_equals(e.data,"end");
+ source.close();
+ test.done();
+ } else {
+ assert_unreached();
+ }
+ counter++;
+ });
+ });
diff --git a/testing/web-platform/tests/eventsource/eventsource-close.window.js b/testing/web-platform/tests/eventsource/eventsource-close.window.js
new file mode 100644
index 0000000000..e5693e6314
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-close.window.js
@@ -0,0 +1,70 @@
+// META: title=EventSource: close()
+
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py")
+ assert_equals(source.readyState, source.CONNECTING, "connecting readyState");
+ source.onopen = this.step_func(function() {
+ assert_equals(source.readyState, source.OPEN, "open readyState");
+ source.close()
+ assert_equals(source.readyState, source.CLOSED, "closed readyState");
+ this.done()
+ })
+ })
+
+ var test2 = async_test(document.title + ", test events");
+ test2.step(function() {
+ var count = 0, reconnected = false,
+ source = new EventSource("resources/reconnect-fail.py?id=" + new Date().getTime());
+
+ source.onerror = this.step_func(function(e) {
+ assert_equals(e.type, 'error');
+ switch(count) {
+ // reconnecting after first message
+ case 1:
+ assert_equals(source.readyState, source.CONNECTING, "reconnecting readyState");
+
+ reconnected = true;
+ break;
+
+ // one more reconnect to get to the closing
+ case 2:
+ assert_equals(source.readyState, source.CONNECTING, "last reconnecting readyState");
+ count++;
+ break;
+
+ // close
+ case 3:
+ assert_equals(source.readyState, source.CLOSED, "closed readyState");
+
+ // give some time for errors to hit us
+ test2.step_timeout(function() { this.done(); }, 100);
+ break;
+
+ default:
+ assert_unreached("Error handler with msg count " + count);
+ }
+
+ });
+
+ source.onmessage = this.step_func(function(e) {
+ switch(count) {
+ case 0:
+ assert_true(!reconnected, "no error event run");
+ assert_equals(e.data, "opened", "data");
+ break;
+
+ case 1:
+ assert_true(reconnected, "have reconnected");
+ assert_equals(e.data, "reconnected", "data");
+ break;
+
+ default:
+ assert_unreached("Dunno what to do with message number " + count);
+ }
+
+ count++;
+ });
+
+ });
+
diff --git a/testing/web-platform/tests/eventsource/eventsource-constructor-document-domain.window.js b/testing/web-platform/tests/eventsource/eventsource-constructor-document-domain.window.js
new file mode 100644
index 0000000000..defaee5b36
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-constructor-document-domain.window.js
@@ -0,0 +1,18 @@
+// META: title=EventSource: document.domain
+
+ var test = async_test()
+ test.step(function() {
+ document.domain = document.domain
+ source = new EventSource("resources/message.py")
+ source.onopen = function(e) {
+ test.step(function() {
+ assert_equals(source.readyState, source.OPEN)
+ assert_false(e.hasOwnProperty('data'))
+ assert_false(e.bubbles)
+ assert_false(e.cancelable)
+ this.close()
+ }, this)
+ test.done()
+ }
+ })
+ // Apart from document.domain equivalent to the onopen test.
diff --git a/testing/web-platform/tests/eventsource/eventsource-constructor-empty-url.any.js b/testing/web-platform/tests/eventsource/eventsource-constructor-empty-url.any.js
new file mode 100644
index 0000000000..850d854db4
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-constructor-empty-url.any.js
@@ -0,0 +1,6 @@
+// META: global=window,worker
+
+test(function() {
+ const source = new EventSource("");
+ assert_equals(source.url, self.location.toString());
+}, "EventSource constructor with an empty url.");
diff --git a/testing/web-platform/tests/eventsource/eventsource-constructor-non-same-origin.window.js b/testing/web-platform/tests/eventsource/eventsource-constructor-non-same-origin.window.js
new file mode 100644
index 0000000000..bb32ed4b76
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-constructor-non-same-origin.window.js
@@ -0,0 +1,21 @@
+// META: title=EventSource: constructor (act as if there is a network error)
+
+ function fetchFail(url) {
+ var test = async_test(document.title + " (" + url + ")")
+ test.step(function() {
+ var source = new EventSource(url)
+ source.onerror = function(e) {
+ test.step(function() {
+ assert_equals(source.readyState, source.CLOSED)
+ assert_false(e.hasOwnProperty('data'))
+ })
+ test.done()
+ }
+ })
+ }
+ fetchFail("ftp://example.not/")
+ fetchFail("about:blank")
+ fetchFail("mailto:whatwg@awesome.example")
+ fetchFail("javascript:alert('FAIL')")
+ // This tests "fails the connection" as well as making sure a simple
+ // event is dispatched and not a MessageEvent
diff --git a/testing/web-platform/tests/eventsource/eventsource-constructor-stringify.window.js b/testing/web-platform/tests/eventsource/eventsource-constructor-stringify.window.js
new file mode 100644
index 0000000000..ba14f90c6c
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-constructor-stringify.window.js
@@ -0,0 +1,28 @@
+// META: title=EventSource: stringify argument
+
+ async_test(function (test) {
+ test.step(function() {
+ var source = new EventSource({toString:function(){return "resources/message.py";}})
+ source.onopen = function(e) {
+ test.step(function() {
+ assert_false(e.hasOwnProperty('data'))
+ source.close()
+ test.done()
+ })
+ }
+ });
+ }, document.title + ', object');
+
+ test(function(){
+ var source = new EventSource(1);
+ assert_regexp_match(source.url, /\/1$/);
+ }, document.title + ', 1');
+ test(function(){
+ var source = new EventSource(null);
+ assert_regexp_match(source.url, /\/null$/);
+ }, document.title + ', null');
+ test(function(){
+ var source = new EventSource(undefined);
+ assert_regexp_match(source.url, /\/undefined$/);
+ }, document.title + ', undefined');
+
diff --git a/testing/web-platform/tests/eventsource/eventsource-constructor-url-bogus.any.js b/testing/web-platform/tests/eventsource/eventsource-constructor-url-bogus.any.js
new file mode 100644
index 0000000000..53c3205e8a
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-constructor-url-bogus.any.js
@@ -0,0 +1,8 @@
+// META: global=window,worker
+// META: title=EventSource: constructor (invalid URL)
+
+test(() => {
+ assert_throws_dom('SyntaxError', () => { new EventSource("http://this is invalid/"); });
+});
+
+done();
diff --git a/testing/web-platform/tests/eventsource/eventsource-constructor-url-multi-window.htm b/testing/web-platform/tests/eventsource/eventsource-constructor-url-multi-window.htm
new file mode 100644
index 0000000000..99fecb972c
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-constructor-url-multi-window.htm
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>EventSource: resolving URLs</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var test = async_test()
+ function init() {
+ test.step(function() {
+ source = new self[0].EventSource("message.py")
+ source.onopen = function(e) {
+ test.step(function() {
+ assert_equals(source.readyState, source.OPEN)
+ assert_false(e.hasOwnProperty('data'))
+ assert_false(e.bubbles)
+ assert_false(e.cancelable)
+ this.close()
+ test.done()
+ }, this)
+ }
+ source.onerror = function(e) {
+ test.step(function() {
+ assert_unreached()
+ source.close()
+ test.done()
+ })
+ }
+ })
+ }
+ </script>
+ <iframe src="resources/init.htm"></iframe>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/eventsource/eventsource-cross-origin.window.js b/testing/web-platform/tests/eventsource/eventsource-cross-origin.window.js
new file mode 100644
index 0000000000..23bd27a7dc
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-cross-origin.window.js
@@ -0,0 +1,51 @@
+// META: title=EventSource: cross-origin
+
+ const crossdomain = location.href.replace('://', '://élève.').replace(/\/[^\/]*$/, '/'),
+ origin = location.origin.replace('://', '://xn--lve-6lad.');
+
+
+ function doCORS(url, title) {
+ async_test(document.title + " " + title).step(function() {
+ var source = new EventSource(url, { withCredentials: true })
+ source.onmessage = this.step_func_done(e => {
+ assert_equals(e.data, "data");
+ assert_equals(e.origin, origin);
+ source.close();
+ })
+ })
+ }
+
+ doCORS(crossdomain + "resources/cors.py?run=message",
+ "basic use")
+ doCORS(crossdomain + "resources/cors.py?run=redirect&location=/eventsource/resources/cors.py?run=message",
+ "redirect use")
+ doCORS(crossdomain + "resources/cors.py?run=status-reconnect&status=200",
+ "redirect use recon")
+
+ function failCORS(url, title) {
+ async_test(document.title + " " + title).step(function() {
+ var source = new EventSource(url)
+ source.onerror = this.step_func(function(e) {
+ assert_equals(source.readyState, source.CLOSED, 'readyState')
+ assert_false(e.hasOwnProperty('data'))
+ source.close()
+ this.done()
+ })
+
+ /* Shouldn't happen */
+ source.onmessage = this.step_func(function(e) {
+ assert_unreached("shouldn't fire message event")
+ })
+ source.onopen = this.step_func(function(e) {
+ assert_unreached("shouldn't fire open event")
+ })
+ })
+ }
+
+ failCORS(crossdomain + "resources/cors.py?run=message&origin=http://example.org",
+ "allow-origin: http://example.org should fail")
+ failCORS(crossdomain + "resources/cors.py?run=message&origin=",
+ "allow-origin:'' should fail")
+ failCORS(crossdomain + "resources/message.py",
+ "No allow-origin should fail")
+
diff --git a/testing/web-platform/tests/eventsource/eventsource-eventtarget.any.js b/testing/web-platform/tests/eventsource/eventsource-eventtarget.any.js
new file mode 100644
index 0000000000..b0d0017dd2
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-eventtarget.any.js
@@ -0,0 +1,16 @@
+// META: title=EventSource: addEventListener()
+
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py")
+ source.addEventListener("message", listener, false)
+ })
+ function listener(e) {
+ test.step(function() {
+ assert_equals("data", e.data)
+ this.close()
+ }, this)
+ test.done()
+ }
+
+
diff --git a/testing/web-platform/tests/eventsource/eventsource-onmessage-realm.htm b/testing/web-platform/tests/eventsource/eventsource-onmessage-realm.htm
new file mode 100644
index 0000000000..db2218b516
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-onmessage-realm.htm
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>EventSource: message event Realm</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/comms.html#dispatchMessage">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<iframe src="resources/eventsource-onmessage-realm.htm"></iframe>
+
+<script>
+"use strict";
+
+async_test(t => {
+ window.onload = t.step_func(() => {
+ const source = new frames[0].EventSource("message.py");
+ t.add_cleanup(() => {
+ source.close();
+ });
+
+ source.onmessage = t.step_func_done(e => {
+ assert_equals(e.constructor, frames[0].MessageEvent);
+ });
+ });
+}, "the MessageEvent must be created in the Realm of the EventSource");
+</script>
diff --git a/testing/web-platform/tests/eventsource/eventsource-onmessage-trusted.any.js b/testing/web-platform/tests/eventsource/eventsource-onmessage-trusted.any.js
new file mode 100644
index 0000000000..d0be4d03e8
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-onmessage-trusted.any.js
@@ -0,0 +1,12 @@
+// META: title=EventSource message events are trusted
+
+"use strict";
+
+async_test(t => {
+ const source = new EventSource("resources/message.py");
+
+ source.onmessage = t.step_func_done(e => {
+ source.close();
+ assert_equals(e.isTrusted, true);
+ });
+}, "EventSource message events are trusted");
diff --git a/testing/web-platform/tests/eventsource/eventsource-onmessage.any.js b/testing/web-platform/tests/eventsource/eventsource-onmessage.any.js
new file mode 100644
index 0000000000..391fa4b193
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-onmessage.any.js
@@ -0,0 +1,14 @@
+// META: title=EventSource: onmessage
+
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals("data", e.data)
+ source.close()
+ })
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/eventsource-onopen.any.js b/testing/web-platform/tests/eventsource/eventsource-onopen.any.js
new file mode 100644
index 0000000000..3977cb176e
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-onopen.any.js
@@ -0,0 +1,17 @@
+// META: title=EventSource: onopen (announcing the connection)
+
+ var test = async_test()
+ test.step(function() {
+ source = new EventSource("resources/message.py")
+ source.onopen = function(e) {
+ test.step(function() {
+ assert_equals(source.readyState, source.OPEN)
+ assert_false(e.hasOwnProperty('data'))
+ assert_false(e.bubbles)
+ assert_false(e.cancelable)
+ this.close()
+ }, this)
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/eventsource-prototype.any.js b/testing/web-platform/tests/eventsource/eventsource-prototype.any.js
new file mode 100644
index 0000000000..b7aefb32f4
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-prototype.any.js
@@ -0,0 +1,10 @@
+// META: title=EventSource: prototype et al
+
+ test(function() {
+ EventSource.prototype.ReturnTrue = function() { return true }
+ var source = new EventSource("resources/message.py")
+ assert_true(source.ReturnTrue())
+ assert_own_property(self, "EventSource")
+ source.close()
+ })
+
diff --git a/testing/web-platform/tests/eventsource/eventsource-reconnect.window.js b/testing/web-platform/tests/eventsource/eventsource-reconnect.window.js
new file mode 100644
index 0000000000..551fbdc88b
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-reconnect.window.js
@@ -0,0 +1,47 @@
+// META: title=EventSource: reconnection
+
+ function doReconn(url, title) {
+ var test = async_test(document.title + " " + title)
+ test.step(function() {
+ var source = new EventSource(url)
+ source.onmessage = test.step_func(function(e) {
+ assert_equals(e.data, "data")
+ source.close()
+ test.done()
+ })
+ })
+ }
+
+ doReconn("resources/status-reconnect.py?status=200",
+ "200")
+
+
+ var t = async_test(document.title + ", test reconnection events");
+ t.step(function() {
+ var opened = false, reconnected = false,
+ source = new EventSource("resources/status-reconnect.py?status=200&ok_first&id=2");
+
+ source.onerror = t.step_func(function(e) {
+ assert_equals(e.type, 'error');
+ assert_equals(source.readyState, source.CONNECTING, "readyState");
+ assert_true(opened, "connection is opened earlier");
+
+ reconnected = true;
+ });
+
+ source.onmessage = t.step_func(function(e) {
+ if (!opened) {
+ opened = true;
+ assert_false(reconnected, "have reconnected before first message");
+ assert_equals(e.data, "ok");
+ }
+ else {
+ assert_true(reconnected, "Got reconnection event");
+ assert_equals(e.data, "data");
+ source.close()
+ t.done()
+ }
+ });
+ });
+
+
diff --git a/testing/web-platform/tests/eventsource/eventsource-request-cancellation.any.window.js b/testing/web-platform/tests/eventsource/eventsource-request-cancellation.any.window.js
new file mode 100644
index 0000000000..1cee9b742e
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-request-cancellation.any.window.js
@@ -0,0 +1,21 @@
+// META: title=EventSource: request cancellation
+
+ var t = async_test();
+ onload = t.step_func(function() {
+ var url = "resources/message.py?sleep=1000&message=" + encodeURIComponent("retry:1000\ndata:abc\n\n");
+ var es = new EventSource(url);
+ es.onerror = t.step_func(function() {
+ assert_equals(es.readyState, EventSource.CLOSED)
+ t.step_timeout(function () {
+ assert_equals(es.readyState, EventSource.CLOSED,
+ "After stopping the eventsource readyState should be CLOSED")
+ t.done();
+ }, 1000);
+ });
+
+ t.step_timeout(function() {
+ window.stop()
+ es.onopen = t.unreached_func("Got open event");
+ es.onmessage = t.unreached_func("Got message after closing source");
+ }, 0);
+ });
diff --git a/testing/web-platform/tests/eventsource/eventsource-url.any.js b/testing/web-platform/tests/eventsource/eventsource-url.any.js
new file mode 100644
index 0000000000..92207ea78a
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/eventsource-url.any.js
@@ -0,0 +1,8 @@
+// META: title=EventSource: url
+
+ test(function() {
+ var url = "resources/message.py",
+ source = new EventSource(url)
+ assert_equals(source.url.substr(-(url.length)), url)
+ source.close()
+ })
diff --git a/testing/web-platform/tests/eventsource/format-bom-2.any.js b/testing/web-platform/tests/eventsource/format-bom-2.any.js
new file mode 100644
index 0000000000..8b7be8402c
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-bom-2.any.js
@@ -0,0 +1,24 @@
+// META: title=EventSource: Double BOM
+
+ var test = async_test(),
+ hasbeenone = false,
+ hasbeentwo = false
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=%EF%BB%BF%EF%BB%BFdata%3A1%0A%0Adata%3A2%0A%0Adata%3A3")
+ source.addEventListener("message", listener, false)
+ })
+ function listener(e) {
+ test.step(function() {
+ if(e.data == "1")
+ hasbeenone = true
+ if(e.data == "2")
+ hasbeentwo = true
+ if(e.data == "3") {
+ assert_false(hasbeenone)
+ assert_true(hasbeentwo)
+ this.close()
+ test.done()
+ }
+ }, this)
+ }
+
diff --git a/testing/web-platform/tests/eventsource/format-bom.any.js b/testing/web-platform/tests/eventsource/format-bom.any.js
new file mode 100644
index 0000000000..05d1abd18b
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-bom.any.js
@@ -0,0 +1,24 @@
+// META: title=EventSource: BOM
+
+ var test = async_test(),
+ hasbeenone = false,
+ hasbeentwo = false
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=%EF%BB%BFdata%3A1%0A%0A%EF%BB%BFdata%3A2%0A%0Adata%3A3")
+ source.addEventListener("message", listener, false)
+ })
+ function listener(e) {
+ test.step(function() {
+ if(e.data == "1")
+ hasbeenone = true
+ if(e.data == "2")
+ hasbeentwo = true
+ if(e.data == "3") {
+ assert_true(hasbeenone)
+ assert_false(hasbeentwo)
+ this.close()
+ test.done()
+ }
+ }, this)
+ }
+
diff --git a/testing/web-platform/tests/eventsource/format-comments.any.js b/testing/web-platform/tests/eventsource/format-comments.any.js
new file mode 100644
index 0000000000..186e4714ba
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-comments.any.js
@@ -0,0 +1,16 @@
+// META: title=EventSource: comment fest
+
+ var test = async_test()
+ test.step(function() {
+ var longstring = (new Array(2*1024+1)).join("x"), // cannot make the string too long; causes timeout
+ message = encodeURI("data:1\r:\0\n:\r\ndata:2\n:" + longstring + "\rdata:3\n:data:fail\r:" + longstring + "\ndata:4\n"),
+ source = new EventSource("resources/message.py?message=" + message + "&newline=none")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals("1\n2\n3\n4", e.data)
+ source.close()
+ })
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-data-before-final-empty-line.any.js b/testing/web-platform/tests/eventsource/format-data-before-final-empty-line.any.js
new file mode 100644
index 0000000000..5a4d84d28d
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-data-before-final-empty-line.any.js
@@ -0,0 +1,17 @@
+// META: title=EventSource: a data before final empty line
+
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?newline=none&message=" + encodeURIComponent("retry:1000\ndata:test1\n\nid:test\ndata:test2"))
+ var count = 0;
+ source.onmessage = function(e) {
+ if (++count === 2) {
+ test.step(function() {
+ assert_equals(e.lastEventId, "", "lastEventId")
+ assert_equals(e.data, "test1", "data")
+ source.close()
+ })
+ test.done()
+ }
+ }
+ })
diff --git a/testing/web-platform/tests/eventsource/format-field-data.any.js b/testing/web-platform/tests/eventsource/format-field-data.any.js
new file mode 100644
index 0000000000..bea9be1742
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-data.any.js
@@ -0,0 +1,23 @@
+// META: title=EventSource: data field parsing
+
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=data%3A%0A%0Adata%0Adata%0A%0Adata%3Atest"),
+ counter = 0
+ source.onmessage = function(e) {
+ test.step(function() {
+ if(counter == 0) {
+ assert_equals("", e.data)
+ } else if(counter == 1) {
+ assert_equals("\n", e.data)
+ } else if(counter == 2) {
+ assert_equals("test", e.data)
+ source.close()
+ test.done()
+ } else {
+ assert_unreached()
+ }
+ counter++
+ })
+ }
+ })
diff --git a/testing/web-platform/tests/eventsource/format-field-event-empty.any.js b/testing/web-platform/tests/eventsource/format-field-event-empty.any.js
new file mode 100644
index 0000000000..ada8e5725f
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-event-empty.any.js
@@ -0,0 +1,13 @@
+// META: title=EventSource: empty "event" field
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=event%3A%20%0Adata%3Adata")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals("data", e.data)
+ this.close()
+ }, this)
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-field-event.any.js b/testing/web-platform/tests/eventsource/format-field-event.any.js
new file mode 100644
index 0000000000..0c7d1fc266
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-event.any.js
@@ -0,0 +1,15 @@
+// META: title=EventSource: custom event name
+ var test = async_test(),
+ dispatchedtest = false
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=event%3Atest%0Adata%3Ax%0A%0Adata%3Ax")
+ source.addEventListener("test", function() { test.step(function() { dispatchedtest = true }) }, false)
+ source.onmessage = function() {
+ test.step(function() {
+ assert_true(dispatchedtest)
+ this.close()
+ }, this)
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-field-id-2.any.js b/testing/web-platform/tests/eventsource/format-field-id-2.any.js
new file mode 100644
index 0000000000..9933f46b87
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-id-2.any.js
@@ -0,0 +1,25 @@
+// META: title=EventSource: Last-Event-ID (2)
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/last-event-id.py"),
+ counter = 0
+ source.onmessage = function(e) {
+ test.step(function() {
+ if(e.data == "hello" && counter == 0) {
+ counter++
+ assert_equals(e.lastEventId, "…")
+ } else if(counter == 1) {
+ counter++
+ assert_equals("…", e.data)
+ assert_equals("…", e.lastEventId)
+ } else if(counter == 2) {
+ counter++
+ assert_equals("…", e.data)
+ assert_equals("…", e.lastEventId)
+ source.close()
+ test.done()
+ } else
+ assert_unreached()
+ })
+ }
+ })
diff --git a/testing/web-platform/tests/eventsource/format-field-id-3.window.js b/testing/web-platform/tests/eventsource/format-field-id-3.window.js
new file mode 100644
index 0000000000..3766fbf7bb
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-id-3.window.js
@@ -0,0 +1,56 @@
+const ID_PERSISTS = 1,
+ID_RESETS_1 = 2,
+ID_RESETS_2 = 3;
+
+async_test(testPersist, "EventSource: lastEventId persists");
+async_test(testReset(ID_RESETS_1), "EventSource: lastEventId resets");
+async_test(testReset(ID_RESETS_2), "EventSource: lastEventId resets (id without colon)");
+
+function testPersist(t) {
+ const source = new EventSource("resources/last-event-id2.py?type=" + ID_PERSISTS);
+ let counter = 0;
+ t.add_cleanup(() => source.close());
+ source.onmessage = t.step_func(e => {
+ counter++;
+ if (counter === 1) {
+ assert_equals(e.lastEventId, "1");
+ assert_equals(e.data, "1");
+ } else if (counter === 2) {
+ assert_equals(e.lastEventId, "1");
+ assert_equals(e.data, "2");
+ } else if (counter === 3) {
+ assert_equals(e.lastEventId, "2");
+ assert_equals(e.data, "3");
+ } else if (counter === 4) {
+ assert_equals(e.lastEventId, "2");
+ assert_equals(e.data, "4");
+ t.done();
+ } else {
+ assert_unreached();
+ }
+ });
+}
+
+function testReset(type) {
+ return function (t) {
+ const source = new EventSource("resources/last-event-id2.py?type=" + type);
+ let counter = 0;
+ t.add_cleanup(() => source.close());
+ source.onmessage = t.step_func(e => {
+ counter++;
+ if (counter === 1) {
+ assert_equals(e.lastEventId, "1");
+ assert_equals(e.data, "1");
+ } else if (counter === 2) {
+ assert_equals(e.lastEventId, "");
+ assert_equals(e.data, "2");
+ } else if (counter === 3) {
+ assert_equals(e.lastEventId, "");
+ assert_equals(e.data, "3");
+ t.done();
+ } else {
+ assert_unreached();
+ }
+ });
+ }
+}
diff --git a/testing/web-platform/tests/eventsource/format-field-id-null.window.js b/testing/web-platform/tests/eventsource/format-field-id-null.window.js
new file mode 100644
index 0000000000..6d564dde0f
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-id-null.window.js
@@ -0,0 +1,25 @@
+[
+ "\u0000\u0000",
+ "x\u0000",
+ "\u0000x",
+ "x\u0000x",
+ " \u0000"
+].forEach(idValue => {
+ const encodedIdValue = encodeURIComponent(idValue);
+ async_test(t => {
+ const source = new EventSource("resources/last-event-id.py?idvalue=" + encodedIdValue);
+ t.add_cleanup(() => source.close());
+ let seenhello = false;
+ source.onmessage = t.step_func(e => {
+ if (e.data == "hello" && !seenhello) {
+ seenhello = true;
+ assert_equals(e.lastEventId, "");
+ } else if(seenhello) {
+ assert_equals(e.data, "hello");
+ assert_equals(e.lastEventId, "");
+ t.done();
+ } else
+ assert_unreached();
+ });
+ }, "EventSource: id field set to " + encodedIdValue);
+});
diff --git a/testing/web-platform/tests/eventsource/format-field-id.any.js b/testing/web-platform/tests/eventsource/format-field-id.any.js
new file mode 100644
index 0000000000..26f1aea709
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-id.any.js
@@ -0,0 +1,21 @@
+// META: title=EventSource: Last-Event-ID
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/last-event-id.py"),
+ seenhello = false
+ source.onmessage = function(e) {
+ test.step(function() {
+ if(e.data == "hello" && !seenhello) {
+ seenhello = true
+ assert_equals(e.lastEventId, "…")
+ } else if(seenhello) {
+ assert_equals("…", e.data)
+ assert_equals("…", e.lastEventId)
+ source.close()
+ test.done()
+ } else
+ assert_unreached()
+ })
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-field-parsing.any.js b/testing/web-platform/tests/eventsource/format-field-parsing.any.js
new file mode 100644
index 0000000000..9b05187153
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-parsing.any.js
@@ -0,0 +1,14 @@
+// META: title=EventSource: field parsing
+ var test = async_test()
+ test.step(function() {
+ var message = encodeURI("data:\0\ndata: 2\rData:1\ndata\0:2\ndata:1\r\0data:4\nda-ta:3\rdata_5\ndata:3\rdata:\r\n data:32\ndata:4\n"),
+ source = new EventSource("resources/message.py?message=" + message + "&newline=none")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals(e.data, "\0\n 2\n1\n3\n\n4")
+ source.close()
+ })
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-field-retry-bogus.any.js b/testing/web-platform/tests/eventsource/format-field-retry-bogus.any.js
new file mode 100644
index 0000000000..86d9b9ea40
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-retry-bogus.any.js
@@ -0,0 +1,19 @@
+// META: title=EventSource: "retry" field (bogus)
+ var test = async_test()
+ test.step(function() {
+ var timeoutms = 3000,
+ source = new EventSource("resources/message.py?message=retry%3A3000%0Aretry%3A1000x%0Adata%3Ax"),
+ opened = 0
+ source.onopen = function() {
+ test.step(function() {
+ if(opened == 0)
+ opened = new Date().getTime()
+ else {
+ var diff = (new Date().getTime()) - opened
+ assert_true(Math.abs(1 - diff / timeoutms) < 0.25) // allow 25% difference
+ this.close();
+ test.done()
+ }
+ }, this)
+ }
+ })
diff --git a/testing/web-platform/tests/eventsource/format-field-retry-empty.any.js b/testing/web-platform/tests/eventsource/format-field-retry-empty.any.js
new file mode 100644
index 0000000000..e7d5e76a13
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-retry-empty.any.js
@@ -0,0 +1,13 @@
+// META: title=EventSource: empty retry field
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=retry%0Adata%3Atest")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals("test", e.data)
+ source.close()
+ })
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-field-retry.any.js b/testing/web-platform/tests/eventsource/format-field-retry.any.js
new file mode 100644
index 0000000000..819241dbd4
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-retry.any.js
@@ -0,0 +1,21 @@
+// META: title=EventSource: "retry" field
+ var test = async_test();
+ test.step(function() {
+ var timeoutms = 3000,
+ timeoutstr = "03000", // 1536 in octal, but should be 3000
+ source = new EventSource("resources/message.py?message=retry%3A" + timeoutstr + "%0Adata%3Ax"),
+ opened = 0
+ source.onopen = function() {
+ test.step(function() {
+ if(opened == 0)
+ opened = new Date().getTime()
+ else {
+ var diff = (new Date().getTime()) - opened
+ assert_true(Math.abs(1 - diff / timeoutms) < 0.25) // allow 25% difference
+ this.close();
+ test.done()
+ }
+ }, this)
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-field-unknown.any.js b/testing/web-platform/tests/eventsource/format-field-unknown.any.js
new file mode 100644
index 0000000000..f702ed8565
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-field-unknown.any.js
@@ -0,0 +1,13 @@
+// META: title=EventSource: unknown fields and parsing fun
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=data%3Atest%0A%20data%0Adata%0Afoobar%3Axxx%0Ajustsometext%0A%3Athisisacommentyay%0Adata%3Atest")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals("test\n\ntest", e.data)
+ source.close()
+ })
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-leading-space.any.js b/testing/web-platform/tests/eventsource/format-leading-space.any.js
new file mode 100644
index 0000000000..0ddfd9b32b
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-leading-space.any.js
@@ -0,0 +1,14 @@
+// META: title=EventSource: leading space
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=data%3A%09test%0Ddata%3A%20%0Adata%3Atest")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals("\ttest\n\ntest", e.data)
+ source.close()
+ })
+ test.done()
+ }
+ })
+ // also used a CR as newline once
+
diff --git a/testing/web-platform/tests/eventsource/format-mime-bogus.any.js b/testing/web-platform/tests/eventsource/format-mime-bogus.any.js
new file mode 100644
index 0000000000..18c7c7d4a4
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-mime-bogus.any.js
@@ -0,0 +1,25 @@
+// META: title=EventSource: bogus MIME type
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?mime=x%20bogus")
+ source.onmessage = function() {
+ test.step(function() {
+ assert_unreached()
+ source.close()
+ })
+ test.done()
+ }
+ source.onerror = function(e) {
+ test.step(function() {
+ assert_equals(this.readyState, this.CLOSED)
+ assert_false(e.hasOwnProperty('data'))
+ assert_false(e.bubbles)
+ assert_false(e.cancelable)
+ this.close()
+ }, this)
+ test.done()
+ }
+ })
+ // This tests "fails the connection" as well as making sure a simple
+ // event is dispatched and not a MessageEvent
+
diff --git a/testing/web-platform/tests/eventsource/format-mime-trailing-semicolon.any.js b/testing/web-platform/tests/eventsource/format-mime-trailing-semicolon.any.js
new file mode 100644
index 0000000000..55a314bf52
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-mime-trailing-semicolon.any.js
@@ -0,0 +1,20 @@
+// META: title=EventSource: MIME type with trailing ;
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?mime=text/event-stream%3B")
+ source.onopen = function() {
+ test.step(function() {
+ assert_equals(source.readyState, source.OPEN)
+ source.close()
+ })
+ test.done()
+ }
+ source.onerror = function() {
+ test.step(function() {
+ assert_unreached()
+ source.close()
+ })
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-mime-valid-bogus.any.js b/testing/web-platform/tests/eventsource/format-mime-valid-bogus.any.js
new file mode 100644
index 0000000000..355ba6c524
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-mime-valid-bogus.any.js
@@ -0,0 +1,24 @@
+// META: title=EventSource: incorrect valid MIME type
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?mime=text/x-bogus")
+ source.onmessage = function() {
+ test.step(function() {
+ assert_unreached()
+ source.close()
+ })
+ test.done()
+ }
+ source.onerror = function(e) {
+ test.step(function() {
+ assert_equals(source.readyState, source.CLOSED)
+ assert_false(e.hasOwnProperty('data'))
+ assert_false(e.bubbles)
+ assert_false(e.cancelable)
+ })
+ test.done()
+ }
+ })
+ // This tests "fails the connection" as well as making sure a simple
+ // event is dispatched and not a MessageEvent
+
diff --git a/testing/web-platform/tests/eventsource/format-newlines.any.js b/testing/web-platform/tests/eventsource/format-newlines.any.js
new file mode 100644
index 0000000000..0768171d33
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-newlines.any.js
@@ -0,0 +1,13 @@
+// META: title=EventSource: newline fest
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=data%3Atest%0D%0Adata%0Adata%3Atest%0D%0A%0D&newline=none")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals("test\n\ntest", e.data)
+ source.close()
+ })
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-null-character.any.js b/testing/web-platform/tests/eventsource/format-null-character.any.js
new file mode 100644
index 0000000000..943628d2c0
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-null-character.any.js
@@ -0,0 +1,17 @@
+// META: title=EventSource: null character in response
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/message.py?message=data%3A%00%0A%0A")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals("\x00", e.data)
+ source.close()
+ }, this)
+ test.done()
+ }
+ source.onerror = function() {
+ test.step(function() { assert_unreached() })
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/format-utf-8.any.js b/testing/web-platform/tests/eventsource/format-utf-8.any.js
new file mode 100644
index 0000000000..7976abfb55
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/format-utf-8.any.js
@@ -0,0 +1,12 @@
+// META: title=EventSource always UTF-8
+async_test().step(function() {
+ var source = new EventSource("resources/message.py?mime=text/event-stream%3bcharset=windows-1252&message=data%3Aok%E2%80%A6")
+ source.onmessage = this.step_func(function(e) {
+ assert_equals('ok…', e.data, 'decoded data')
+ source.close()
+ this.done()
+ })
+ source.onerror = this.step_func(function() {
+ assert_unreached("Got error event")
+ })
+})
diff --git a/testing/web-platform/tests/eventsource/request-accept.any.js b/testing/web-platform/tests/eventsource/request-accept.any.js
new file mode 100644
index 0000000000..2e18173556
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/request-accept.any.js
@@ -0,0 +1,13 @@
+// META: title=EventSource: Accept header
+ var test = async_test()
+ test.step(function() {
+ var source = new EventSource("resources/accept.event_stream?pipe=sub")
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals(e.data, "text/event-stream")
+ this.close()
+ }, this)
+ test.done()
+ }
+ })
+
diff --git a/testing/web-platform/tests/eventsource/request-cache-control.any.js b/testing/web-platform/tests/eventsource/request-cache-control.any.js
new file mode 100644
index 0000000000..95b71d7a58
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/request-cache-control.any.js
@@ -0,0 +1,35 @@
+// META: title=EventSource: Cache-Control
+ var crossdomain = location.href
+ .replace('://', '://www2.')
+ .replace(/\/[^\/]*$/, '/')
+
+ // running it twice to check whether it stays consistent
+ function cacheTest(url) {
+ var test = async_test(url + "1")
+ // Recursive test. This avoids test that timeout
+ var test2 = async_test(url + "2")
+ test.step(function() {
+ var source = new EventSource(url)
+ source.onmessage = function(e) {
+ test.step(function() {
+ assert_equals(e.data, "no-cache")
+ this.close()
+ test2.step(function() {
+ var source2 = new EventSource(url)
+ source2.onmessage = function(e) {
+ test2.step(function() {
+ assert_equals(e.data, "no-cache")
+ this.close()
+ }, this)
+ test2.done()
+ }
+ })
+ }, this)
+ test.done()
+ }
+ })
+ }
+
+ cacheTest("resources/cache-control.event_stream?pipe=sub")
+ cacheTest(crossdomain + "resources/cors.py?run=cache-control")
+
diff --git a/testing/web-platform/tests/eventsource/request-credentials.any.window.js b/testing/web-platform/tests/eventsource/request-credentials.any.window.js
new file mode 100644
index 0000000000..d7c554aa4a
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/request-credentials.any.window.js
@@ -0,0 +1,37 @@
+// META: title=EventSource: credentials
+ var crossdomain = location.href
+ .replace('://', '://www2.')
+ .replace(/\/[^\/]*$/, '/')
+
+ function testCookie(desc, success, props, id) {
+ var test = async_test(document.title + ': credentials ' + desc)
+ test.step(function() {
+ var source = new EventSource(crossdomain + "resources/cors-cookie.py?ident=" + id, props)
+
+ source.onmessage = test.step_func(function(e) {
+ if(e.data.indexOf("first") == 0) {
+ assert_equals(e.data, "first NO_COOKIE", "cookie status")
+ }
+ else if(e.data.indexOf("second") == 0) {
+ if (success)
+ assert_equals(e.data, "second COOKIE", "cookie status")
+ else
+ assert_equals(e.data, "second NO_COOKIE", "cookie status")
+
+ source.close()
+ test.done()
+ }
+ else {
+ assert_unreached("unrecognized data returned: " + e.data)
+ source.close()
+ test.done()
+ }
+ })
+ })
+ }
+
+ testCookie('enabled', true, { withCredentials: true }, '1_' + new Date().getTime())
+ testCookie('disabled', false, { withCredentials: false }, '2_' + new Date().getTime())
+ testCookie('default', false, { }, '3_' + new Date().getTime())
+
+
diff --git a/testing/web-platform/tests/eventsource/request-redirect.any.window.js b/testing/web-platform/tests/eventsource/request-redirect.any.window.js
new file mode 100644
index 0000000000..3788dd8450
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/request-redirect.any.window.js
@@ -0,0 +1,24 @@
+// META: title=EventSource: redirect
+ function redirectTest(status) {
+ var test = async_test(document.title + " (" + status +")")
+ test.step(function() {
+ var source = new EventSource("/common/redirect.py?location=/eventsource/resources/message.py&status=" + status)
+ source.onopen = function() {
+ test.step(function() {
+ assert_equals(this.readyState, this.OPEN)
+ this.close()
+ }, this)
+ test.done()
+ }
+ source.onerror = function() {
+ test.step(function() { assert_unreached() })
+ test.done()
+ }
+ })
+ }
+
+ redirectTest("301")
+ redirectTest("302")
+ redirectTest("303")
+ redirectTest("307")
+
diff --git a/testing/web-platform/tests/eventsource/request-status-error.window.js b/testing/web-platform/tests/eventsource/request-status-error.window.js
new file mode 100644
index 0000000000..8632d8e8c6
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/request-status-error.window.js
@@ -0,0 +1,27 @@
+// META: title=EventSource: incorrect HTTP status code
+ function statusTest(status) {
+ var test = async_test(document.title + " (" + status +")")
+ test.step(function() {
+ var source = new EventSource("resources/status-error.py?status=" + status)
+ source.onmessage = function() {
+ test.step(function() {
+ assert_unreached()
+ })
+ test.done()
+ }
+ source.onerror = function() {
+ test.step(function() {
+ assert_equals(this.readyState, this.CLOSED)
+ }, this)
+ test.done()
+ }
+ })
+ }
+ statusTest("204")
+ statusTest("205")
+ statusTest("210")
+ statusTest("299")
+ statusTest("404")
+ statusTest("410")
+ statusTest("503")
+
diff --git a/testing/web-platform/tests/eventsource/resources/accept.event_stream b/testing/web-platform/tests/eventsource/resources/accept.event_stream
new file mode 100644
index 0000000000..24da548267
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/accept.event_stream
@@ -0,0 +1,2 @@
+data: {{headers[accept]}}
+
diff --git a/testing/web-platform/tests/eventsource/resources/cache-control.event_stream b/testing/web-platform/tests/eventsource/resources/cache-control.event_stream
new file mode 100644
index 0000000000..aa9f2d6c09
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/cache-control.event_stream
@@ -0,0 +1,2 @@
+data: {{headers[cache-control]}}
+
diff --git a/testing/web-platform/tests/eventsource/resources/cors-cookie.py b/testing/web-platform/tests/eventsource/resources/cors-cookie.py
new file mode 100644
index 0000000000..9eaab9b95a
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/cors-cookie.py
@@ -0,0 +1,31 @@
+from datetime import datetime
+
+def main(request, response):
+ last_event_id = request.headers.get(b"Last-Event-Id", b"")
+ ident = request.GET.first(b'ident', b"test")
+ cookie = b"COOKIE" if ident in request.cookies else b"NO_COOKIE"
+ origin = request.GET.first(b'origin', request.headers[b"origin"])
+ credentials = request.GET.first(b'credentials', b'true')
+
+ headers = []
+
+ if origin != b'none':
+ headers.append((b"Access-Control-Allow-Origin", origin));
+
+ if credentials != b'none':
+ headers.append((b"Access-Control-Allow-Credentials", credentials));
+
+ if last_event_id == b'':
+ headers.append((b"Content-Type", b"text/event-stream"))
+ response.set_cookie(ident, b"COOKIE")
+ data = b"id: 1\nretry: 200\ndata: first %s\n\n" % cookie
+ elif last_event_id == b'1':
+ headers.append((b"Content-Type", b"text/event-stream"))
+ long_long_time_ago = datetime.now().replace(year=2001, month=7, day=27)
+ response.set_cookie(ident, b"COOKIE", expires=long_long_time_ago)
+ data = b"id: 2\ndata: second %s\n\n" % cookie
+ else:
+ headers.append((b"Content-Type", b"stop"))
+ data = b"data: " + last_event_id + cookie + b"\n\n";
+
+ return headers, data
diff --git a/testing/web-platform/tests/eventsource/resources/cors.py b/testing/web-platform/tests/eventsource/resources/cors.py
new file mode 100644
index 0000000000..6ed31f2cd7
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/cors.py
@@ -0,0 +1,36 @@
+import os
+from wptserve import pipes
+
+from wptserve.utils import isomorphic_decode
+
+def run_other(request, response, path):
+ #This is a terrible hack
+ environ = {u"__file__": path}
+ exec(compile(open(path, u"r").read(), path, u'exec'), environ, environ)
+ rv = environ[u"main"](request, response)
+ return rv
+
+def main(request, response):
+ origin = request.GET.first(b"origin", request.headers[b"origin"])
+ credentials = request.GET.first(b"credentials", b"true")
+
+ response.headers.update([(b"Access-Control-Allow-Origin", origin),
+ (b"Access-Control-Allow-Credentials", credentials)])
+
+ handler = request.GET.first(b'run')
+ if handler in [b"status-reconnect",
+ b"message",
+ b"redirect",
+ b"cache-control"]:
+ if handler == b"cache-control":
+ response.headers.set(b"Content-Type", b"text/event-stream")
+ rv = open(os.path.join(request.doc_root, u"eventsource", u"resources", u"cache-control.event_stream"), u"r").read()
+ response.content = rv
+ pipes.sub(request, response)
+ return
+ elif handler == b"redirect":
+ return run_other(request, response, os.path.join(request.doc_root, u"common", u"redirect.py"))
+ else:
+ return run_other(request, response, os.path.join(os.path.dirname(isomorphic_decode(__file__)), isomorphic_decode(handler) + u".py"))
+ else:
+ return
diff --git a/testing/web-platform/tests/eventsource/resources/eventsource-onmessage-realm.htm b/testing/web-platform/tests/eventsource/resources/eventsource-onmessage-realm.htm
new file mode 100644
index 0000000000..63e6d012b4
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/eventsource-onmessage-realm.htm
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<title>This page is just used to grab an EventSource constructor</title>
diff --git a/testing/web-platform/tests/eventsource/resources/init.htm b/testing/web-platform/tests/eventsource/resources/init.htm
new file mode 100644
index 0000000000..7c56d88800
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/init.htm
@@ -0,0 +1,9 @@
+<!doctype html>
+<html>
+ <head>
+ <title>support init file</title>
+ </head>
+ <body>
+ <script> parent.init() </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/eventsource/resources/last-event-id.py b/testing/web-platform/tests/eventsource/resources/last-event-id.py
new file mode 100644
index 0000000000..a2cb726445
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/last-event-id.py
@@ -0,0 +1,9 @@
+def main(request, response):
+ response.headers.set(b"Content-Type", b"text/event-stream")
+
+ last_event_id = request.headers.get(b"Last-Event-ID", b"")
+ if last_event_id:
+ return b"data: " + last_event_id + b"\n\n"
+ else:
+ idvalue = request.GET.first(b"idvalue", u"\u2026".encode("utf-8"))
+ return b"id: " + idvalue + b"\nretry: 200\ndata: hello\n\n"
diff --git a/testing/web-platform/tests/eventsource/resources/last-event-id2.py b/testing/web-platform/tests/eventsource/resources/last-event-id2.py
new file mode 100644
index 0000000000..4f133d707d
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/last-event-id2.py
@@ -0,0 +1,23 @@
+ID_PERSISTS = 1
+ID_RESETS_1 = 2
+ID_RESETS_2 = 3
+
+def main(request, response):
+ response.headers.set(b"Content-Type", b"text/event-stream")
+ try:
+ test_type = int(request.GET.first(b"type", ID_PERSISTS))
+ except:
+ test_type = ID_PERSISTS
+
+ if test_type == ID_PERSISTS:
+ return b"id: 1\ndata: 1\n\ndata: 2\n\nid: 2\ndata:3\n\ndata:4\n\n"
+
+ elif test_type == ID_RESETS_1:
+ return b"id: 1\ndata: 1\n\nid:\ndata:2\n\ndata:3\n\n"
+
+ # empty id field without colon character (:) should also reset
+ elif test_type == ID_RESETS_2:
+ return b"id: 1\ndata: 1\n\nid\ndata:2\n\ndata:3\n\n"
+
+ else:
+ return b"data: invalid_test\n\n"
diff --git a/testing/web-platform/tests/eventsource/resources/message.py b/testing/web-platform/tests/eventsource/resources/message.py
new file mode 100644
index 0000000000..468564f4df
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/message.py
@@ -0,0 +1,14 @@
+import time
+
+def main(request, response):
+ mime = request.GET.first(b"mime", b"text/event-stream")
+ message = request.GET.first(b"message", b"data: data");
+ newline = b"" if request.GET.first(b"newline", None) == b"none" else b"\n\n";
+ sleep = int(request.GET.first(b"sleep", b"0"))
+
+ headers = [(b"Content-Type", mime)]
+ body = message + newline + b"\n"
+ if sleep != 0:
+ time.sleep(sleep/1000)
+
+ return headers, body
diff --git a/testing/web-platform/tests/eventsource/resources/message2.py b/testing/web-platform/tests/eventsource/resources/message2.py
new file mode 100644
index 0000000000..8515e7b25e
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/message2.py
@@ -0,0 +1,33 @@
+import time
+
+def main(request, response):
+ response.headers.set(b'Content-Type', b'text/event-stream')
+ response.headers.set(b'Cache-Control', b'no-cache')
+
+ response.write_status_headers()
+
+ while True:
+ response.writer.write(u"data:msg")
+ response.writer.write(u"\n")
+ response.writer.write(u"data: msg")
+ response.writer.write(u"\n\n")
+
+ response.writer.write(u":")
+ response.writer.write(u"\n")
+
+ response.writer.write(u"falsefield:msg")
+ response.writer.write(u"\n\n")
+
+ response.writer.write(u"falsefield:msg")
+ response.writer.write(u"\n")
+
+ response.writer.write(u"Data:data")
+ response.writer.write(u"\n\n")
+
+ response.writer.write(u"data")
+ response.writer.write(u"\n\n")
+
+ response.writer.write(u"data:end")
+ response.writer.write(u"\n\n")
+
+ time.sleep(2)
diff --git a/testing/web-platform/tests/eventsource/resources/reconnect-fail.py b/testing/web-platform/tests/eventsource/resources/reconnect-fail.py
new file mode 100644
index 0000000000..12b07700cd
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/reconnect-fail.py
@@ -0,0 +1,24 @@
+def main(request, response):
+ name = b"recon_fail_" + request.GET.first(b"id")
+
+ headers = [(b"Content-Type", b"text/event-stream")]
+ cookie = request.cookies.first(name, None)
+ state = cookie.value if cookie is not None else None
+
+ if state == b'opened':
+ status = (200, b"RECONNECT")
+ response.set_cookie(name, b"reconnected");
+ body = b"data: reconnected\n\n";
+
+ elif state == b'reconnected':
+ status = (204, b"NO CONTENT (CLOSE)")
+ response.delete_cookie(name);
+ body = b"data: closed\n\n" # Will never get through
+
+ else:
+ status = (200, b"OPEN");
+ response.set_cookie(name, b"opened");
+ body = b"retry: 2\ndata: opened\n\n";
+
+ return status, headers, body
+
diff --git a/testing/web-platform/tests/eventsource/resources/status-error.py b/testing/web-platform/tests/eventsource/resources/status-error.py
new file mode 100644
index 0000000000..ed5687b6c2
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/status-error.py
@@ -0,0 +1,15 @@
+def main(request, response):
+ status = (request.GET.first(b"status", b"404"), b"HAHAHAHA")
+ headers = [(b"Content-Type", b"text/event-stream")]
+
+ # According to RFC7231, HTTP responses bearing status code 204 or 205 must
+ # not specify a body. The expected browser behavior for this condition is not
+ # currently defined--see the following for further discussion:
+ #
+ # https://github.com/web-platform-tests/wpt/pull/5227
+ if status[0] in [b"204", b"205"]:
+ body = b""
+ else:
+ body = b"data: data\n\n"
+
+ return status, headers, body
diff --git a/testing/web-platform/tests/eventsource/resources/status-reconnect.py b/testing/web-platform/tests/eventsource/resources/status-reconnect.py
new file mode 100644
index 0000000000..a59f751fc3
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/resources/status-reconnect.py
@@ -0,0 +1,21 @@
+def main(request, response):
+ status_code = request.GET.first(b"status", b"204")
+ name = request.GET.first(b"id", status_code)
+
+ headers = [(b"Content-Type", b"text/event-stream")]
+
+ cookie_name = b"request" + name
+
+ if request.cookies.first(cookie_name, b"") == status_code:
+ status = 200
+ response.delete_cookie(cookie_name)
+ body = b"data: data\n\n"
+ else:
+ response.set_cookie(cookie_name, status_code);
+ status = (int(status_code), b"TEST")
+ body = b"retry: 2\n"
+ if b"ok_first" in request.GET:
+ body += b"data: ok\n\n"
+
+ return status, headers, body
+
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-close.htm b/testing/web-platform/tests/eventsource/shared-worker/eventsource-close.htm
new file mode 100644
index 0000000000..30fbc309ab
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-close.htm
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>shared worker - EventSource: close()</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 worker = new SharedWorker('eventsource-close.js')
+ worker.port.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_equals(e.data[1], EventSource.CLOSED, 'this.readyState')
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-close.js b/testing/web-platform/tests/eventsource/shared-worker/eventsource-close.js
new file mode 100644
index 0000000000..8d160b605f
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-close.js
@@ -0,0 +1,12 @@
+onconnect = function(e) {
+try {
+ var port = e.ports[0]
+ var source = new EventSource("../resources/message.py")
+ source.onopen = function(e) {
+ this.close()
+ port.postMessage([true, this.readyState])
+ }
+} catch(e) {
+ port.postMessage([false, String(e)])
+}
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.htm b/testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.htm
new file mode 100644
index 0000000000..690cde3600
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.htm
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>shared worker - EventSource: constructor (act as if there is a network error)</title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function fetchFail(url) {
+ var test = async_test(document.title + " (" + url + ")")
+ test.step(function() {
+ var worker = new SharedWorker('eventsource-constructor-non-same-origin.js#'+encodeURIComponent(url))
+ worker.port.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_equals(e.data[1], EventSource.CLOSED, 'source.readyState')
+ assert_false(e.data[2], "'data' in e");
+ })
+ test.done()
+ }
+ })
+ }
+ fetchFail("ftp://example.not")
+ fetchFail("about:blank")
+ fetchFail("mailto:whatwg@awesome.example")
+ fetchFail("javascript:alert('FAIL')")
+ </script>
+ <!-- This tests "fails the connection" as well as making sure a simple
+ event is dispatched and not a MessageEvent -->
+ </body>
+</html>
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.js b/testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.js
new file mode 100644
index 0000000000..a68dc5b0b7
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.js
@@ -0,0 +1,13 @@
+onconnect = function(e) {
+try {
+ var port = e.ports[0]
+ var url = decodeURIComponent(location.hash.substr(1))
+ var source = new EventSource(url)
+ source.onerror = function(e) {
+ port.postMessage([true, this.readyState, 'data' in e])
+ this.close();
+ }
+} catch(e) {
+ port.postMessage([false, String(e)])
+}
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-url-bogus.js b/testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-url-bogus.js
new file mode 100644
index 0000000000..80847357b5
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-constructor-url-bogus.js
@@ -0,0 +1,10 @@
+onconnect = function(e) {
+try {
+ var port = e.ports[0]
+ var source = new EventSource("http://this is invalid/")
+ port.postMessage([false, 'no exception thrown'])
+ source.close()
+} catch(e) {
+ port.postMessage([true, e.code])
+}
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-eventtarget.htm b/testing/web-platform/tests/eventsource/shared-worker/eventsource-eventtarget.htm
new file mode 100644
index 0000000000..f25509dfd4
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-eventtarget.htm
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>shared worker - EventSource: addEventListener()</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 worker = new SharedWorker('eventsource-eventtarget.js')
+ worker.port.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_equals(e.data[1], 'data', 'e.data')
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-eventtarget.js b/testing/web-platform/tests/eventsource/shared-worker/eventsource-eventtarget.js
new file mode 100644
index 0000000000..761165118a
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-eventtarget.js
@@ -0,0 +1,13 @@
+onconnect = function(e) {
+try {
+ var port = e.ports[0]
+ var source = new EventSource("../resources/message.py")
+ source.addEventListener("message", listener, false)
+ function listener(e) {
+ port.postMessage([true, e.data])
+ this.close()
+ }
+} catch(e) {
+ port.postMessage([false, String(e)])
+}
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-onmesage.js b/testing/web-platform/tests/eventsource/shared-worker/eventsource-onmesage.js
new file mode 100644
index 0000000000..f5e2c898df
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-onmesage.js
@@ -0,0 +1,12 @@
+onconnect = function(e) {
+try {
+ var port = e.ports[0]
+ var source = new EventSource("../resources/message.py")
+ source.onmessage = function(e) {
+ port.postMessage([true, e.data])
+ this.close()
+ }
+} catch(e) {
+ port.postMessage([false, String(e)])
+}
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-onmessage.htm b/testing/web-platform/tests/eventsource/shared-worker/eventsource-onmessage.htm
new file mode 100644
index 0000000000..bcd6093454
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-onmessage.htm
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>shared worker - EventSource: onmessage</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 worker = new SharedWorker('eventsource-onmesage.js')
+ worker.port.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_equals(e.data[1], "data", 'e.data')
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-onopen.htm b/testing/web-platform/tests/eventsource/shared-worker/eventsource-onopen.htm
new file mode 100644
index 0000000000..752a6e449f
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-onopen.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+ <head>
+ <title>shared worker - EventSource: onopen (announcing the connection)</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 worker = new SharedWorker('eventsource-onopen.js')
+ worker.port.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_equals(e.data[1], EventSource.OPEN, 'source.readyState')
+ assert_false(e.data[2], "'data' in e")
+ assert_false(e.data[3], 'e.bubbles')
+ assert_false(e.data[4], 'e.calcelable')
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-onopen.js b/testing/web-platform/tests/eventsource/shared-worker/eventsource-onopen.js
new file mode 100644
index 0000000000..6dc9424a21
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-onopen.js
@@ -0,0 +1,12 @@
+onconnect = function(e) {
+try {
+ var port = e.ports[0]
+ var source = new EventSource("../resources/message.py")
+ source.onopen = function(e) {
+ port.postMessage([true, source.readyState, 'data' in e, e.bubbles, e.cancelable])
+ this.close()
+ }
+} catch(e) {
+ port.postMessage([false, String(e)])
+}
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-prototype.htm b/testing/web-platform/tests/eventsource/shared-worker/eventsource-prototype.htm
new file mode 100644
index 0000000000..16c932a338
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-prototype.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <heAd>
+ <title>shared worker - EventSource: prototype et al</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 worker = new SharedWorker('eventsource-prototype.js')
+ worker.port.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1])
+ assert_true(e.data[1], 'source.ReturnTrue()')
+ assert_true(e.data[2], "'EventSource' in self")
+ })
+ test.done()
+ }
+ })
+ </scrIpt>
+ </bOdy>
+</htMl> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-prototype.js b/testing/web-platform/tests/eventsource/shared-worker/eventsource-prototype.js
new file mode 100644
index 0000000000..f4c809a9b3
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-prototype.js
@@ -0,0 +1,11 @@
+onconnect = function(e) {
+try {
+ var port = e.ports[0]
+ EventSource.prototype.ReturnTrue = function() { return true }
+ var source = new EventSource("../resources/message.py")
+ port.postMessage([true, source.ReturnTrue(), 'EventSource' in self])
+ source.close()
+} catch(e) {
+ port.postMessage([false, String(e)])
+}
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-url.htm b/testing/web-platform/tests/eventsource/shared-worker/eventsource-url.htm
new file mode 100644
index 0000000000..a1c9ca8455
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-url.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>shared worker - EventSource: url</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 url = "resources/message.py"
+ var worker = new SharedWorker('eventsource-url.js')
+ worker.port.onmessage = function(e) {
+ test.step(function() {
+ assert_true(e.data[0], e.data[1]);
+ assert_equals(e.data[1].substr(-(url.length)), url)
+ })
+ test.done()
+ }
+ })
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/eventsource/shared-worker/eventsource-url.js b/testing/web-platform/tests/eventsource/shared-worker/eventsource-url.js
new file mode 100644
index 0000000000..491dbac333
--- /dev/null
+++ b/testing/web-platform/tests/eventsource/shared-worker/eventsource-url.js
@@ -0,0 +1,10 @@
+onconnect = function(e) {
+try {
+ var port = e.ports[0]
+ var source = new EventSource("../resources/message.py")
+ port.postMessage([true, source.url])
+ source.close()
+} catch(e) {
+ port.postMessage([false, String(e)])
+}
+} \ No newline at end of file