Rebase WPT streams tests up to 8d1dc42
https://bugs.webkit.org/show_bug.cgi?id=235580

Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

Rebased WPT stream tests and expectations from WPT ToT.

* web-platform-tests/streams: Refreshed.

LayoutTests:

* platform/mac-wk1/TestExpectations: Skipping service worker tests.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@288616 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 6804f27..115272f 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,12 @@
+2022-01-26  Youenn Fablet  <youenn@apple.com>
+
+        Rebase WPT streams tests up to 8d1dc42
+        https://bugs.webkit.org/show_bug.cgi?id=235580
+
+        Reviewed by Chris Dumez.
+
+        * platform/mac-wk1/TestExpectations: Skipping service worker tests.
+
 2022-01-26  Kimmo Kinnunen  <kkinnunen@apple.com>
 
         WebGL conformance tests that are pending upstreaming should not duplicate unmodified files
diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog
index 0d057c2..05529ed 100644
--- a/LayoutTests/imported/w3c/ChangeLog
+++ b/LayoutTests/imported/w3c/ChangeLog
@@ -1,3 +1,14 @@
+2022-01-26  Youenn Fablet  <youenn@apple.com>
+
+        Rebase WPT streams tests up to 8d1dc42
+        https://bugs.webkit.org/show_bug.cgi?id=235580
+
+        Reviewed by Chris Dumez.
+
+        Rebased WPT stream tests and expectations from WPT ToT.
+
+        * web-platform-tests/streams: Refreshed.
+
 2022-01-25  Alexey Shvayka  <ashvayka@apple.com>
 
         [WebIDL] Blob-related methods should use _relevant_ context instead of _current_
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/idlharness.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/idlharness.any.serviceworker-expected.txt
new file mode 100644
index 0000000..5894856
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/idlharness.any.serviceworker-expected.txt
@@ -0,0 +1,238 @@
+
+PASS idl_test setup
+PASS idl_test validation
+PASS ReadableStreamDefaultReader includes ReadableStreamGenericReader: member names are unique
+PASS ReadableStreamBYOBReader includes ReadableStreamGenericReader: member names are unique
+PASS ReadableStream interface: existence and properties of interface object
+PASS ReadableStream interface object length
+PASS ReadableStream interface object name
+PASS ReadableStream interface: existence and properties of interface prototype object
+PASS ReadableStream interface: existence and properties of interface prototype object's "constructor" property
+PASS ReadableStream interface: existence and properties of interface prototype object's @@unscopables property
+FAIL ReadableStream interface: attribute locked assert_true: property should be enumerable expected true got false
+FAIL ReadableStream interface: operation cancel(optional any) assert_true: property should be enumerable expected true got false
+FAIL ReadableStream interface: operation getReader(optional ReadableStreamGetReaderOptions) assert_true: property should be enumerable expected true got false
+FAIL ReadableStream interface: operation pipeThrough(ReadableWritablePair, optional StreamPipeOptions) assert_true: property should be enumerable expected true got false
+FAIL ReadableStream interface: operation pipeTo(WritableStream, optional StreamPipeOptions) assert_true: property should be enumerable expected true got false
+FAIL ReadableStream interface: operation tee() assert_true: property should be enumerable expected true got false
+FAIL ReadableStream interface: async iterable<any> undefined is not an object (evaluating 'iteratorDesc.writable')
+PASS ReadableStream must be primary interface of new ReadableStream()
+PASS Stringification of new ReadableStream()
+PASS ReadableStream interface: new ReadableStream() must inherit property "locked" with the proper type
+PASS ReadableStream interface: new ReadableStream() must inherit property "cancel(optional any)" with the proper type
+PASS ReadableStream interface: calling cancel(optional any) on new ReadableStream() with too few arguments must throw TypeError
+PASS ReadableStream interface: new ReadableStream() must inherit property "getReader(optional ReadableStreamGetReaderOptions)" with the proper type
+PASS ReadableStream interface: calling getReader(optional ReadableStreamGetReaderOptions) on new ReadableStream() with too few arguments must throw TypeError
+PASS ReadableStream interface: new ReadableStream() must inherit property "pipeThrough(ReadableWritablePair, optional StreamPipeOptions)" with the proper type
+PASS ReadableStream interface: calling pipeThrough(ReadableWritablePair, optional StreamPipeOptions) on new ReadableStream() with too few arguments must throw TypeError
+PASS ReadableStream interface: new ReadableStream() must inherit property "pipeTo(WritableStream, optional StreamPipeOptions)" with the proper type
+PASS ReadableStream interface: calling pipeTo(WritableStream, optional StreamPipeOptions) on new ReadableStream() with too few arguments must throw TypeError
+PASS ReadableStream interface: new ReadableStream() must inherit property "tee()" with the proper type
+FAIL ReadableStreamDefaultReader interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader interface object length assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader interface object name assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader interface: operation read() assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader interface: operation releaseLock() assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader interface: attribute closed assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader interface: operation cancel(optional any) assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+FAIL ReadableStreamDefaultReader must be primary interface of (new ReadableStream()).getReader() assert_own_property: self does not have own property "ReadableStreamDefaultReader" expected property "ReadableStreamDefaultReader" missing
+PASS Stringification of (new ReadableStream()).getReader()
+PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "read()" with the proper type
+PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "releaseLock()" with the proper type
+PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "closed" with the proper type
+PASS ReadableStreamDefaultReader interface: (new ReadableStream()).getReader() must inherit property "cancel(optional any)" with the proper type
+PASS ReadableStreamDefaultReader interface: calling cancel(optional any) on (new ReadableStream()).getReader() with too few arguments must throw TypeError
+FAIL ReadableStreamBYOBReader interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader interface object length assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader interface object name assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader interface: operation read(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader interface: operation releaseLock() assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader interface: attribute closed assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader interface: operation cancel(optional any) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+FAIL ReadableStreamBYOBReader must be primary interface of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) assert_own_property: self does not have own property "ReadableStreamBYOBReader" expected property "ReadableStreamBYOBReader" missing
+PASS Stringification of (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' })
+PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "read(ArrayBufferView)" with the proper type
+PASS ReadableStreamBYOBReader interface: calling read(ArrayBufferView) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError
+PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "releaseLock()" with the proper type
+PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "closed" with the proper type
+PASS ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property "cancel(optional any)" with the proper type
+PASS ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError
+FAIL ReadableStreamDefaultController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController interface object length assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController interface object name assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController interface: attribute desiredSize assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController interface: operation close() assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController interface: operation enqueue(optional any) assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController interface: operation error(optional any) assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+FAIL ReadableStreamDefaultController must be primary interface of self.readableStreamDefaultController assert_own_property: self does not have own property "ReadableStreamDefaultController" expected property "ReadableStreamDefaultController" missing
+PASS Stringification of self.readableStreamDefaultController
+PASS ReadableStreamDefaultController interface: self.readableStreamDefaultController must inherit property "desiredSize" with the proper type
+PASS ReadableStreamDefaultController interface: self.readableStreamDefaultController must inherit property "close()" with the proper type
+PASS ReadableStreamDefaultController interface: self.readableStreamDefaultController must inherit property "enqueue(optional any)" with the proper type
+PASS ReadableStreamDefaultController interface: calling enqueue(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError
+PASS ReadableStreamDefaultController interface: self.readableStreamDefaultController must inherit property "error(optional any)" with the proper type
+PASS ReadableStreamDefaultController interface: calling error(optional any) on self.readableStreamDefaultController with too few arguments must throw TypeError
+FAIL ReadableByteStreamController interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface object length assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface object name assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface: attribute byobRequest assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface: attribute desiredSize assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface: operation close() assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface: operation enqueue(ArrayBufferView) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController interface: operation error(optional any) assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+FAIL ReadableByteStreamController must be primary interface of self.readableByteStreamController assert_own_property: self does not have own property "ReadableByteStreamController" expected property "ReadableByteStreamController" missing
+PASS Stringification of self.readableByteStreamController
+FAIL ReadableByteStreamController interface: self.readableByteStreamController must inherit property "byobRequest" with the proper type assert_in_array: wrong type: not object or function value "undefined" not in array ["object", "function"]
+PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "desiredSize" with the proper type
+PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "close()" with the proper type
+PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "enqueue(ArrayBufferView)" with the proper type
+PASS ReadableByteStreamController interface: calling enqueue(ArrayBufferView) on self.readableByteStreamController with too few arguments must throw TypeError
+PASS ReadableByteStreamController interface: self.readableByteStreamController must inherit property "error(optional any)" with the proper type
+PASS ReadableByteStreamController interface: calling error(optional any) on self.readableByteStreamController with too few arguments must throw TypeError
+FAIL ReadableStreamBYOBRequest interface: existence and properties of interface object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+FAIL ReadableStreamBYOBRequest interface object length assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+FAIL ReadableStreamBYOBRequest interface object name assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+FAIL ReadableStreamBYOBRequest interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+FAIL ReadableStreamBYOBRequest interface: attribute view assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+FAIL ReadableStreamBYOBRequest interface: operation respond(unsigned long long) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+FAIL ReadableStreamBYOBRequest interface: operation respondWithNewView(ArrayBufferView) assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+FAIL ReadableStreamBYOBRequest must be primary interface of self.readableStreamByobRequest assert_own_property: self does not have own property "ReadableStreamBYOBRequest" expected property "ReadableStreamBYOBRequest" missing
+PASS Stringification of self.readableStreamByobRequest
+PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "view" with the proper type
+PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respond(unsigned long long)" with the proper type
+FAIL ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError assert_throws_js: Called with 0 arguments function "function () {
+            fn.apply(obj, args);
+        }" threw object "RangeError: bytesWritten has an incorrect value" ("RangeError") expected instance of function "function TypeError() {
+    [native code]
+}" ("TypeError")
+PASS ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property "respondWithNewView(ArrayBufferView)" with the proper type
+PASS ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError
+PASS WritableStream interface: existence and properties of interface object
+PASS WritableStream interface object length
+PASS WritableStream interface object name
+PASS WritableStream interface: existence and properties of interface prototype object
+PASS WritableStream interface: existence and properties of interface prototype object's "constructor" property
+PASS WritableStream interface: existence and properties of interface prototype object's @@unscopables property
+PASS WritableStream interface: attribute locked
+PASS WritableStream interface: operation abort(optional any)
+PASS WritableStream interface: operation close()
+PASS WritableStream interface: operation getWriter()
+PASS WritableStream must be primary interface of new WritableStream()
+PASS Stringification of new WritableStream()
+PASS WritableStream interface: new WritableStream() must inherit property "locked" with the proper type
+PASS WritableStream interface: new WritableStream() must inherit property "abort(optional any)" with the proper type
+PASS WritableStream interface: calling abort(optional any) on new WritableStream() with too few arguments must throw TypeError
+PASS WritableStream interface: new WritableStream() must inherit property "close()" with the proper type
+PASS WritableStream interface: new WritableStream() must inherit property "getWriter()" with the proper type
+PASS WritableStreamDefaultWriter interface: existence and properties of interface object
+PASS WritableStreamDefaultWriter interface object length
+PASS WritableStreamDefaultWriter interface object name
+PASS WritableStreamDefaultWriter interface: existence and properties of interface prototype object
+PASS WritableStreamDefaultWriter interface: existence and properties of interface prototype object's "constructor" property
+PASS WritableStreamDefaultWriter interface: existence and properties of interface prototype object's @@unscopables property
+PASS WritableStreamDefaultWriter interface: attribute closed
+PASS WritableStreamDefaultWriter interface: attribute desiredSize
+PASS WritableStreamDefaultWriter interface: attribute ready
+FAIL WritableStreamDefaultWriter interface: operation abort(optional any) assert_equals: property has wrong .length expected 0 but got 1
+PASS WritableStreamDefaultWriter interface: operation close()
+PASS WritableStreamDefaultWriter interface: operation releaseLock()
+FAIL WritableStreamDefaultWriter interface: operation write(optional any) assert_equals: property has wrong .length expected 0 but got 1
+PASS WritableStreamDefaultWriter must be primary interface of (new WritableStream()).getWriter()
+PASS Stringification of (new WritableStream()).getWriter()
+PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "closed" with the proper type
+PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "desiredSize" with the proper type
+PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "ready" with the proper type
+PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "abort(optional any)" with the proper type
+PASS WritableStreamDefaultWriter interface: calling abort(optional any) on (new WritableStream()).getWriter() with too few arguments must throw TypeError
+PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "close()" with the proper type
+PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "releaseLock()" with the proper type
+PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "write(optional any)" with the proper type
+PASS WritableStreamDefaultWriter interface: calling write(optional any) on (new WritableStream()).getWriter() with too few arguments must throw TypeError
+FAIL WritableStreamDefaultController interface: existence and properties of interface object assert_throws_js: interface object didn't throw TypeError when called as a constructor function "function () {
+                new interface_object();
+            }" did not throw
+PASS WritableStreamDefaultController interface object length
+PASS WritableStreamDefaultController interface object name
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property
+FAIL WritableStreamDefaultController interface: operation error(optional any) assert_equals: property has wrong .length expected 0 but got 1
+PASS WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController
+PASS Stringification of self.writableStreamDefaultController
+PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "error(optional any)" with the proper type
+PASS WritableStreamDefaultController interface: calling error(optional any) on self.writableStreamDefaultController with too few arguments must throw TypeError
+PASS TransformStream interface: existence and properties of interface object
+PASS TransformStream interface object length
+PASS TransformStream interface object name
+PASS TransformStream interface: existence and properties of interface prototype object
+PASS TransformStream interface: existence and properties of interface prototype object's "constructor" property
+PASS TransformStream interface: existence and properties of interface prototype object's @@unscopables property
+PASS TransformStream interface: attribute readable
+FAIL TransformStream interface: attribute writable assert_equals: getter must have the name 'get writable' expected "get writable" but got "writable"
+PASS TransformStream must be primary interface of new TransformStream()
+PASS Stringification of new TransformStream()
+PASS TransformStream interface: new TransformStream() must inherit property "readable" with the proper type
+PASS TransformStream interface: new TransformStream() must inherit property "writable" with the proper type
+FAIL TransformStreamDefaultController interface: existence and properties of interface object assert_throws_js: interface object didn't throw TypeError when called as a constructor function "function () {
+                new interface_object();
+            }" did not throw
+PASS TransformStreamDefaultController interface object length
+PASS TransformStreamDefaultController interface object name
+PASS TransformStreamDefaultController interface: existence and properties of interface prototype object
+PASS TransformStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property
+PASS TransformStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property
+PASS TransformStreamDefaultController interface: attribute desiredSize
+FAIL TransformStreamDefaultController interface: operation enqueue(optional any) assert_equals: property has wrong .length expected 0 but got 1
+FAIL TransformStreamDefaultController interface: operation error(optional any) assert_equals: property has wrong .length expected 0 but got 1
+PASS TransformStreamDefaultController interface: operation terminate()
+PASS TransformStreamDefaultController must be primary interface of self.transformStreamDefaultController
+PASS Stringification of self.transformStreamDefaultController
+PASS TransformStreamDefaultController interface: self.transformStreamDefaultController must inherit property "desiredSize" with the proper type
+PASS TransformStreamDefaultController interface: self.transformStreamDefaultController must inherit property "enqueue(optional any)" with the proper type
+PASS TransformStreamDefaultController interface: calling enqueue(optional any) on self.transformStreamDefaultController with too few arguments must throw TypeError
+PASS TransformStreamDefaultController interface: self.transformStreamDefaultController must inherit property "error(optional any)" with the proper type
+PASS TransformStreamDefaultController interface: calling error(optional any) on self.transformStreamDefaultController with too few arguments must throw TypeError
+PASS TransformStreamDefaultController interface: self.transformStreamDefaultController must inherit property "terminate()" with the proper type
+PASS ByteLengthQueuingStrategy interface: existence and properties of interface object
+PASS ByteLengthQueuingStrategy interface object length
+PASS ByteLengthQueuingStrategy interface object name
+PASS ByteLengthQueuingStrategy interface: existence and properties of interface prototype object
+PASS ByteLengthQueuingStrategy interface: existence and properties of interface prototype object's "constructor" property
+PASS ByteLengthQueuingStrategy interface: existence and properties of interface prototype object's @@unscopables property
+PASS ByteLengthQueuingStrategy interface: attribute highWaterMark
+FAIL ByteLengthQueuingStrategy interface: attribute size assert_throws_js: getting property on prototype object must throw TypeError function "function () {
+    [native code]
+}" did not throw
+PASS ByteLengthQueuingStrategy must be primary interface of new ByteLengthQueuingStrategy({ highWaterMark: 5 })
+PASS Stringification of new ByteLengthQueuingStrategy({ highWaterMark: 5 })
+PASS ByteLengthQueuingStrategy interface: new ByteLengthQueuingStrategy({ highWaterMark: 5 }) must inherit property "highWaterMark" with the proper type
+PASS ByteLengthQueuingStrategy interface: new ByteLengthQueuingStrategy({ highWaterMark: 5 }) must inherit property "size" with the proper type
+PASS CountQueuingStrategy interface: existence and properties of interface object
+PASS CountQueuingStrategy interface object length
+PASS CountQueuingStrategy interface object name
+PASS CountQueuingStrategy interface: existence and properties of interface prototype object
+PASS CountQueuingStrategy interface: existence and properties of interface prototype object's "constructor" property
+PASS CountQueuingStrategy interface: existence and properties of interface prototype object's @@unscopables property
+PASS CountQueuingStrategy interface: attribute highWaterMark
+FAIL CountQueuingStrategy interface: attribute size assert_throws_js: getting property on prototype object must throw TypeError function "function () {
+    [native code]
+}" did not throw
+PASS CountQueuingStrategy must be primary interface of new CountQueuingStrategy({ highWaterMark: 5 })
+PASS Stringification of new CountQueuingStrategy({ highWaterMark: 5 })
+PASS CountQueuingStrategy interface: new CountQueuingStrategy({ highWaterMark: 5 }) must inherit property "highWaterMark" with the proper type
+PASS CountQueuingStrategy interface: new CountQueuingStrategy({ highWaterMark: 5 }) must inherit property "size" with the proper type
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/idlharness.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/idlharness.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/idlharness.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any-expected.txt
index 804fcc7..e8ea40a 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any-expected.txt
@@ -7,12 +7,18 @@
 PASS a signal argument '-1' should cause pipeTo() to reject
 PASS a signal argument '[object AbortSignal]' should cause pipeTo() to reject
 PASS an aborted signal should cause the writable stream to reject with an AbortError
-PASS all the AbortError objects should be the same object
+FAIL (reason: 'null') all the error objects should be the same object promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw null
+FAIL (reason: 'undefined') all the error objects should be the same object assert_equals: signal.reason should be error expected object "AbortError: abort pipeTo from signal" but got object "AbortError: The operation was aborted."
+FAIL (reason: 'error1: error1') all the error objects should be the same object promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw object "error1: error1"
 PASS preventCancel should prevent canceling the readable
 PASS preventAbort should prevent aborting the readable
 PASS preventCancel and preventAbort should prevent canceling the readable and aborting the readable
-PASS abort should prevent further reads
-PASS all pending writes should complete on abort
+FAIL (reason: 'null') abort should prevent further reads promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw null
+FAIL (reason: 'undefined') abort should prevent further reads assert_equals: signal.reason should be error expected object "AbortError: abort pipeTo from signal" but got object "AbortError: The operation was aborted."
+FAIL (reason: 'error1: error1') abort should prevent further reads promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw object "error1: error1"
+FAIL (reason: 'null') all pending writes should complete on abort promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw null
+FAIL (reason: 'undefined') all pending writes should complete on abort assert_equals: signal.reason should be error expected object "AbortError: abort pipeTo from signal" but got object "AbortError: The operation was aborted."
+FAIL (reason: 'error1: error1') all pending writes should complete on abort promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw object "error1: error1"
 PASS a rejection from underlyingSource.cancel() should be returned by pipeTo()
 PASS a rejection from underlyingSink.abort() should be returned by pipeTo()
 PASS a rejection from underlyingSink.abort() should be preferred to one from underlyingSource.cancel()
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.js b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.js
index 3fe029d..bb62dc8 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.js
@@ -53,29 +53,28 @@
       });
 }, 'an aborted signal should cause the writable stream to reject with an AbortError');
 
-promise_test(() => {
-  let error;
-  const rs = recordingReadableStream(errorOnPull, hwm0);
-  const ws = new WritableStream();
-  const abortController = new AbortController();
-  const signal = abortController.signal;
-  abortController.abort();
-  return rs.pipeTo(ws, { signal })
-      .catch(e => {
-        error = e;
-      })
-      .then(() => Promise.all([
-        rs.getReader().closed,
-        ws.getWriter().closed.catch(e => {
-          assert_equals(e, error, 'the writable should be errored with the same object');
-        })
-      ]))
-  .then(() => {
+for (const reason of [null, undefined, error1]) {
+  promise_test(async t => {
+    const rs = recordingReadableStream(errorOnPull, hwm0);
+    const ws = new WritableStream();
+    const abortController = new AbortController();
+    const signal = abortController.signal;
+    abortController.abort(reason);
+    const pipeToPromise = rs.pipeTo(ws, { signal });
+    if (reason !== undefined) {
+      await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason');
+    } else {
+      await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError');
+    }
+    const error = await pipeToPromise.catch(e => e);
+    await rs.getReader().closed;
+    await promise_rejects_exactly(t, error, ws.getWriter().closed, 'the writable should be errored with the same object');
+    assert_equals(signal.reason, error, 'signal.reason should be error'),
     assert_equals(rs.events.length, 2, 'cancel should have been called');
     assert_equals(rs.events[0], 'cancel', 'first event should be cancel');
     assert_equals(rs.events[1], error, 'the readable should be canceled with the same object');
-  });
-}, 'all the AbortError objects should be the same object');
+  }, `(reason: '${reason}') all the error objects should be the same object`);
+}
 
 promise_test(t => {
   const rs = recordingReadableStream(errorOnPull, hwm0);
@@ -115,61 +114,74 @@
     });
 }, 'preventCancel and preventAbort should prevent canceling the readable and aborting the readable');
 
-promise_test(t => {
-  const rs = new ReadableStream({
-    start(controller) {
-      controller.enqueue('a');
-      controller.enqueue('b');
-      controller.close();
+for (const reason of [null, undefined, error1]) {
+  promise_test(async t => {
+    const rs = new ReadableStream({
+      start(controller) {
+        controller.enqueue('a');
+        controller.enqueue('b');
+        controller.close();
+      }
+    });
+    const abortController = new AbortController();
+    const signal = abortController.signal;
+    const ws = recordingWritableStream({
+      write() {
+        abortController.abort(reason);
+      }
+    });
+    const pipeToPromise = rs.pipeTo(ws, { signal });
+    if (reason !== undefined) {
+      await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason');
+    } else {
+      await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError');
     }
-  });
-  const abortController = new AbortController();
-  const signal = abortController.signal;
-  const ws = recordingWritableStream({
-    write() {
-      abortController.abort();
-    }
-  });
-  return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject')
-      .then(() => {
-        assert_equals(ws.events.length, 4, 'only chunk "a" should have been written');
-        assert_array_equals(ws.events.slice(0, 3), ['write', 'a', 'abort'], 'events should match');
-        assert_equals(ws.events[3].name, 'AbortError', 'abort reason should be an AbortError');
-      });
-}, 'abort should prevent further reads');
+    const error = await pipeToPromise.catch(e => e);
+    assert_equals(signal.reason, error, 'signal.reason should be error');
+    assert_equals(ws.events.length, 4, 'only chunk "a" should have been written');
+    assert_array_equals(ws.events.slice(0, 3), ['write', 'a', 'abort'], 'events should match');
+    assert_equals(ws.events[3], error, 'abort reason should be error');
+  }, `(reason: '${reason}') abort should prevent further reads`);
+}
 
-promise_test(t => {
-  let readController;
-  const rs = new ReadableStream({
-    start(c) {
-      readController = c;
-      c.enqueue('a');
-      c.enqueue('b');
+for (const reason of [null, undefined, error1]) {
+  promise_test(async t => {
+    let readController;
+    const rs = new ReadableStream({
+      start(c) {
+        readController = c;
+        c.enqueue('a');
+        c.enqueue('b');
+      }
+    });
+    const abortController = new AbortController();
+    const signal = abortController.signal;
+    let resolveWrite;
+    const writePromise = new Promise(resolve => {
+      resolveWrite = resolve;
+    });
+    const ws = recordingWritableStream({
+      write() {
+        return writePromise;
+      }
+    }, new CountQueuingStrategy({ highWaterMark: Infinity }));
+    const pipeToPromise = rs.pipeTo(ws, { signal });
+    await delay(0);
+    await abortController.abort(reason);
+    await readController.close(); // Make sure the test terminates when signal is not implemented.
+    await resolveWrite();
+    if (reason !== undefined) {
+      await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason');
+    } else {
+      await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError');
     }
-  });
-  const abortController = new AbortController();
-  const signal = abortController.signal;
-  let resolveWrite;
-  const writePromise = new Promise(resolve => {
-    resolveWrite = resolve;
-  });
-  const ws = recordingWritableStream({
-    write() {
-      return writePromise;
-    }
-  }, new CountQueuingStrategy({ highWaterMark: Infinity }));
-  const pipeToPromise = rs.pipeTo(ws, { signal });
-  return delay(0).then(() => {
-    abortController.abort();
-    readController.close(); // Make sure the test terminates when signal is not implemented.
-    resolveWrite();
-    return promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo should reject');
-  }).then(() => {
+    const error = await pipeToPromise.catch(e => e);
+    assert_equals(signal.reason, error, 'signal.reason should be error');
     assert_equals(ws.events.length, 6, 'chunks "a" and "b" should have been written');
     assert_array_equals(ws.events.slice(0, 5), ['write', 'a', 'write', 'b', 'abort'], 'events should match');
-    assert_equals(ws.events[5].name, 'AbortError', 'abort reason should be an AbortError');
-  });
-}, 'all pending writes should complete on abort');
+    assert_equals(ws.events[5], error, 'abort reason should be error');
+  }, `(reason: '${reason}') all pending writes should complete on abort`);
+}
 
 promise_test(t => {
   const rs = new ReadableStream({
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.serviceworker-expected.txt
new file mode 100644
index 0000000..e8ea40a
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.serviceworker-expected.txt
@@ -0,0 +1,33 @@
+
+Harness Error (FAIL), message = Unhandled rejection: error1
+
+PASS a signal argument 'null' should cause pipeTo() to reject
+PASS a signal argument 'AbortSignal' should cause pipeTo() to reject
+PASS a signal argument 'true' should cause pipeTo() to reject
+PASS a signal argument '-1' should cause pipeTo() to reject
+PASS a signal argument '[object AbortSignal]' should cause pipeTo() to reject
+PASS an aborted signal should cause the writable stream to reject with an AbortError
+FAIL (reason: 'null') all the error objects should be the same object promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw null
+FAIL (reason: 'undefined') all the error objects should be the same object assert_equals: signal.reason should be error expected object "AbortError: abort pipeTo from signal" but got object "AbortError: The operation was aborted."
+FAIL (reason: 'error1: error1') all the error objects should be the same object promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw object "error1: error1"
+PASS preventCancel should prevent canceling the readable
+PASS preventAbort should prevent aborting the readable
+PASS preventCancel and preventAbort should prevent canceling the readable and aborting the readable
+FAIL (reason: 'null') abort should prevent further reads promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw null
+FAIL (reason: 'undefined') abort should prevent further reads assert_equals: signal.reason should be error expected object "AbortError: abort pipeTo from signal" but got object "AbortError: The operation was aborted."
+FAIL (reason: 'error1: error1') abort should prevent further reads promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw object "error1: error1"
+FAIL (reason: 'null') all pending writes should complete on abort promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw null
+FAIL (reason: 'undefined') all pending writes should complete on abort assert_equals: signal.reason should be error expected object "AbortError: abort pipeTo from signal" but got object "AbortError: The operation was aborted."
+FAIL (reason: 'error1: error1') all pending writes should complete on abort promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw object "error1: error1"
+PASS a rejection from underlyingSource.cancel() should be returned by pipeTo()
+PASS a rejection from underlyingSink.abort() should be returned by pipeTo()
+PASS a rejection from underlyingSink.abort() should be preferred to one from underlyingSource.cancel()
+PASS abort signal takes priority over closed readable
+PASS abort signal takes priority over errored readable
+PASS abort signal takes priority over closed writable
+PASS abort signal takes priority over errored writable
+PASS abort should do nothing after the readable is closed
+PASS abort should do nothing after the readable is errored
+PASS abort should do nothing after the readable is errored, even with pending writes
+PASS abort should do nothing after the writable is errored
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.worker-expected.txt
index 804fcc7..e8ea40a 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.worker-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/abort.any.worker-expected.txt
@@ -7,12 +7,18 @@
 PASS a signal argument '-1' should cause pipeTo() to reject
 PASS a signal argument '[object AbortSignal]' should cause pipeTo() to reject
 PASS an aborted signal should cause the writable stream to reject with an AbortError
-PASS all the AbortError objects should be the same object
+FAIL (reason: 'null') all the error objects should be the same object promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw null
+FAIL (reason: 'undefined') all the error objects should be the same object assert_equals: signal.reason should be error expected object "AbortError: abort pipeTo from signal" but got object "AbortError: The operation was aborted."
+FAIL (reason: 'error1: error1') all the error objects should be the same object promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw object "error1: error1"
 PASS preventCancel should prevent canceling the readable
 PASS preventAbort should prevent aborting the readable
 PASS preventCancel and preventAbort should prevent canceling the readable and aborting the readable
-PASS abort should prevent further reads
-PASS all pending writes should complete on abort
+FAIL (reason: 'null') abort should prevent further reads promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw null
+FAIL (reason: 'undefined') abort should prevent further reads assert_equals: signal.reason should be error expected object "AbortError: abort pipeTo from signal" but got object "AbortError: The operation was aborted."
+FAIL (reason: 'error1: error1') abort should prevent further reads promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw object "error1: error1"
+FAIL (reason: 'null') all pending writes should complete on abort promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw null
+FAIL (reason: 'undefined') all pending writes should complete on abort assert_equals: signal.reason should be error expected object "AbortError: abort pipeTo from signal" but got object "AbortError: The operation was aborted."
+FAIL (reason: 'error1: error1') all pending writes should complete on abort promise_rejects_exactly: pipeTo rejects with abort reason function "function () { throw e }" threw object "AbortError: abort pipeTo from signal" but we expected it to throw object "error1: error1"
 PASS a rejection from underlyingSource.cancel() should be returned by pipeTo()
 PASS a rejection from underlyingSink.abort() should be returned by pipeTo()
 PASS a rejection from underlyingSink.abort() should be preferred to one from underlyingSource.cancel()
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-backward.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-backward.any.serviceworker-expected.txt
new file mode 100644
index 0000000..e3a65d4
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-backward.any.serviceworker-expected.txt
@@ -0,0 +1,20 @@
+
+Harness Error (FAIL), message = Unhandled rejection: releasing lock of reader whose stream is still in readable state
+
+PASS Closing must be propagated backward: starts closed; preventCancel omitted; fulfilled cancel promise
+PASS Closing must be propagated backward: starts closed; preventCancel omitted; rejected cancel promise
+PASS Closing must be propagated backward: starts closed; preventCancel = undefined (falsy); fulfilled cancel promise
+PASS Closing must be propagated backward: starts closed; preventCancel = null (falsy); fulfilled cancel promise
+PASS Closing must be propagated backward: starts closed; preventCancel = false (falsy); fulfilled cancel promise
+PASS Closing must be propagated backward: starts closed; preventCancel = 0 (falsy); fulfilled cancel promise
+PASS Closing must be propagated backward: starts closed; preventCancel = -0 (falsy); fulfilled cancel promise
+PASS Closing must be propagated backward: starts closed; preventCancel = NaN (falsy); fulfilled cancel promise
+PASS Closing must be propagated backward: starts closed; preventCancel =  (falsy); fulfilled cancel promise
+PASS Closing must be propagated backward: starts closed; preventCancel = true (truthy)
+PASS Closing must be propagated backward: starts closed; preventCancel = a (truthy)
+PASS Closing must be propagated backward: starts closed; preventCancel = 1 (truthy)
+PASS Closing must be propagated backward: starts closed; preventCancel = Symbol() (truthy)
+PASS Closing must be propagated backward: starts closed; preventCancel = [object Object] (truthy)
+PASS Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true
+PASS Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true, preventClose = true
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-backward.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-backward.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-backward.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-forward.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-forward.any.serviceworker-expected.txt
new file mode 100644
index 0000000..aed282a
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-forward.any.serviceworker-expected.txt
@@ -0,0 +1,32 @@
+
+PASS Closing must be propagated forward: starts closed; preventClose omitted; fulfilled close promise
+PASS Closing must be propagated forward: starts closed; preventClose omitted; rejected close promise
+PASS Closing must be propagated forward: starts closed; preventClose = undefined (falsy); fulfilled close promise
+PASS Closing must be propagated forward: starts closed; preventClose = null (falsy); fulfilled close promise
+PASS Closing must be propagated forward: starts closed; preventClose = false (falsy); fulfilled close promise
+PASS Closing must be propagated forward: starts closed; preventClose = 0 (falsy); fulfilled close promise
+PASS Closing must be propagated forward: starts closed; preventClose = -0 (falsy); fulfilled close promise
+PASS Closing must be propagated forward: starts closed; preventClose = NaN (falsy); fulfilled close promise
+PASS Closing must be propagated forward: starts closed; preventClose =  (falsy); fulfilled close promise
+PASS Closing must be propagated forward: starts closed; preventClose = true (truthy)
+PASS Closing must be propagated forward: starts closed; preventClose = a (truthy)
+PASS Closing must be propagated forward: starts closed; preventClose = 1 (truthy)
+PASS Closing must be propagated forward: starts closed; preventClose = Symbol() (truthy)
+PASS Closing must be propagated forward: starts closed; preventClose = [object Object] (truthy)
+PASS Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true
+PASS Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true, preventCancel = true
+PASS Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; fulfilled close promise
+PASS Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; rejected close promise
+PASS Closing must be propagated forward: becomes closed asynchronously; preventClose = true
+PASS Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; fulfilled close promise
+PASS Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; rejected close promise
+PASS Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose = true
+PASS Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; fulfilled close promise
+PASS Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; rejected close promise
+PASS Closing must be propagated forward: becomes closed after one chunk; preventClose = true
+PASS Closing must be propagated forward: shutdown must not occur until the final write completes
+PASS Closing must be propagated forward: shutdown must not occur until the final write completes; preventClose = true
+PASS Closing must be propagated forward: shutdown must not occur until the final write completes; becomes closed after first write
+PASS Closing must be propagated forward: shutdown must not occur until the final write completes; becomes closed after first write; preventClose = true
+PASS Closing must be propagated forward: erroring the writable while flushing pending writes should error pipeTo
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-forward.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-forward.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-forward.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-backward.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-backward.any.serviceworker-expected.txt
new file mode 100644
index 0000000..cd09dda
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-backward.any.serviceworker-expected.txt
@@ -0,0 +1,39 @@
+
+Harness Error (FAIL), message = Unhandled rejection: releasing lock of reader whose stream is still in readable state
+
+PASS Errors must be propagated backward: starts errored; preventCancel omitted; fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; rejected cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = undefined (falsy); fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = null (falsy); fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = false (falsy); fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 0 (falsy); fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = -0 (falsy); fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = NaN (falsy); fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel =  (falsy); fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true (truthy)
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = a (truthy)
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 1 (truthy)
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = Symbol() (truthy)
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = [object Object] (truthy)
+PASS Errors must be propagated backward: becomes errored before piping due to write, preventCancel = true; preventAbort = true
+PASS Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true, preventAbort = true, preventClose = true
+PASS Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; rejected cancel promise
+PASS Errors must be propagated backward: becomes errored during piping due to write; preventCancel = true
+PASS Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; rejected cancel promise
+PASS Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = true
+PASS Errors must be propagated backward: becomes errored after piping; preventCancel omitted; fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored after piping; preventCancel omitted; rejected cancel promise
+PASS Errors must be propagated backward: becomes errored after piping; preventCancel = true
+PASS Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel omitted (but cancel is never called)
+PASS Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel = true
+PASS Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; rejected cancel promise
+PASS Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = true
+PASS Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled cancel promise
+PASS Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected cancel promise
+PASS Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true
+PASS Errors must be propagated backward: erroring via the controller errors once pending write completes
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-backward.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-backward.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-backward.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-forward.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-forward.any.serviceworker-expected.txt
new file mode 100644
index 0000000..9c9b458
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-forward.any.serviceworker-expected.txt
@@ -0,0 +1,36 @@
+
+Harness Error (FAIL), message = Unhandled rejection: error1!
+
+PASS Errors must be propagated forward: starts errored; preventAbort = false; fulfilled abort promise
+PASS Errors must be propagated forward: starts errored; preventAbort = false; rejected abort promise
+PASS Errors must be propagated forward: starts errored; preventAbort = undefined (falsy); fulfilled abort promise
+PASS Errors must be propagated forward: starts errored; preventAbort = null (falsy); fulfilled abort promise
+PASS Errors must be propagated forward: starts errored; preventAbort = false (falsy); fulfilled abort promise
+PASS Errors must be propagated forward: starts errored; preventAbort = 0 (falsy); fulfilled abort promise
+PASS Errors must be propagated forward: starts errored; preventAbort = -0 (falsy); fulfilled abort promise
+PASS Errors must be propagated forward: starts errored; preventAbort = NaN (falsy); fulfilled abort promise
+PASS Errors must be propagated forward: starts errored; preventAbort =  (falsy); fulfilled abort promise
+PASS Errors must be propagated forward: starts errored; preventAbort = true (truthy)
+PASS Errors must be propagated forward: starts errored; preventAbort = a (truthy)
+PASS Errors must be propagated forward: starts errored; preventAbort = 1 (truthy)
+PASS Errors must be propagated forward: starts errored; preventAbort = Symbol() (truthy)
+PASS Errors must be propagated forward: starts errored; preventAbort = [object Object] (truthy)
+PASS Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true
+PASS Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true, preventClose = true
+PASS Errors must be propagated forward: becomes errored while empty; preventAbort = false; fulfilled abort promise
+PASS Errors must be propagated forward: becomes errored while empty; preventAbort = false; rejected abort promise
+PASS Errors must be propagated forward: becomes errored while empty; preventAbort = true
+PASS Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; fulfilled abort promise
+PASS Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; rejected abort promise
+PASS Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = true
+PASS Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; fulfilled abort promise
+PASS Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; rejected abort promise
+PASS Errors must be propagated forward: becomes errored after one chunk; preventAbort = true
+PASS Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; fulfilled abort promise
+PASS Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; rejected abort promise
+PASS Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = true
+PASS Errors must be propagated forward: shutdown must not occur until the final write completes
+PASS Errors must be propagated forward: shutdown must not occur until the final write completes; preventAbort = true
+PASS Errors must be propagated forward: shutdown must not occur until the final write completes; becomes errored after first write
+PASS Errors must be propagated forward: shutdown must not occur until the final write completes; becomes errored after first write; preventAbort = true
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-forward.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-forward.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-forward.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/flow-control.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/flow-control.any.serviceworker-expected.txt
new file mode 100644
index 0000000..dbe888a
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/flow-control.any.serviceworker-expected.txt
@@ -0,0 +1,9 @@
+
+Harness Error (FAIL), message = Unhandled rejection: releasing lock of reader whose stream is still in readable state
+
+PASS Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks
+PASS Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks, but then does
+PASS Piping from an empty ReadableStream into a WritableStream that does not desire chunks, but then the readable stream becomes non-empty and the writable stream starts desiring chunks
+PASS Piping from a ReadableStream to a WritableStream that desires more chunks before finishing with previous ones
+PASS Piping to a WritableStream that does not consume the writes fast enough exerts backpressure on the ReadableStream
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/flow-control.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/flow-control.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/flow-control.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general.any.serviceworker-expected.txt
new file mode 100644
index 0000000..e5567b2
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general.any.serviceworker-expected.txt
@@ -0,0 +1,16 @@
+
+PASS Piping must lock both the ReadableStream and WritableStream
+PASS Piping finishing must unlock both the ReadableStream and WritableStream
+PASS pipeTo must check the brand of its ReadableStream this value
+PASS pipeTo must check the brand of its WritableStream argument
+PASS pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream
+PASS pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream
+PASS Piping from a ReadableStream from which lots of chunks are synchronously readable
+PASS Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo
+PASS an undefined rejection from pull should cause pipeTo() to reject when preventAbort is true
+PASS an undefined rejection from pull should cause pipeTo() to reject when preventAbort is false
+PASS an undefined rejection from write should cause pipeTo() to reject when preventCancel is true
+PASS an undefined rejection from write should cause pipeTo() to reject when preventCancel is false
+PASS pipeTo() should reject if an option getter grabs a writer
+PASS pipeTo() promise should resolve if null is passed
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/multiple-propagation.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/multiple-propagation.any.serviceworker-expected.txt
new file mode 100644
index 0000000..eb5205a
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/multiple-propagation.any.serviceworker-expected.txt
@@ -0,0 +1,13 @@
+
+Harness Error (FAIL), message = Unhandled rejection: error1!
+
+PASS Piping from an errored readable stream to an erroring writable stream
+PASS Piping from an errored readable stream to an errored writable stream
+PASS Piping from an errored readable stream to an erroring writable stream; preventAbort = true
+PASS Piping from an errored readable stream to an errored writable stream; preventAbort = true
+PASS Piping from an errored readable stream to a closing writable stream
+PASS Piping from an errored readable stream to a closed writable stream
+PASS Piping from a closed readable stream to an erroring writable stream
+PASS Piping from a closed readable stream to an errored writable stream
+PASS Piping from a closed readable stream to a closed writable stream
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/multiple-propagation.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/multiple-propagation.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/multiple-propagation.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/pipe-through.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/pipe-through.any.serviceworker-expected.txt
new file mode 100644
index 0000000..697a739
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/pipe-through.any.serviceworker-expected.txt
@@ -0,0 +1,47 @@
+
+Harness Error (FAIL), message = Unhandled rejection
+
+PASS Piping through a duck-typed pass-through transform stream should work
+PASS Piping through a transform errored on the writable end does not cause an unhandled promise rejection
+PASS pipeThrough should not call pipeTo on this
+PASS pipeThrough should not call pipeTo on the ReadableStream prototype
+PASS pipeThrough should brand-check this and not allow 'null'
+PASS pipeThrough should brand-check readable and not allow 'null'
+PASS pipeThrough should brand-check this and not allow 'undefined'
+PASS pipeThrough should brand-check readable and not allow 'undefined'
+PASS pipeThrough should brand-check this and not allow '0'
+PASS pipeThrough should brand-check readable and not allow '0'
+PASS pipeThrough should brand-check this and not allow 'NaN'
+PASS pipeThrough should brand-check readable and not allow 'NaN'
+PASS pipeThrough should brand-check this and not allow 'true'
+PASS pipeThrough should brand-check readable and not allow 'true'
+PASS pipeThrough should brand-check this and not allow 'ReadableStream'
+PASS pipeThrough should brand-check readable and not allow 'ReadableStream'
+PASS pipeThrough should brand-check this and not allow '[object ReadableStream]'
+PASS pipeThrough should brand-check readable and not allow '[object ReadableStream]'
+PASS pipeThrough should brand-check writable and not allow 'null'
+PASS pipeThrough should brand-check writable and not allow 'undefined'
+PASS pipeThrough should brand-check writable and not allow '0'
+PASS pipeThrough should brand-check writable and not allow 'NaN'
+PASS pipeThrough should brand-check writable and not allow 'true'
+PASS pipeThrough should brand-check writable and not allow 'WritableStream'
+PASS pipeThrough should brand-check writable and not allow '[object WritableStream]'
+PASS pipeThrough should rethrow errors from accessing readable or writable
+PASS invalid values of signal should throw; specifically 'null'
+PASS invalid values of signal should throw; specifically '0'
+PASS invalid values of signal should throw; specifically 'NaN'
+PASS invalid values of signal should throw; specifically 'true'
+PASS invalid values of signal should throw; specifically 'AbortSignal'
+PASS invalid values of signal should throw; specifically '[object AbortSignal]'
+PASS pipeThrough should accept a real AbortSignal
+PASS pipeThrough should throw if this is locked
+PASS pipeThrough should throw if writable is locked
+PASS pipeThrough should not care if readable is locked
+PASS preventCancel should work
+PASS preventClose should work
+PASS preventAbort should work
+PASS pipeThrough() should throw if an option getter grabs a writer
+PASS pipeThrough() should not throw if option is null
+PASS pipeThrough() should not throw if signal is undefined
+PASS pipeThrough() should throw if readable/writable getters throw
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/pipe-through.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/pipe-through.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/pipe-through.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/then-interception.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/then-interception.any.serviceworker-expected.txt
new file mode 100644
index 0000000..1a21a71
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/then-interception.any.serviceworker-expected.txt
@@ -0,0 +1,4 @@
+
+PASS piping should not be observable
+PASS tee should not be observable
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/then-interception.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/then-interception.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/then-interception.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/throwing-options.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/throwing-options.any.serviceworker-expected.txt
new file mode 100644
index 0000000..0809def
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/throwing-options.any.serviceworker-expected.txt
@@ -0,0 +1,10 @@
+
+PASS pipeTo should stop after getting preventAbort throws
+PASS pipeThrough should stop after getting preventAbort throws
+PASS pipeTo should stop after getting preventCancel throws
+PASS pipeThrough should stop after getting preventCancel throws
+PASS pipeTo should stop after getting preventClose throws
+PASS pipeThrough should stop after getting preventClose throws
+PASS pipeTo should stop after getting signal throws
+PASS pipeThrough should stop after getting signal throws
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/throwing-options.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/throwing-options.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/throwing-options.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/transform-streams.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/transform-streams.any.serviceworker-expected.txt
new file mode 100644
index 0000000..26fc20e
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/transform-streams.any.serviceworker-expected.txt
@@ -0,0 +1,3 @@
+
+PASS Piping through an identity transform stream should close the destination when the source closes
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/piping/transform-streams.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/transform-streams.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/piping/transform-streams.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any-expected.txt
index 5c8538e..335b67b 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any-expected.txt
@@ -5,12 +5,16 @@
 PASS CountQueuingStrategy: size is the same function across all instances
 PASS CountQueuingStrategy: size should have the right name
 PASS CountQueuingStrategy: subclassing should work correctly
+PASS CountQueuingStrategy: size should not have a prototype property
 PASS ByteLengthQueuingStrategy: Can construct a with a valid high water mark
 PASS ByteLengthQueuingStrategy: Constructor behaves as expected with strange arguments
 PASS ByteLengthQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules
 PASS ByteLengthQueuingStrategy: size is the same function across all instances
 PASS ByteLengthQueuingStrategy: size should have the right name
 PASS ByteLengthQueuingStrategy: subclassing should work correctly
+PASS ByteLengthQueuingStrategy: size should not have a prototype property
+PASS CountQueuingStrategy: size should not be a constructor
+PASS ByteLengthQueuingStrategy: size should not be a constructor
 PASS CountQueuingStrategy: size should have the right length
 PASS ByteLengthQueuingStrategy: size should have the right length
 PASS CountQueuingStrategy: size behaves as expected with strange arguments
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.js b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.js
index 1846ea6..82235ae 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.js
@@ -75,9 +75,24 @@
     assert_equals(sc.size(), 2, 'size() on the subclass should override the parent');
     assert_true(sc.subClassMethod(), 'subClassMethod() should work');
   }, `${QueuingStrategy.name}: subclassing should work correctly`);
+
+  test(() => {
+    const size = new QueuingStrategy({ highWaterMark: 5 }).size;
+    assert_false('prototype' in size);
+  }, `${QueuingStrategy.name}: size should not have a prototype property`);
 }
 
 test(() => {
+  const size = new CountQueuingStrategy({ highWaterMark: 5 }).size;
+  assert_throws_js(TypeError, () => new size());
+}, `CountQueuingStrategy: size should not be a constructor`);
+
+test(() => {
+  const size = new ByteLengthQueuingStrategy({ highWaterMark: 5 }).size;
+  assert_throws_js(TypeError, () => new size({ byteLength: 1024 }));
+}, `ByteLengthQueuingStrategy: size should not be a constructor`);
+
+test(() => {
   const size = (new CountQueuingStrategy({ highWaterMark: 5 })).size;
   assert_equals(size.length, 0);
 }, 'CountQueuingStrategy: size should have the right length');
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.serviceworker-expected.txt
new file mode 100644
index 0000000..335b67b
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.serviceworker-expected.txt
@@ -0,0 +1,22 @@
+
+PASS CountQueuingStrategy: Can construct a with a valid high water mark
+PASS CountQueuingStrategy: Constructor behaves as expected with strange arguments
+PASS CountQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules
+PASS CountQueuingStrategy: size is the same function across all instances
+PASS CountQueuingStrategy: size should have the right name
+PASS CountQueuingStrategy: subclassing should work correctly
+PASS CountQueuingStrategy: size should not have a prototype property
+PASS ByteLengthQueuingStrategy: Can construct a with a valid high water mark
+PASS ByteLengthQueuingStrategy: Constructor behaves as expected with strange arguments
+PASS ByteLengthQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules
+PASS ByteLengthQueuingStrategy: size is the same function across all instances
+PASS ByteLengthQueuingStrategy: size should have the right name
+PASS ByteLengthQueuingStrategy: subclassing should work correctly
+PASS ByteLengthQueuingStrategy: size should not have a prototype property
+PASS CountQueuingStrategy: size should not be a constructor
+PASS ByteLengthQueuingStrategy: size should not be a constructor
+PASS CountQueuingStrategy: size should have the right length
+PASS ByteLengthQueuingStrategy: size should have the right length
+PASS CountQueuingStrategy: size behaves as expected with strange arguments
+PASS ByteLengthQueuingStrategy: size behaves as expected with strange arguments
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.worker-expected.txt
index 5c8538e..335b67b 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.worker-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/queuing-strategies.any.worker-expected.txt
@@ -5,12 +5,16 @@
 PASS CountQueuingStrategy: size is the same function across all instances
 PASS CountQueuingStrategy: size should have the right name
 PASS CountQueuingStrategy: subclassing should work correctly
+PASS CountQueuingStrategy: size should not have a prototype property
 PASS ByteLengthQueuingStrategy: Can construct a with a valid high water mark
 PASS ByteLengthQueuingStrategy: Constructor behaves as expected with strange arguments
 PASS ByteLengthQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules
 PASS ByteLengthQueuingStrategy: size is the same function across all instances
 PASS ByteLengthQueuingStrategy: size should have the right name
 PASS ByteLengthQueuingStrategy: subclassing should work correctly
+PASS ByteLengthQueuingStrategy: size should not have a prototype property
+PASS CountQueuingStrategy: size should not be a constructor
+PASS ByteLengthQueuingStrategy: size should not be a constructor
 PASS CountQueuingStrategy: size should have the right length
 PASS ByteLengthQueuingStrategy: size should have the right length
 PASS CountQueuingStrategy: size behaves as expected with strange arguments
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any-expected.txt
index 06b7251..e1be38c 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any-expected.txt
@@ -18,11 +18,16 @@
 FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the readable state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
     [native code]
 }" ("TypeError")
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset (in the readable state)
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset (in the closed state)
+FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has a different length (in the readable state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" did not throw
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view has a larger length (in the readable state)
 PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the closed state)
-FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the closed state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the closed state)
+FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is non-zero-length (in the closed state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
     [native code]
 }" ("TypeError")
-FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the closed state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
-    [native code]
-}" ("TypeError")
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has a different length (in the closed state)
+FAIL ReadableStream with byte source: enqueue() throws if the BYOB request's buffer has been detached (in the readable state) assert_throws_js: enqueue() must throw if the BYOB request's buffer has become detached function "() => c.enqueue(new Uint8Array([1]))" did not throw
+PASS ReadableStream with byte source: enqueue() throws if the BYOB request's buffer has been detached (in the closed state)
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.js
index d4ad483..cc75dc4 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.js
@@ -140,11 +140,11 @@
 async_test(t => {
   const stream = new ReadableStream({
     pull: t.step_func_done(c => {
+      c.close();
+
       // Detach it by reading into it
       reader.read(c.byobRequest.view);
 
-      c.close();
-
       assert_throws_js(TypeError, () => c.byobRequest.respond(0),
         'respond() must throw if the corresponding view has become detached');
     }),
@@ -191,7 +191,7 @@
 async_test(t => {
   const stream = new ReadableStream({
     pull: t.step_func_done(c => {
-      const view = new Uint8Array(new ArrayBuffer(10), 0, 0);
+      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 0);
 
       assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view));
     }),
@@ -206,12 +206,83 @@
 async_test(t => {
   const stream = new ReadableStream({
     pull: t.step_func_done(c => {
+      const view = c.byobRequest.view.subarray(1, 2);
+
+      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
+    }),
+    type: 'bytes'
+  });
+  const reader = stream.getReader({ mode: 'byob' });
+
+  reader.read(new Uint8Array([4, 5, 6]));
+}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset ' +
+   '(in the readable state)');
+
+async_test(t => {
+  const stream = new ReadableStream({
+    pull: t.step_func_done(c => {
+      c.close();
+
+      const view = c.byobRequest.view.subarray(1, 1);
+
+      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
+    }),
+    type: 'bytes'
+  });
+  const reader = stream.getReader({ mode: 'byob' });
+
+  reader.read(new Uint8Array([4, 5, 6]));
+}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset ' +
+   '(in the closed state)');
+
+async_test(t => {
+  const stream = new ReadableStream({
+    pull: t.step_func_done(c => {
+      const view = new Uint8Array(new ArrayBuffer(10), 0, 3);
+
+      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
+    }),
+    type: 'bytes'
+  });
+  const reader = stream.getReader({ mode: 'byob' });
+
+  reader.read(new Uint8Array([4, 5, 6]));
+}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has a ' +
+   'different length (in the readable state)');
+
+async_test(t => {
+  const stream = new ReadableStream({
+    pull: t.step_func_done(c => {
+      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 4);
+      view[0] = 20;
+      view[1] = 21;
+      view[2] = 22;
+      view[3] = 23;
+
+      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
+    }),
+    type: 'bytes'
+  });
+  const reader = stream.getReader({ mode: 'byob' });
+
+  const buffer = new ArrayBuffer(10);
+  const view = new Uint8Array(buffer, 0, 3);
+  view[0] = 10;
+  view[1] = 11;
+  view[2] = 12;
+  reader.read(view);
+}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view has a larger length ' +
+   '(in the readable state)');
+
+async_test(t => {
+  const stream = new ReadableStream({
+    pull: t.step_func_done(c => {
+      c.close();
+
       // Detach it by reading into it
       const view = new Uint8Array([1, 2, 3]);
       reader.read(view);
 
-      c.close();
-
       assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view));
     }),
     type: 'bytes'
@@ -229,7 +300,7 @@
 
       c.close();
 
-      assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view));
+      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
     }),
     type: 'bytes'
   });
@@ -242,7 +313,7 @@
 async_test(t => {
   const stream = new ReadableStream({
     pull: t.step_func_done(c => {
-      const view = new Uint8Array(new ArrayBuffer(10), 0, 0);
+      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 1);
 
       c.close();
 
@@ -253,5 +324,58 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   reader.read(new Uint8Array([4, 5, 6]));
-}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a ' +
-    'non-zero-length buffer (in the closed state)');
+}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view is non-zero-length ' +
+   '(in the closed state)');
+
+async_test(t => {
+  const stream = new ReadableStream({
+    pull: t.step_func_done(c => {
+      const view = new Uint8Array(new ArrayBuffer(10), 0, 0);
+
+      c.close();
+
+      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
+    }),
+    type: 'bytes'
+  });
+  const reader = stream.getReader({ mode: 'byob' });
+
+  reader.read(new Uint8Array([4, 5, 6]));
+}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has a ' +
+   'different length (in the closed state)');
+
+async_test(t => {
+  const stream = new ReadableStream({
+    pull: t.step_func_done(c => {
+      // Detach it by reading into it
+      reader.read(c.byobRequest.view);
+
+      assert_throws_js(TypeError, () => c.enqueue(new Uint8Array([1])),
+        'enqueue() must throw if the BYOB request\'s buffer has become detached');
+    }),
+    type: 'bytes'
+  });
+  const reader = stream.getReader({ mode: 'byob' });
+
+  reader.read(new Uint8Array([4, 5, 6]));
+}, 'ReadableStream with byte source: enqueue() throws if the BYOB request\'s buffer has been detached (in the ' +
+  'readable state)');
+
+async_test(t => {
+  const stream = new ReadableStream({
+    pull: t.step_func_done(c => {
+      c.close();
+
+      // Detach it by reading into it
+      reader.read(c.byobRequest.view);
+
+      assert_throws_js(TypeError, () => c.enqueue(new Uint8Array([1])),
+        'enqueue() must throw if the BYOB request\'s buffer has become detached');
+    }),
+    type: 'bytes'
+  });
+  const reader = stream.getReader({ mode: 'byob' });
+
+  reader.read(new Uint8Array([4, 5, 6]));
+}, 'ReadableStream with byte source: enqueue() throws if the BYOB request\'s buffer has been detached (in the ' +
+  'closed state)');
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker-expected.txt
new file mode 100644
index 0000000..e1be38c
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker-expected.txt
@@ -0,0 +1,33 @@
+
+Harness Error (TIMEOUT), message = null
+
+FAIL ReadableStream with byte source: read()ing from a closed stream still transfers the buffer assert_not_equals: a different ArrayBuffer must underlie the value got disallowed value object "[object ArrayBuffer]"
+FAIL ReadableStream with byte source: read()ing from a stream with queued chunks still transfers the buffer assert_not_equals: a different ArrayBuffer must underlie the value got disallowed value object "[object ArrayBuffer]"
+FAIL ReadableStream with byte source: enqueuing an already-detached buffer throws assert_throws_js: function "() => c.enqueue(view)" did not throw
+FAIL ReadableStream with byte source: enqueuing a zero-length buffer throws assert_throws_js: function "() => c.enqueue(view)" did not throw
+FAIL ReadableStream with byte source: enqueuing a zero-length view on a non-zero-length buffer throws assert_throws_js: function "() => c.enqueue(view)" did not throw
+TIMEOUT ReadableStream with byte source: reading into an already-detached buffer rejects Test timed out
+NOTRUN ReadableStream with byte source: reading into a zero-length buffer rejects
+NOTRUN ReadableStream with byte source: reading into a zero-length view on a non-zero-length buffer rejects
+FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the readable state) assert_throws_js: respond() must throw if the corresponding view has become detached function "() => c.byobRequest.respond(1)" did not throw
+FAIL ReadableStream with byte source: respond() throws if the BYOB request's buffer has been detached (in the closed state) assert_throws_js: respond() must throw if the corresponding view has become detached function "() => c.byobRequest.respond(0)" did not throw
+FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the readable state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" did not throw
+FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the readable state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
+    [native code]
+}" ("TypeError")
+FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the readable state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
+    [native code]
+}" ("TypeError")
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset (in the readable state)
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset (in the closed state)
+FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has a different length (in the readable state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" did not throw
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view has a larger length (in the readable state)
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the closed state)
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the closed state)
+FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is non-zero-length (in the closed state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
+    [native code]
+}" ("TypeError")
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has a different length (in the closed state)
+FAIL ReadableStream with byte source: enqueue() throws if the BYOB request's buffer has been detached (in the readable state) assert_throws_js: enqueue() must throw if the BYOB request's buffer has become detached function "() => c.enqueue(new Uint8Array([1]))" did not throw
+PASS ReadableStream with byte source: enqueue() throws if the BYOB request's buffer has been detached (in the closed state)
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.worker-expected.txt
index 06b7251..e1be38c 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.worker-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.worker-expected.txt
@@ -18,11 +18,16 @@
 FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the readable state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
     [native code]
 }" ("TypeError")
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset (in the readable state)
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset (in the closed state)
+FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has a different length (in the readable state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" did not throw
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view has a larger length (in the readable state)
 PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has been detached (in the closed state)
-FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the closed state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer is zero-length (in the closed state)
+FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is non-zero-length (in the closed state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
     [native code]
 }" ("TypeError")
-FAIL ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a non-zero-length buffer (in the closed state) assert_throws_js: function "() => c.byobRequest.respondWithNewView(view)" threw object "RangeError: Invalid value for view.byteLength" ("RangeError") expected instance of function "function TypeError() {
-    [native code]
-}" ("TypeError")
+PASS ReadableStream with byte source: respondWithNewView() throws if the supplied view's buffer has a different length (in the closed state)
+FAIL ReadableStream with byte source: enqueue() throws if the BYOB request's buffer has been detached (in the readable state) assert_throws_js: enqueue() must throw if the BYOB request's buffer has become detached function "() => c.enqueue(new Uint8Array([1]))" did not throw
+PASS ReadableStream with byte source: enqueue() throws if the BYOB request's buffer has been detached (in the closed state)
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt
new file mode 100644
index 0000000..87de5b3
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt
@@ -0,0 +1,5 @@
+CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: ReferenceError: Can't find variable: ReadableByteStreamController
+
+Harness Error (FAIL), message = Unhandled rejection: ReferenceError: Can't find variable: ReadableByteStreamController
+
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window-expected.txt
new file mode 100644
index 0000000..40ce901
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window-expected.txt
@@ -0,0 +1,3 @@
+
+PASS enqueue after detaching byobRequest.view.buffer should throw
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window.js
new file mode 100644
index 0000000..15400f6
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window.js
@@ -0,0 +1,19 @@
+promise_test(async t => {
+  const error = new Error('cannot proceed');
+  const rs = new ReadableStream({
+    type: 'bytes',
+    pull: t.step_func((controller) => {
+      const buffer = controller.byobRequest.view.buffer;
+      // Detach the buffer.
+      postMessage(buffer, '*', [buffer]);
+
+      // Try to enqueue with a new buffer.
+      assert_throws_js(TypeError, () => controller.enqueue(new Uint8Array([42])));
+
+      // If we got here the test passed.
+      controller.error(error);
+    })
+  });
+  const reader = rs.getReader({ mode: 'byob' });
+  await promise_rejects_exactly(t, error, reader.read(new Uint8Array(1)));
+}, 'enqueue after detaching byobRequest.view.buffer should throw');
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any-expected.txt
index 1166534..633e307 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any-expected.txt
@@ -16,7 +16,8 @@
 PASS ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically
 PASS ReadableStream with byte source: Test that erroring a stream does not release a reader automatically
 PASS ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically
-PASS ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader with pending read() must throw
+FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: There are still pending read requests, cannot release the lock"
+FAIL ReadableStream with byte source: releaseLock() on ReadableStreamBYOBReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: There are still pending read requests, cannot release the lock"
 PASS ReadableStream with byte source: Automatic pull() after start()
 PASS ReadableStream with byte source: Automatic pull() after start() and read()
 FAIL ReadableStream with byte source: autoAllocateChunkSize assert_equals: pull() must have been invoked twice expected 2 but got 1
@@ -36,7 +37,7 @@
 FAIL ReadableStream with byte source: Respond to pull() by enqueue() asynchronously assert_equals: byobRequest should be null expected (object) null but got (undefined) undefined
 TIMEOUT ReadableStream with byte source: Respond to multiple pull() by separate enqueue() Test timed out
 NOTRUN ReadableStream with byte source: read(view), then respond()
-NOTRUN ReadableStream with byte source: read(view), then respond() with a transferred ArrayBuffer
+NOTRUN ReadableStream with byte source: read(view), then respondWithNewView() with a transferred ArrayBuffer
 NOTRUN ReadableStream with byte source: read(view), then respond() with too big value
 NOTRUN ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder
 NOTRUN ReadableStream with byte source: enqueue(), getReader(), then read(view)
@@ -56,6 +57,7 @@
 PASS ReadableStream with byte source: Throw on enqueue() after close()
 NOTRUN ReadableStream with byte source: read(view), then respond() and close() in pull()
 NOTRUN ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls
+NOTRUN ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple enqueue() calls
 NOTRUN ReadableStream with byte source: read() twice, then enqueue() twice
 NOTRUN ReadableStream with byte source: Multiple read(view), close() and respond()
 NOTRUN ReadableStream with byte source: Multiple read(view), big enqueue()
@@ -74,7 +76,8 @@
 NOTRUN calling respond() twice on the same byobRequest should throw
 NOTRUN calling respondWithNewView() twice on the same byobRequest should throw
 NOTRUN calling respond(0) twice on the same byobRequest should throw even when closed
-NOTRUN pull() resolving should not make releaseLock() possible
+NOTRUN calling respond() should throw when canceled
+NOTRUN pull() resolving should not resolve read()
 NOTRUN ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction
 FAIL ReadableStream with byte source: autoAllocateChunkSize cannot be 0 assert_throws_js: controller cannot be setup with autoAllocateChunkSize = 0 function "() => new ReadableStream({ autoAllocateChunkSize: 0, type: 'bytes' })" threw object "RangeError: autoAllocateChunkSize value is negative or equal to positive or negative infinity" ("RangeError") expected instance of function "function TypeError() {
     [native code]
@@ -84,4 +87,21 @@
 PASS ReadableStreamBYOBReader constructor requires an unlocked ReadableStream
 PASS ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes"
 PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes"
+NOTRUN ReadableStream with byte source: respondWithNewView() with a smaller view
+NOTRUN ReadableStream with byte source: respondWithNewView() with a zero-length view (in the closed state)
+NOTRUN ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view (in the readable state)
+NOTRUN ReadableStream with byte source: respondWithNewView() with a transferred zero-length view (in the closed state)
+NOTRUN ReadableStream with byte source: enqueue() discards auto-allocated BYOB request
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respond()
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 1 element Uint16Array, respond(1)
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 2 element Uint8Array, respond(3)
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respondWithNewView()
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, enqueue()
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, close(), respond(0)
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, respond()
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, enqueue()
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, respond()
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, enqueue()
+NOTRUN ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read(view) on second reader with 1 element Uint16Array, respond(1)
+NOTRUN ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read() on second reader, enqueue()
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.js
index bbcae33..3b88e8d 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.js
@@ -236,15 +236,27 @@
   });
 }, 'ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically');
 
-test(() => {
+promise_test(async t => {
   const stream = new ReadableStream({
     type: 'bytes'
   });
 
   const reader = stream.getReader();
-  reader.read();
-  assert_throws_js(TypeError, () => reader.releaseLock(), 'reader.releaseLock() must throw');
-}, 'ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader with pending read() must throw');
+  const read = reader.read();
+  reader.releaseLock();
+  await promise_rejects_js(t, TypeError, read, 'pending read must reject');
+}, 'ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader must reject pending read()');
+
+promise_test(async t => {
+  const stream = new ReadableStream({
+    type: 'bytes'
+  });
+
+  const reader = stream.getReader({ mode: 'byob' });
+  const read = reader.read(new Uint8Array(1));
+  reader.releaseLock();
+  await promise_rejects_js(t, TypeError, read, 'pending read must reject');
+}, 'ReadableStream with byte source: releaseLock() on ReadableStreamBYOBReader must reject pending read()');
 
 promise_test(() => {
   let pullCount = 0;
@@ -517,7 +529,7 @@
     assert_equals(desiredSizeInPull, 8, 'desiredSize in pull()');
 
     return promise.then(result => {
-      assert_equals(result.done, false, 'result.done');
+      assert_false(result.done, 'result.done');
 
       const view = result.value;
       assert_equals(view.constructor, Uint8Array, 'view.constructor');
@@ -541,7 +553,7 @@
   const reader = stream.getReader();
 
   const promise = reader.read().then(result => {
-    assert_equals(result.done, false);
+    assert_false(result.done);
 
     const view = result.value;
     assert_equals(view.constructor, Uint8Array);
@@ -573,7 +585,7 @@
   const reader = stream.getReader();
 
   return reader.read().then(result => {
-    assert_equals(result.done, false);
+    assert_false(result.done);
 
     const view = result.value;
     assert_equals(view.constructor, Uint8Array);
@@ -598,7 +610,7 @@
   const byobReader = stream.getReader({ mode: 'byob' });
 
   return byobReader.read(new Uint8Array(8)).then(result => {
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
 
     const view = result.value;
     assert_equals(view.constructor, Uint8Array, 'value.constructor');
@@ -613,7 +625,7 @@
 
     return reader.read();
   }).then(result => {
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
 
     const view = result.value;
     assert_equals(view.constructor, Uint8Array, 'value.constructor');
@@ -641,7 +653,7 @@
   controller.close();
 
   return reader.read().then(result => {
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
 
     const view = result.value;
     assert_equals(view.byteOffset, 0, 'byteOffset');
@@ -649,7 +661,7 @@
 
     return reader.read();
   }).then(result => {
-    assert_equals(result.done, true, 'done');
+    assert_true(result.done, 'done');
     assert_equals(result.value, undefined, 'value');
   });
 }, 'ReadableStream with byte source: getReader(), enqueue(), close(), then read()');
@@ -667,7 +679,7 @@
   const reader = stream.getReader();
 
   return reader.read().then(result => {
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
 
     const view = result.value;
     assert_equals(view.byteOffset, 0, 'byteOffset');
@@ -675,7 +687,7 @@
 
     return reader.read();
   }).then(result => {
-    assert_equals(result.done, true, 'done');
+    assert_true(result.done, 'done');
     assert_equals(result.value, undefined, 'value');
   });
 }, 'ReadableStream with byte source: enqueue(), close(), getReader(), then read()');
@@ -698,7 +710,7 @@
   const reader = stream.getReader();
 
   return reader.read().then(result => {
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
     assert_equals(result.value.byteLength, 16, 'byteLength');
     assert_equals(byobRequest, null, 'byobRequest must be null');
   });
@@ -812,6 +824,7 @@
 
   let pullCount = 0;
   const byobRequestDefined = [];
+  let byobRequestViewDefined;
 
   const stream = new ReadableStream({
     start(c) {
@@ -819,12 +832,14 @@
     },
     pull() {
       byobRequestDefined.push(controller.byobRequest !== null);
+      const initialByobRequest = controller.byobRequest;
 
       const view = controller.byobRequest.view;
       view[0] = 0x01;
       controller.byobRequest.respond(1);
 
       byobRequestDefined.push(controller.byobRequest !== null);
+      byobRequestViewDefined = initialByobRequest.view !== null;
 
       ++pullCount;
     },
@@ -834,12 +849,13 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   return reader.read(new Uint8Array(1)).then(result => {
-    assert_equals(result.done, false, 'result.done');
+    assert_false(result.done, 'result.done');
     assert_equals(result.value.byteLength, 1, 'result.value.byteLength');
     assert_equals(result.value[0], 0x01, 'result.value[0]');
     assert_equals(pullCount, 1, 'pull() should be called only once');
     assert_true(byobRequestDefined[0], 'byobRequest must not be null before respond()');
     assert_false(byobRequestDefined[1], 'byobRequest must be null after respond()');
+    assert_false(byobRequestViewDefined, 'view of initial byobRequest must be null after respond()');
   });
 }, 'ReadableStream with byte source: read(view), then respond()');
 
@@ -848,24 +864,22 @@
 
   let pullCount = 0;
   const byobRequestDefined = [];
+  let byobRequestViewDefined;
 
   const stream = new ReadableStream({
     start(c) {
       controller = c;
     },
-    pull() {
+    async pull() {
       byobRequestDefined.push(controller.byobRequest !== null);
+      const initialByobRequest = controller.byobRequest;
 
-      // Emulate ArrayBuffer transfer by just creating a new ArrayBuffer and pass it. By checking the result of
-      // read(view), we test that the respond()'s buffer argument is working correctly.
-      //
-      // A real implementation of the underlying byte source would transfer controller.byobRequest.view.buffer into
-      // a new ArrayBuffer, then construct a view around it and write to it.
-      const transferredView = new Uint8Array(1);
+      const transferredView = await transferArrayBufferView(controller.byobRequest.view);
       transferredView[0] = 0x01;
       controller.byobRequest.respondWithNewView(transferredView);
 
       byobRequestDefined.push(controller.byobRequest !== null);
+      byobRequestViewDefined = initialByobRequest.view !== null;
 
       ++pullCount;
     },
@@ -875,14 +889,15 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   return reader.read(new Uint8Array(1)).then(result => {
-    assert_equals(result.done, false, 'result.done');
+    assert_false(result.done, 'result.done');
     assert_equals(result.value.byteLength, 1, 'result.value.byteLength');
     assert_equals(result.value[0], 0x01, 'result.value[0]');
     assert_equals(pullCount, 1, 'pull() should be called only once');
-    assert_true(byobRequestDefined[0], 'byobRequest must not be null before respond()');
-    assert_false(byobRequestDefined[1], 'byobRequest must be null after respond()');
+    assert_true(byobRequestDefined[0], 'byobRequest must not be null before respondWithNewView()');
+    assert_false(byobRequestDefined[1], 'byobRequest must be null after respondWithNewView()');
+    assert_false(byobRequestViewDefined, 'view of initial byobRequest must be null after respondWithNewView()');
   });
-}, 'ReadableStream with byte source: read(view), then respond() with a transferred ArrayBuffer');
+}, 'ReadableStream with byte source: read(view), then respondWithNewView() with a transferred ArrayBuffer');
 
 promise_test(() => {
   let controller;
@@ -948,13 +963,14 @@
   return reader.read(new Uint16Array(2)).then(result => {
     assert_equals(pullCount, 1);
 
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
 
     const view = result.value;
     assert_equals(view.byteOffset, 0, 'byteOffset');
     assert_equals(view.byteLength, 2, 'byteLength');
 
-    assert_equals(view[0], 0x0201);
+    const dataView = new DataView(view.buffer, view.byteOffset, view.byteLength);
+    assert_equals(dataView.getUint16(0), 0x0102);
 
     return reader.read(new Uint8Array(1));
   }).then(result => {
@@ -965,7 +981,7 @@
     assert_equals(viewInfo.byteOffset, 0, 'view.byteOffset should be 0');
     assert_equals(viewInfo.byteLength, 4, 'view.byteLength should be 4');
 
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
 
     const view = result.value;
     assert_equals(view.byteOffset, 0, 'byteOffset');
@@ -990,7 +1006,7 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   return reader.read(new Uint8Array(16)).then(result => {
-    assert_equals(result.done, false);
+    assert_false(result.done);
 
     const view = result.value;
     assert_equals(view.byteOffset, 0);
@@ -1075,7 +1091,6 @@
     cancel(r) {
       if (cancelCount === 0) {
         reason = r;
-        controller.byobRequest.respond(0);
       }
 
       ++cancelCount;
@@ -1088,12 +1103,13 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   const readPromise = reader.read(new Uint8Array(1)).then(result => {
-    assert_equals(result.done, true);
+    assert_true(result.done, 'result.done');
+    assert_equals(result.value, undefined, 'result.value');
   });
 
   const cancelPromise = reader.cancel(passedReason).then(result => {
-    assert_equals(result, undefined);
-    assert_equals(cancelCount, 1);
+    assert_equals(result, undefined, 'cancel() return value should be fulfilled with undefined');
+    assert_equals(cancelCount, 1, 'cancel() should be called only once');
     assert_equals(reason, passedReason, 'reason should equal the passed reason');
   });
 
@@ -1129,21 +1145,17 @@
     const reader = stream.getReader({ mode: 'byob' });
 
     const promise = reader.read(new Uint16Array(1)).then(result => {
-      assert_equals(result.done, true, 'result.done');
-      assert_equals(result.value.constructor, Uint16Array, 'result.value');
+      assert_true(result.done, 'result.done');
+      assert_equals(result.value, undefined, 'result.value');
     });
 
     assert_equals(pullCount, 1, '1 pull() should have been made in response to partial fill by enqueue()');
     assert_not_equals(byobRequest, null, 'byobRequest should not be null');
-    assert_equals(viewInfos[0].byteLength, 2, 'byteLength before enqueue() shouild be 2');
+    assert_equals(viewInfos[0].byteLength, 2, 'byteLength before enqueue() should be 2');
     assert_equals(viewInfos[1].byteLength, 1, 'byteLength after enqueue() should be 1');
 
-
     reader.cancel();
 
-    // Tell that the buffer given via pull() is returned.
-    controller.byobRequest.respond(0);
-
     assert_equals(pullCount, 1, 'pull() should only be called once');
     return promise;
   });
@@ -1172,7 +1184,7 @@
   const buffer = new ArrayBuffer(16);
 
   return reader.read(new Uint8Array(buffer, 8, 8)).then(result => {
-    assert_equals(result.done, false);
+    assert_false(result.done);
 
     assert_false(pullCalled, 'pull() must not have been called');
 
@@ -1213,7 +1225,7 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   return reader.read(new Uint8Array(24)).then(result => {
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
 
     assert_false(pullCalled, 'pull() must not have been called');
 
@@ -1243,7 +1255,7 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   return reader.read(new Uint8Array(24)).then(result => {
-    assert_equals(result.done, false);
+    assert_false(result.done);
 
     assert_false(pullCalled, 'pull() must not have been called');
 
@@ -1273,7 +1285,7 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   return reader.read(new Uint8Array(8)).then(result => {
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
 
     const view = result.value;
     assert_equals(view.byteOffset, 0);
@@ -1282,7 +1294,7 @@
 
     return reader.read(new Uint8Array(8));
   }).then(result => {
-    assert_equals(result.done, false, 'done');
+    assert_false(result.done, 'done');
 
     assert_false(pullCalled, 'pull() must not have been called');
 
@@ -1322,12 +1334,14 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   return reader.read(new Uint16Array(1)).then(result => {
-    assert_equals(result.done, false);
+    assert_false(result.done);
 
     const view = result.value;
     assert_equals(view.byteOffset, 0);
     assert_equals(view.byteLength, 2);
-    assert_equals(view[0], 0xaaff);
+
+    const dataView = new DataView(view.buffer, view.byteOffset, view.byteLength);
+    assert_equals(dataView.getUint16(0), 0xffaa);
 
     assert_equals(viewInfo.constructor, Uint8Array, 'view.constructor should be Uint8Array');
     assert_equals(viewInfo.bufferByteLength, 2, 'view.buffer.byteLength should be 2');
@@ -1375,14 +1389,16 @@
     const reader = stream.getReader({ mode: 'byob' });
 
     const promise = reader.read(new Uint16Array(2)).then(result => {
-      assert_equals(result.done, false, 'done');
+      assert_false(result.done, 'done');
 
       const view = result.value;
       assert_equals(view.constructor, Uint16Array, 'constructor');
       assert_equals(view.buffer.byteLength, 4, 'buffer.byteLength');
       assert_equals(view.byteOffset, 0, 'byteOffset');
       assert_equals(view.byteLength, 2, 'byteLength');
-      assert_equals(view[0], 0x0001, 'Contents are set');
+
+      const dataView = new DataView(view.buffer, view.byteOffset, view.byteLength);
+      assert_equals(dataView.getUint16(0), 0x0100, 'contents are set');
 
       const p = reader.read(new Uint16Array(1));
 
@@ -1390,13 +1406,15 @@
 
       return p;
     }).then(result => {
-      assert_equals(result.done, false, 'done');
+      assert_false(result.done, 'done');
 
       const view = result.value;
       assert_equals(view.buffer.byteLength, 2, 'buffer.byteLength');
       assert_equals(view.byteOffset, 0, 'byteOffset');
       assert_equals(view.byteLength, 2, 'byteLength');
-      assert_equals(view[0], 0x0302, 'Contents are set');
+
+      const dataView = new DataView(view.buffer, view.byteOffset, view.byteLength);
+      assert_equals(dataView.getUint16(0), 0x0203, 'contents are set');
 
       assert_not_equals(byobRequest, null, 'byobRequest must not be null');
       assert_equals(viewInfo.constructor, Uint8Array, 'view.constructor should be Uint8Array');
@@ -1520,7 +1538,7 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   return reader.read(new Uint8Array(16)).then(result => {
-    assert_equals(result.done, false);
+    assert_false(result.done);
 
     const view = result.value;
     assert_equals(view.byteOffset, 0);
@@ -1529,7 +1547,7 @@
 
     return reader.read(new Uint8Array(16));
   }).then(result => {
-    assert_equals(result.done, true);
+    assert_true(result.done);
 
     const view = result.value;
     assert_equals(view.byteOffset, 0);
@@ -1548,6 +1566,7 @@
 
   let controller;
   const viewInfos = [];
+  const viewInfosAfterRespond = [];
 
   const stream = new ReadableStream({
     start(c) {
@@ -1564,6 +1583,7 @@
 
         view[0] = 0x01;
         controller.byobRequest.respond(1);
+        viewInfosAfterRespond.push(extractViewInfo(view));
       }
 
       ++pullCount;
@@ -1574,12 +1594,12 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   return reader.read(new Uint32Array(1)).then(result => {
-    assert_equals(result.done, false);
+    assert_false(result.done, 'result.done');
 
     const view = result.value;
-    assert_equals(view.byteOffset, 0);
-    assert_equals(view.byteLength, 4);
-    assert_equals(view[0], 0x01010101);
+    assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
+    assert_equals(view.byteLength, 4, 'result.value.byteLength');
+    assert_equals(view[0], 0x01010101, 'result.value[0]');
 
     assert_equals(pullCount, 1, 'pull() should only be called once');
 
@@ -1589,6 +1609,8 @@
 
       assert_equals(viewInfos[i].byteOffset, i, 'view.byteOffset should be i');
       assert_equals(viewInfos[i].byteLength, 4 - i, 'view.byteLength should be 4 - i');
+
+      assert_equals(viewInfosAfterRespond[i].bufferByteLength, 0, 'view.buffer should be transferred after respond()');
     }
   });
 }, 'ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls');
@@ -1597,6 +1619,59 @@
   let pullCount = 0;
 
   let controller;
+  const viewInfos = [];
+  const viewInfosAfterEnqueue = [];
+
+  const stream = new ReadableStream({
+    start(c) {
+      controller = c;
+    },
+    pull() {
+      if (controller.byobRequest === null) {
+        return;
+      }
+
+      for (let i = 0; i < 4; ++i) {
+        const view = controller.byobRequest.view;
+        viewInfos.push(extractViewInfo(view));
+
+        controller.enqueue(new Uint8Array([0x01]));
+        viewInfosAfterEnqueue.push(extractViewInfo(view));
+      }
+
+      ++pullCount;
+    },
+    type: 'bytes'
+  });
+
+  const reader = stream.getReader({ mode: 'byob' });
+
+  return reader.read(new Uint32Array(1)).then(result => {
+    assert_false(result.done, 'result.done');
+
+    const view = result.value;
+    assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
+    assert_equals(view.byteLength, 4, 'result.value.byteLength');
+    assert_equals(view[0], 0x01010101, 'result.value[0]');
+
+    assert_equals(pullCount, 1, 'pull() should only be called once');
+
+    for (let i = 0; i < 4; ++i) {
+      assert_equals(viewInfos[i].constructor, Uint8Array, 'view.constructor should be Uint8Array');
+      assert_equals(viewInfos[i].bufferByteLength, 4, 'view.buffer.byteLength should be 4');
+
+      assert_equals(viewInfos[i].byteOffset, i, 'view.byteOffset should be i');
+      assert_equals(viewInfos[i].byteLength, 4 - i, 'view.byteLength should be 4 - i');
+
+      assert_equals(viewInfosAfterEnqueue[i].bufferByteLength, 0, 'view.buffer should be transferred after enqueue()');
+    }
+  });
+}, 'ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple enqueue() calls');
+
+promise_test(() => {
+  let pullCount = 0;
+
+  let controller;
   let byobRequest;
 
   const stream = new ReadableStream({
@@ -1621,7 +1696,7 @@
     // Since the queue has data no less than HWM, no more pull.
     assert_equals(pullCount, 1);
 
-    assert_equals(result.done, false);
+    assert_false(result.done);
 
     const view = result.value;
     assert_equals(view.constructor, Uint8Array);
@@ -1635,7 +1710,7 @@
   const p1 = reader.read().then(result => {
     assert_equals(pullCount, 1);
 
-    assert_equals(result.done, false);
+    assert_false(result.done);
 
     const view = result.value;
     assert_equals(view.constructor, Uint8Array);
@@ -1669,7 +1744,7 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   const p0 = reader.read(new Uint8Array(16)).then(result => {
-    assert_equals(result.done, true, '1st read: done');
+    assert_true(result.done, '1st read: done');
 
     const view = result.value;
     assert_equals(view.buffer.byteLength, 16, '1st read: buffer.byteLength');
@@ -1678,7 +1753,7 @@
   });
 
   const p1 = reader.read(new Uint8Array(32)).then(result => {
-    assert_equals(result.done, true, '2nd read: done');
+    assert_true(result.done, '2nd read: done');
 
     const view = result.value;
     assert_equals(view.buffer.byteLength, 32, '2nd read: buffer.byteLength');
@@ -1706,7 +1781,7 @@
   const reader = stream.getReader({ mode: 'byob' });
 
   const p0 = reader.read(new Uint8Array(16)).then(result => {
-    assert_equals(result.done, false, '1st read: done');
+    assert_false(result.done, '1st read: done');
 
     const view = result.value;
     assert_equals(view.buffer.byteLength, 16, '1st read: buffer.byteLength');
@@ -1715,7 +1790,7 @@
   });
 
   const p1 = reader.read(new Uint8Array(16)).then(result => {
-    assert_equals(result.done, false, '2nd read: done');
+    assert_false(result.done, '2nd read: done');
 
     const view = result.value;
     assert_equals(view.buffer.byteLength, 16, '2nd read: buffer.byteLength');
@@ -1985,6 +2060,7 @@
 }, 'calling respondWithNewView() twice on the same byobRequest should throw');
 
 promise_test(() => {
+  let controller;
   let byobRequest;
   let resolvePullCalledPromise;
   const pullCalledPromise = new Promise(resolve => {
@@ -1992,8 +2068,44 @@
   });
   let resolvePull;
   const rs = new ReadableStream({
-    pull(controller) {
-      byobRequest = controller.byobRequest;
+    start(c) {
+      controller = c;
+    },
+    pull(c) {
+      byobRequest = c.byobRequest;
+      resolvePullCalledPromise();
+      return new Promise(resolve => {
+        resolvePull = resolve;
+      });
+    },
+    type: 'bytes'
+  });
+  const reader = rs.getReader({ mode: 'byob' });
+  const readPromise = reader.read(new Uint8Array(16));
+  return pullCalledPromise.then(() => {
+    controller.close();
+    byobRequest.respond(0);
+    resolvePull();
+    return readPromise.then(() => {
+      assert_throws_js(TypeError, () => byobRequest.respond(0), 'respond() should throw');
+    });
+  });
+}, 'calling respond(0) twice on the same byobRequest should throw even when closed');
+
+promise_test(() => {
+  let controller;
+  let byobRequest;
+  let resolvePullCalledPromise;
+  const pullCalledPromise = new Promise(resolve => {
+    resolvePullCalledPromise = resolve;
+  });
+  let resolvePull;
+  const rs = new ReadableStream({
+    start(c) {
+      controller = c;
+    },
+    pull(c) {
+      byobRequest = c.byobRequest;
       resolvePullCalledPromise();
       return new Promise(resolve => {
         resolvePull = resolve;
@@ -2005,15 +2117,13 @@
   const readPromise = reader.read(new Uint8Array(16));
   return pullCalledPromise.then(() => {
     const cancelPromise = reader.cancel('meh');
+    assert_throws_js(TypeError, () => byobRequest.respond(0), 'respond() should throw');
     resolvePull();
-    byobRequest.respond(0);
-    return Promise.all([readPromise, cancelPromise]).then(() => {
-      assert_throws_js(TypeError, () => byobRequest.respond(0), 'respond() should throw');
-    });
+    return Promise.all([readPromise, cancelPromise]);
   });
-}, 'calling respond(0) twice on the same byobRequest should throw even when closed');
+}, 'calling respond() should throw when canceled');
 
-promise_test(() => {
+promise_test(async t => {
   let resolvePullCalledPromise;
   const pullCalledPromise = new Promise(resolve => {
     resolvePullCalledPromise = resolve;
@@ -2029,14 +2139,13 @@
     type: 'bytes'
   });
   const reader = rs.getReader({ mode: 'byob' });
-  reader.read(new Uint8Array(16));
-  return pullCalledPromise.then(() => {
-    resolvePull();
-    return delay(0).then(() => {
-      assert_throws_js(TypeError, () => reader.releaseLock(), 'releaseLock() should throw');
-    });
-  });
-}, 'pull() resolving should not make releaseLock() possible');
+  const read = reader.read(new Uint8Array(16));
+  await pullCalledPromise;
+  resolvePull();
+  await delay(0);
+  reader.releaseLock();
+  await promise_rejects_js(t, TypeError, read, 'pending read should reject');
+}, 'pull() resolving should not resolve read()');
 
 promise_test(() => {
   // Tests https://github.com/whatwg/streams/issues/686
@@ -2111,3 +2220,659 @@
   assert_throws_js(RangeError, () => new ReadableStream({ type: 'bytes' }, new HasSizeMethod()),
                    'constructor should throw when size on the prototype chain');
 }, 'ReadableStream constructor should not accept a strategy with a size defined if type is "bytes"');
+
+promise_test(async t => {
+  const stream = new ReadableStream({
+    pull: t.step_func(c => {
+      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 1);
+      view[0] = 1;
+
+      c.byobRequest.respondWithNewView(view);
+    }),
+    type: 'bytes'
+  });
+  const reader = stream.getReader({ mode: 'byob' });
+
+  const result = await reader.read(new Uint8Array([4, 5, 6]));
+  assert_false(result.done, 'result.done');
+
+  const view = result.value;
+  assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
+  assert_equals(view.byteLength, 1, 'result.value.byteLength');
+  assert_equals(view[0], 1, 'result.value[0]');
+  assert_equals(view.buffer.byteLength, 3, 'result.value.buffer.byteLength');
+  assert_array_equals([...new Uint8Array(view.buffer)], [1, 5, 6], 'result.value.buffer');
+}, 'ReadableStream with byte source: respondWithNewView() with a smaller view');
+
+promise_test(async t => {
+  const stream = new ReadableStream({
+    pull: t.step_func(c => {
+      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 0);
+
+      c.close();
+
+      c.byobRequest.respondWithNewView(view);
+    }),
+    type: 'bytes'
+  });
+  const reader = stream.getReader({ mode: 'byob' });
+
+  const result = await reader.read(new Uint8Array([4, 5, 6]));
+  assert_true(result.done, 'result.done');
+
+  const view = result.value;
+  assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
+  assert_equals(view.byteLength, 0, 'result.value.byteLength');
+  assert_equals(view.buffer.byteLength, 3, 'result.value.buffer.byteLength');
+  assert_array_equals([...new Uint8Array(view.buffer)], [4, 5, 6], 'result.value.buffer');
+}, 'ReadableStream with byte source: respondWithNewView() with a zero-length view (in the closed state)');
+
+promise_test(async t => {
+  let controller;
+  let resolvePullCalledPromise;
+  const pullCalledPromise = new Promise(resolve => {
+    resolvePullCalledPromise = resolve;
+  });
+  const stream = new ReadableStream({
+    start: t.step_func((c) => {
+      controller = c;
+    }),
+    pull: t.step_func(() => {
+      resolvePullCalledPromise();
+    }),
+    type: 'bytes'
+  });
+
+  const reader = stream.getReader({ mode: 'byob' });
+  const readPromise = reader.read(new Uint8Array([4, 5, 6]));
+  await pullCalledPromise;
+
+  // Transfer the original BYOB request's buffer, and respond with a new view on that buffer
+  const transferredView = await transferArrayBufferView(controller.byobRequest.view);
+  const newView = transferredView.subarray(0, 1);
+  newView[0] = 42;
+
+  controller.byobRequest.respondWithNewView(newView);
+
+  const result = await readPromise;
+  assert_false(result.done, 'result.done');
+
+  const view = result.value;
+  assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
+  assert_equals(view.byteLength, 1, 'result.value.byteLength');
+  assert_equals(view[0], 42, 'result.value[0]');
+  assert_equals(view.buffer.byteLength, 3, 'result.value.buffer.byteLength');
+  assert_array_equals([...new Uint8Array(view.buffer)], [42, 5, 6], 'result.value.buffer');
+
+}, 'ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view ' +
+   '(in the readable state)');
+
+promise_test(async t => {
+  let controller;
+  let resolvePullCalledPromise;
+  const pullCalledPromise = new Promise(resolve => {
+    resolvePullCalledPromise = resolve;
+  });
+  const stream = new ReadableStream({
+    start: t.step_func((c) => {
+      controller = c;
+    }),
+    pull: t.step_func(() => {
+      resolvePullCalledPromise();
+    }),
+    type: 'bytes'
+  });
+
+  const reader = stream.getReader({ mode: 'byob' });
+  const readPromise = reader.read(new Uint8Array([4, 5, 6]));
+  await pullCalledPromise;
+
+  // Transfer the original BYOB request's buffer, and respond with an empty view on that buffer
+  const transferredView = await transferArrayBufferView(controller.byobRequest.view);
+  const newView = transferredView.subarray(0, 0);
+
+  controller.close();
+  controller.byobRequest.respondWithNewView(newView);
+
+  const result = await readPromise;
+  assert_true(result.done, 'result.done');
+
+  const view = result.value;
+  assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
+  assert_equals(view.byteLength, 0, 'result.value.byteLength');
+  assert_equals(view.buffer.byteLength, 3, 'result.value.buffer.byteLength');
+  assert_array_equals([...new Uint8Array(view.buffer)], [4, 5, 6], 'result.value.buffer');
+
+}, 'ReadableStream with byte source: respondWithNewView() with a transferred zero-length view ' +
+   '(in the closed state)');
+
+promise_test(async t => {
+  let controller;
+  let pullCount = 0;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    autoAllocateChunkSize: 10,
+    start: t.step_func((c) => {
+      controller = c;
+    }),
+    pull: t.step_func(() => {
+      ++pullCount;
+    })
+  });
+
+  await flushAsyncEvents();
+  assert_equals(pullCount, 0, 'pull() must not have been invoked yet');
+
+  const reader1 = rs.getReader();
+  const read1 = reader1.read();
+  assert_equals(pullCount, 1, 'pull() must have been invoked once');
+  const byobRequest1 = controller.byobRequest;
+  assert_equals(byobRequest1.view.byteLength, 10, 'first byobRequest.view.byteLength');
+
+  // enqueue() must discard the auto-allocated BYOB request
+  controller.enqueue(new Uint8Array([1, 2, 3]));
+  assert_equals(byobRequest1.view, null, 'first byobRequest must be invalidated after enqueue()');
+
+  const result1 = await read1;
+  assert_false(result1.done, 'first result.done');
+  const view1 = result1.value;
+  assert_equals(view1.byteOffset, 0, 'first result.value.byteOffset');
+  assert_equals(view1.byteLength, 3, 'first result.value.byteLength');
+  assert_array_equals([...new Uint8Array(view1.buffer)], [1, 2, 3], 'first result.value.buffer');
+
+  reader1.releaseLock();
+
+  // read(view) should work after discarding the auto-allocated BYOB request
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
+  assert_equals(pullCount, 2, 'pull() must have been invoked twice');
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2.view.byteOffset, 0, 'second byobRequest.view.byteOffset');
+  assert_equals(byobRequest2.view.byteLength, 3, 'second byobRequest.view.byteLength');
+  assert_array_equals([...new Uint8Array(byobRequest2.view.buffer)], [4, 5, 6], 'second byobRequest.view.buffer');
+
+  byobRequest2.respond(3);
+  assert_equals(byobRequest2.view, null, 'second byobRequest must be invalidated after respond()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  const view2 = result2.value;
+  assert_equals(view2.byteOffset, 0, 'second result.value.byteOffset');
+  assert_equals(view2.byteLength, 3, 'second result.value.byteLength');
+  assert_array_equals([...new Uint8Array(view2.buffer)], [4, 5, 6], 'second result.value.buffer');
+
+  reader2.releaseLock();
+  assert_equals(pullCount, 2, 'pull() must only have been invoked twice');
+}, 'ReadableStream with byte source: enqueue() discards auto-allocated BYOB request');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader({ mode: 'byob' });
+  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  assert_equals(controller.byobRequest, byobRequest1, 'byobRequest should be unchanged');
+  assert_array_equals([...new Uint8Array(byobRequest1.view.buffer)], [1, 2, 3], 'byobRequest.view.buffer should be unchanged');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // respond() should fulfill the *second* read() request
+  byobRequest1.view[0] = 11;
+  byobRequest1.respond(1);
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([11, 5, 6]).subarray(0, 1), 'second result.value');
+
+}, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respond()');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader({ mode: 'byob' });
+  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint16Array(1));
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  assert_equals(controller.byobRequest, byobRequest1, 'byobRequest should be unchanged');
+  assert_array_equals([...new Uint8Array(byobRequest1.view.buffer)], [1, 2, 3], 'byobRequest.view.buffer should be unchanged');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // respond(1) should partially fill the second read(), but not yet fulfill it
+  byobRequest1.view[0] = 0x11;
+  byobRequest1.respond(1);
+
+  // second BYOB request should use remaining buffer from the second read()
+  const byobRequest2 = controller.byobRequest;
+  assert_not_equals(byobRequest2, null, 'second byobRequest should exist');
+  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'second byobRequest.view');
+
+  // second respond(1) should fill the read request and fulfill it
+  byobRequest2.view[0] = 0x22;
+  byobRequest2.respond(1);
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  const view2 = result2.value;
+  assert_equals(view2.byteOffset, 0, 'second result.value.byteOffset');
+  assert_equals(view2.byteLength, 2, 'second result.value.byteLength');
+  const dataView2 = new DataView(view2.buffer, view2.byteOffset, view2.byteLength);
+  assert_equals(dataView2.getUint16(0), 0x1122, 'second result.value[0]');
+
+}, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with ' +
+   '1 element Uint16Array, respond(1)');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader({ mode: 'byob' });
+  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint8Array([4, 5]));
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  assert_equals(controller.byobRequest, byobRequest1, 'byobRequest should be unchanged');
+  assert_array_equals([...new Uint8Array(byobRequest1.view.buffer)], [1, 2, 3], 'byobRequest.view.buffer should be unchanged');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // respond(3) should fulfill the second read(), and put 1 remaining byte in the queue
+  byobRequest1.view[0] = 6;
+  byobRequest1.view[1] = 7;
+  byobRequest1.view[2] = 8;
+  byobRequest1.respond(3);
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([6, 7]), 'second result.value');
+
+  // third read() should fulfill with the remaining byte
+  const result3 = await reader2.read(new Uint8Array([0, 0, 0]));
+  assert_false(result3.done, 'third result.done');
+  assert_typed_array_equals(result3.value, new Uint8Array([8, 0, 0]).subarray(0, 1), 'third result.value');
+
+}, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with ' +
+   '2 element Uint8Array, respond(3)');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader({ mode: 'byob' });
+  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // respondWithNewView() should fulfill the *second* read() request
+  byobRequest1.view[0] = 11;
+  byobRequest1.view[1] = 12;
+  byobRequest1.respondWithNewView(byobRequest1.view.subarray(0, 2));
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2, null, 'byobRequest should be null after respondWithNewView()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([11, 12, 6]).subarray(0, 2), 'second result.value');
+
+}, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respondWithNewView()');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader({ mode: 'byob' });
+  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // enqueue() should fulfill the *second* read() request
+  controller.enqueue(new Uint8Array([11, 12]));
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2, null, 'byobRequest should be null after enqueue()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([11, 12, 6]).subarray(0, 2), 'second result.value');
+
+}, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, enqueue()');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader({ mode: 'byob' });
+  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // close() followed by respond(0) should fulfill the second read()
+  controller.close();
+  byobRequest1.respond(0);
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
+
+  const result2 = await read2;
+  assert_true(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([4, 5, 6]).subarray(0, 0), 'second result.value');
+}, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, ' +
+   'close(), respond(0)');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    autoAllocateChunkSize: 4,
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader();
+  const read1 = reader1.read();
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array(4), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader();
+  const read2 = reader2.read();
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // respond() should fulfill the *second* read() request
+  byobRequest1.view[0] = 11;
+  byobRequest1.respond(1);
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([11, 0, 0, 0]).subarray(0, 1), 'second result.value');
+
+}, 'ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, respond()');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    autoAllocateChunkSize: 4,
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader();
+  const read1 = reader1.read();
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array(4), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader();
+  const read2 = reader2.read();
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // enqueue() should fulfill the *second* read() request
+  controller.enqueue(new Uint8Array([11]));
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2, null, 'byobRequest should be null after enqueue()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([11]), 'second result.value');
+
+}, 'ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, enqueue()');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    autoAllocateChunkSize: 4,
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader();
+  const read1 = reader1.read();
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array(4), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // respond() should fulfill the *second* read() request
+  byobRequest1.view[0] = 11;
+  byobRequest1.respond(1);
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([11, 5, 6]).subarray(0, 1), 'second result.value');
+
+}, 'ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, respond()');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    autoAllocateChunkSize: 4,
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader();
+  const read1 = reader1.read();
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array(4), 'first byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // enqueue() should fulfill the *second* read() request
+  controller.enqueue(new Uint8Array([11]));
+  const byobRequest2 = controller.byobRequest;
+  assert_equals(byobRequest2, null, 'byobRequest should be null after enqueue()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([11, 5, 6]).subarray(0, 1), 'second result.value');
+
+}, 'ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, enqueue()');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader({ mode: 'byob' });
+  const read1 = reader1.read(new Uint16Array(1));
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([0, 0]), 'first byobRequest.view');
+
+  // respond(1) should partially fill the first read(), but not yet fulfill it
+  byobRequest1.view[0] = 0x11;
+  byobRequest1.respond(1);
+  const byobRequest2 = controller.byobRequest;
+  assert_not_equals(byobRequest2, null, 'second byobRequest should exist');
+  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'second byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader({ mode: 'byob' });
+  const read2 = reader2.read(new Uint16Array(1));
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  assert_equals(controller.byobRequest, byobRequest2, 'byobRequest should be unchanged');
+  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'byobRequest.view should be unchanged');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // second respond(1) should fill the read request and fulfill it
+  byobRequest2.view[0] = 0x22;
+  byobRequest2.respond(1);
+  assert_equals(controller.byobRequest, null, 'byobRequest should be invalidated after second respond()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  const view2 = result2.value;
+  assert_equals(view2.byteOffset, 0, 'second result.value.byteOffset');
+  assert_equals(view2.byteLength, 2, 'second result.value.byteLength');
+  const dataView2 = new DataView(view2.buffer, view2.byteOffset, view2.byteLength);
+  assert_equals(dataView2.getUint16(0), 0x1122, 'second result.value[0]');
+
+}, 'ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read(view) on ' +
+   'second reader with 1 element Uint16Array, respond(1)');
+
+promise_test(async t => {
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start: t.step_func((c) => {
+      controller = c;
+    })
+  });
+  await flushAsyncEvents();
+
+  const reader1 = rs.getReader({ mode: 'byob' });
+  const read1 = reader1.read(new Uint16Array(1));
+  const byobRequest1 = controller.byobRequest;
+  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([0, 0]), 'first byobRequest.view');
+
+  // respond(1) should partially fill the first read(), but not yet fulfill it
+  byobRequest1.view[0] = 0x11;
+  byobRequest1.respond(1);
+  const byobRequest2 = controller.byobRequest;
+  assert_not_equals(byobRequest2, null, 'second byobRequest should exist');
+  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'second byobRequest.view');
+
+  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
+  reader1.releaseLock();
+  const reader2 = rs.getReader();
+  const read2 = reader2.read();
+  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
+  assert_equals(controller.byobRequest, byobRequest2, 'byobRequest should be unchanged');
+  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'byobRequest.view should be unchanged');
+  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
+
+  // enqueue() should fulfill the read request and put remaining byte in the queue
+  controller.enqueue(new Uint8Array([0x22]));
+  assert_equals(controller.byobRequest, null, 'byobRequest should be invalidated after second respond()');
+
+  const result2 = await read2;
+  assert_false(result2.done, 'second result.done');
+  assert_typed_array_equals(result2.value, new Uint8Array([0x11]), 'second result.value');
+
+  const result3 = await reader2.read();
+  assert_false(result3.done, 'third result.done');
+  assert_typed_array_equals(result3.value, new Uint8Array([0x22]), 'third result.value');
+
+}, 'ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read() on ' +
+   'second reader, enqueue()');
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.serviceworker-expected.txt
new file mode 100644
index 0000000..633e307
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.serviceworker-expected.txt
@@ -0,0 +1,107 @@
+
+Harness Error (TIMEOUT), message = null
+
+PASS getReader({mode: "byob"}) throws on non-bytes streams
+PASS ReadableStream with byte source can be constructed with no errors
+PASS getReader({mode}) must perform ToString()
+PASS ReadableStream with byte source: Construct and expect start and pull being called
+PASS ReadableStream with byte source: No automatic pull call if start doesn't finish
+PASS ReadableStream with byte source: start() throws an exception
+PASS ReadableStream with byte source: Construct with highWaterMark of 0
+PASS ReadableStream with byte source: desiredSize when closed
+PASS ReadableStream with byte source: desiredSize when errored
+PASS ReadableStream with byte source: getReader(), then releaseLock()
+PASS ReadableStream with byte source: getReader() with mode set to byob, then releaseLock()
+PASS ReadableStream with byte source: Test that closing a stream does not release a reader automatically
+PASS ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically
+PASS ReadableStream with byte source: Test that erroring a stream does not release a reader automatically
+PASS ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically
+FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: There are still pending read requests, cannot release the lock"
+FAIL ReadableStream with byte source: releaseLock() on ReadableStreamBYOBReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: There are still pending read requests, cannot release the lock"
+PASS ReadableStream with byte source: Automatic pull() after start()
+PASS ReadableStream with byte source: Automatic pull() after start() and read()
+FAIL ReadableStream with byte source: autoAllocateChunkSize assert_equals: pull() must have been invoked twice expected 2 but got 1
+PASS ReadableStream with byte source: Mix of auto allocate and BYOB
+PASS ReadableStream with byte source: Automatic pull() after start() and read(view)
+PASS ReadableStream with byte source: enqueue(), getReader(), then read()
+PASS ReadableStream with byte source: Push source that doesn't understand pull signal
+FAIL ReadableStream with byte source: pull() function is not callable assert_throws_js: constructor should throw function "() => new ReadableStream({
+    pull: 'foo',
+    type: 'bytes'
+  })" did not throw
+PASS ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read()
+PASS ReadableStream with byte source: enqueue(), read(view) partially, then read()
+PASS ReadableStream with byte source: getReader(), enqueue(), close(), then read()
+PASS ReadableStream with byte source: enqueue(), close(), getReader(), then read()
+FAIL ReadableStream with byte source: Respond to pull() by enqueue() assert_equals: byobRequest must be null expected (object) null but got (undefined) undefined
+FAIL ReadableStream with byte source: Respond to pull() by enqueue() asynchronously assert_equals: byobRequest should be null expected (object) null but got (undefined) undefined
+TIMEOUT ReadableStream with byte source: Respond to multiple pull() by separate enqueue() Test timed out
+NOTRUN ReadableStream with byte source: read(view), then respond()
+NOTRUN ReadableStream with byte source: read(view), then respondWithNewView() with a transferred ArrayBuffer
+NOTRUN ReadableStream with byte source: read(view), then respond() with too big value
+NOTRUN ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder
+NOTRUN ReadableStream with byte source: enqueue(), getReader(), then read(view)
+NOTRUN ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB)
+NOTRUN ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB)
+NOTRUN ReadableStream with byte source: getReader(), read(view), then cancel()
+NOTRUN ReadableStream with byte source: cancel() with partially filled pending pull() request
+NOTRUN ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully covered by view
+NOTRUN ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view)
+NOTRUN ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view
+NOTRUN ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views
+NOTRUN ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array
+NOTRUN ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array
+NOTRUN ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must fail
+NOTRUN ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with Uint16Array
+PASS ReadableStream with byte source: Throw if close()-ed more than once
+PASS ReadableStream with byte source: Throw on enqueue() after close()
+NOTRUN ReadableStream with byte source: read(view), then respond() and close() in pull()
+NOTRUN ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls
+NOTRUN ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple enqueue() calls
+NOTRUN ReadableStream with byte source: read() twice, then enqueue() twice
+NOTRUN ReadableStream with byte source: Multiple read(view), close() and respond()
+NOTRUN ReadableStream with byte source: Multiple read(view), big enqueue()
+NOTRUN ReadableStream with byte source: Multiple read(view) and multiple enqueue()
+NOTRUN ReadableStream with byte source: read(view) with passing undefined as view must fail
+NOTRUN ReadableStream with byte source: read(view) with passing an empty object as view must fail
+NOTRUN ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail
+NOTRUN ReadableStream with byte source: read() on an errored stream
+NOTRUN ReadableStream with byte source: read(), then error()
+NOTRUN ReadableStream with byte source: read(view) on an errored stream
+NOTRUN ReadableStream with byte source: read(view), then error()
+NOTRUN ReadableStream with byte source: Throwing in pull function must error the stream
+NOTRUN ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it
+NOTRUN ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream
+NOTRUN ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it
+NOTRUN calling respond() twice on the same byobRequest should throw
+NOTRUN calling respondWithNewView() twice on the same byobRequest should throw
+NOTRUN calling respond(0) twice on the same byobRequest should throw even when closed
+NOTRUN calling respond() should throw when canceled
+NOTRUN pull() resolving should not resolve read()
+NOTRUN ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction
+FAIL ReadableStream with byte source: autoAllocateChunkSize cannot be 0 assert_throws_js: controller cannot be setup with autoAllocateChunkSize = 0 function "() => new ReadableStream({ autoAllocateChunkSize: 0, type: 'bytes' })" threw object "RangeError: autoAllocateChunkSize value is negative or equal to positive or negative infinity" ("RangeError") expected instance of function "function TypeError() {
+    [native code]
+}" ("TypeError")
+PASS ReadableStreamBYOBReader can be constructed directly
+PASS ReadableStreamBYOBReader constructor requires a ReadableStream argument
+PASS ReadableStreamBYOBReader constructor requires an unlocked ReadableStream
+PASS ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes"
+PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes"
+NOTRUN ReadableStream with byte source: respondWithNewView() with a smaller view
+NOTRUN ReadableStream with byte source: respondWithNewView() with a zero-length view (in the closed state)
+NOTRUN ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view (in the readable state)
+NOTRUN ReadableStream with byte source: respondWithNewView() with a transferred zero-length view (in the closed state)
+NOTRUN ReadableStream with byte source: enqueue() discards auto-allocated BYOB request
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respond()
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 1 element Uint16Array, respond(1)
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 2 element Uint8Array, respond(3)
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respondWithNewView()
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, enqueue()
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, close(), respond(0)
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, respond()
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, enqueue()
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, respond()
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, enqueue()
+NOTRUN ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read(view) on second reader with 1 element Uint16Array, respond(1)
+NOTRUN ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read() on second reader, enqueue()
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.worker-expected.txt
index 1166534..633e307 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.worker-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.worker-expected.txt
@@ -16,7 +16,8 @@
 PASS ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically
 PASS ReadableStream with byte source: Test that erroring a stream does not release a reader automatically
 PASS ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically
-PASS ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader with pending read() must throw
+FAIL ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: There are still pending read requests, cannot release the lock"
+FAIL ReadableStream with byte source: releaseLock() on ReadableStreamBYOBReader must reject pending read() promise_test: Unhandled rejection with value: object "TypeError: There are still pending read requests, cannot release the lock"
 PASS ReadableStream with byte source: Automatic pull() after start()
 PASS ReadableStream with byte source: Automatic pull() after start() and read()
 FAIL ReadableStream with byte source: autoAllocateChunkSize assert_equals: pull() must have been invoked twice expected 2 but got 1
@@ -36,7 +37,7 @@
 FAIL ReadableStream with byte source: Respond to pull() by enqueue() asynchronously assert_equals: byobRequest should be null expected (object) null but got (undefined) undefined
 TIMEOUT ReadableStream with byte source: Respond to multiple pull() by separate enqueue() Test timed out
 NOTRUN ReadableStream with byte source: read(view), then respond()
-NOTRUN ReadableStream with byte source: read(view), then respond() with a transferred ArrayBuffer
+NOTRUN ReadableStream with byte source: read(view), then respondWithNewView() with a transferred ArrayBuffer
 NOTRUN ReadableStream with byte source: read(view), then respond() with too big value
 NOTRUN ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte remainder
 NOTRUN ReadableStream with byte source: enqueue(), getReader(), then read(view)
@@ -56,6 +57,7 @@
 PASS ReadableStream with byte source: Throw on enqueue() after close()
 NOTRUN ReadableStream with byte source: read(view), then respond() and close() in pull()
 NOTRUN ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls
+NOTRUN ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple enqueue() calls
 NOTRUN ReadableStream with byte source: read() twice, then enqueue() twice
 NOTRUN ReadableStream with byte source: Multiple read(view), close() and respond()
 NOTRUN ReadableStream with byte source: Multiple read(view), big enqueue()
@@ -74,7 +76,8 @@
 NOTRUN calling respond() twice on the same byobRequest should throw
 NOTRUN calling respondWithNewView() twice on the same byobRequest should throw
 NOTRUN calling respond(0) twice on the same byobRequest should throw even when closed
-NOTRUN pull() resolving should not make releaseLock() possible
+NOTRUN calling respond() should throw when canceled
+NOTRUN pull() resolving should not resolve read()
 NOTRUN ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction
 FAIL ReadableStream with byte source: autoAllocateChunkSize cannot be 0 assert_throws_js: controller cannot be setup with autoAllocateChunkSize = 0 function "() => new ReadableStream({ autoAllocateChunkSize: 0, type: 'bytes' })" threw object "RangeError: autoAllocateChunkSize value is negative or equal to positive or negative infinity" ("RangeError") expected instance of function "function TypeError() {
     [native code]
@@ -84,4 +87,21 @@
 PASS ReadableStreamBYOBReader constructor requires an unlocked ReadableStream
 PASS ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes"
 PASS ReadableStream constructor should not accept a strategy with a size defined if type is "bytes"
+NOTRUN ReadableStream with byte source: respondWithNewView() with a smaller view
+NOTRUN ReadableStream with byte source: respondWithNewView() with a zero-length view (in the closed state)
+NOTRUN ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view (in the readable state)
+NOTRUN ReadableStream with byte source: respondWithNewView() with a transferred zero-length view (in the closed state)
+NOTRUN ReadableStream with byte source: enqueue() discards auto-allocated BYOB request
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respond()
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 1 element Uint16Array, respond(1)
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with 2 element Uint8Array, respond(3)
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respondWithNewView()
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, enqueue()
+NOTRUN ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, close(), respond(0)
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, respond()
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, enqueue()
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, respond()
+NOTRUN ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, enqueue()
+NOTRUN ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read(view) on second reader with 1 element Uint16Array, respond(1)
+NOTRUN ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read() on second reader, enqueue()
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any-expected.txt
new file mode 100644
index 0000000..b9cacff
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any-expected.txt
@@ -0,0 +1,5 @@
+
+FAIL ReadableStream with byte source: read() with a non-transferable buffer assert_unreached: pull() should not be called Reached unreachable code
+FAIL ReadableStream with byte source: enqueue() with a non-transferable buffer assert_throws_js: function "() => controller.enqueue(view)" did not throw
+FAIL ReadableStream with byte source: respondWithNewView() with a non-transferable buffer assert_unreached: read() should not resolve Reached unreachable code
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.js
new file mode 100644
index 0000000..7c0bffb
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.js
@@ -0,0 +1,58 @@
+// META: global=window,worker,jsshell
+'use strict';
+
+promise_test(async t => {
+  const rs = new ReadableStream({
+    pull: t.unreached_func('pull() should not be called'),
+    type: 'bytes'
+  });
+
+  const reader = rs.getReader({ mode: 'byob' });
+  const memory = new WebAssembly.Memory({ initial: 1 });
+  const view = new Uint8Array(memory.buffer, 0, 1);
+  await promise_rejects_js(t, TypeError, reader.read(view));
+}, 'ReadableStream with byte source: read() with a non-transferable buffer');
+
+test(t => {
+  let controller;
+  const rs = new ReadableStream({
+    start(c) {
+      controller = c;
+    },
+    pull: t.unreached_func('pull() should not be called'),
+    type: 'bytes'
+  });
+
+  const memory = new WebAssembly.Memory({ initial: 1 });
+  const view = new Uint8Array(memory.buffer, 0, 1);
+  assert_throws_js(TypeError, () => controller.enqueue(view));
+}, 'ReadableStream with byte source: enqueue() with a non-transferable buffer');
+
+promise_test(async t => {
+  let byobRequest;
+  let resolvePullCalledPromise;
+  const pullCalledPromise = new Promise(resolve => {
+    resolvePullCalledPromise = resolve;
+  });
+  const rs = new ReadableStream({
+    pull(controller) {
+      byobRequest = controller.byobRequest;
+      resolvePullCalledPromise();
+    },
+    type: 'bytes'
+  });
+
+  const memory = new WebAssembly.Memory({ initial: 1 });
+  // Make sure the backing buffers of both views have the same length
+  const byobView = new Uint8Array(new ArrayBuffer(memory.buffer.byteLength), 0, 1);
+  const newView = new Uint8Array(memory.buffer, byobView.byteOffset, byobView.byteLength);
+
+  const reader = rs.getReader({ mode: 'byob' });
+  reader.read(byobView).then(
+    t.unreached_func('read() should not resolve'),
+    t.unreached_func('read() should not reject')
+  );
+  await pullCalledPromise;
+
+  assert_throws_js(TypeError, () => byobRequest.respondWithNewView(newView));
+}, 'ReadableStream with byte source: respondWithNewView() with a non-transferable buffer');
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.serviceworker-expected.txt
new file mode 100644
index 0000000..b9cacff
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.serviceworker-expected.txt
@@ -0,0 +1,5 @@
+
+FAIL ReadableStream with byte source: read() with a non-transferable buffer assert_unreached: pull() should not be called Reached unreachable code
+FAIL ReadableStream with byte source: enqueue() with a non-transferable buffer assert_throws_js: function "() => controller.enqueue(view)" did not throw
+FAIL ReadableStream with byte source: respondWithNewView() with a non-transferable buffer assert_unreached: read() should not resolve Reached unreachable code
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.worker-expected.txt
new file mode 100644
index 0000000..b9cacff
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.worker-expected.txt
@@ -0,0 +1,5 @@
+
+FAIL ReadableStream with byte source: read() with a non-transferable buffer assert_unreached: pull() should not be called Reached unreachable code
+FAIL ReadableStream with byte source: enqueue() with a non-transferable buffer assert_throws_js: function "() => controller.enqueue(view)" did not throw
+FAIL ReadableStream with byte source: respondWithNewView() with a non-transferable buffer assert_unreached: read() should not resolve Reached unreachable code
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.worker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.worker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.worker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any-expected.txt
new file mode 100644
index 0000000..868009d
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any-expected.txt
@@ -0,0 +1,5 @@
+
+FAIL byobRequest.respond() after enqueue() should not crash promise_test: Unhandled rejection with value: object "ReferenceError: Can't find private variable: PrivateSymbol.Uint8Array"
+FAIL byobRequest.respond() with cached byobRequest after enqueue() should not crash promise_test: Unhandled rejection with value: object "ReferenceError: Can't find private variable: PrivateSymbol.Uint8Array"
+FAIL byobRequest.respond() after enqueue() with double read should not crash promise_test: Unhandled rejection with value: object "ReferenceError: Can't find private variable: PrivateSymbol.Uint8Array"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.js
new file mode 100644
index 0000000..f4be0d4
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.js
@@ -0,0 +1,55 @@
+// META: global=window,worker,jsshell
+
+'use strict';
+
+// Repro for Blink bug https://crbug.com/1255762.
+promise_test(async () => {
+  const rs = new ReadableStream({
+    type: 'bytes',
+    autoAllocateChunkSize: 10,
+    pull(controller) {
+      controller.enqueue(new Uint8Array([1, 2, 3]));
+      controller.byobRequest.respond(10);
+    }
+  });
+
+  const reader = rs.getReader();
+  const {value, done} = await reader.read();
+  assert_false(done, 'done should not be true');
+  assert_array_equals(value, [1, 2, 3], 'value should be 3 bytes');
+}, 'byobRequest.respond() after enqueue() should not crash');
+
+promise_test(async () => {
+  const rs = new ReadableStream({
+    type: 'bytes',
+    autoAllocateChunkSize: 10,
+    pull(controller) {
+      const byobRequest = controller.byobRequest;
+      controller.enqueue(new Uint8Array([1, 2, 3]));
+      byobRequest.respond(10);
+    }
+  });
+
+  const reader = rs.getReader();
+  const {value, done} = await reader.read();
+  assert_false(done, 'done should not be true');
+  assert_array_equals(value, [1, 2, 3], 'value should be 3 bytes');
+}, 'byobRequest.respond() with cached byobRequest after enqueue() should not crash');
+
+promise_test(async () => {
+  const rs = new ReadableStream({
+    type: 'bytes',
+    autoAllocateChunkSize: 10,
+    pull(controller) {
+      controller.enqueue(new Uint8Array([1, 2, 3]));
+      controller.byobRequest.respond(2);
+    }
+  });
+
+  const reader = rs.getReader();
+  const [read1, read2] = await Promise.all([reader.read(), reader.read()]);
+  assert_false(read1.done, 'read1.done should not be true');
+  assert_array_equals(read1.value, [1, 2, 3], 'read1.value should be 3 bytes');
+  assert_false(read2.done, 'read2.done should not be true');
+  assert_array_equals(read2.value, [0, 0], 'read2.value should be 2 bytes');
+}, 'byobRequest.respond() after enqueue() with double read should not crash');
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.serviceworker-expected.txt
new file mode 100644
index 0000000..868009d
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.serviceworker-expected.txt
@@ -0,0 +1,5 @@
+
+FAIL byobRequest.respond() after enqueue() should not crash promise_test: Unhandled rejection with value: object "ReferenceError: Can't find private variable: PrivateSymbol.Uint8Array"
+FAIL byobRequest.respond() with cached byobRequest after enqueue() should not crash promise_test: Unhandled rejection with value: object "ReferenceError: Can't find private variable: PrivateSymbol.Uint8Array"
+FAIL byobRequest.respond() after enqueue() with double read should not crash promise_test: Unhandled rejection with value: object "ReferenceError: Can't find private variable: PrivateSymbol.Uint8Array"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.worker-expected.txt
new file mode 100644
index 0000000..868009d
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.worker-expected.txt
@@ -0,0 +1,5 @@
+
+FAIL byobRequest.respond() after enqueue() should not crash promise_test: Unhandled rejection with value: object "ReferenceError: Can't find private variable: PrivateSymbol.Uint8Array"
+FAIL byobRequest.respond() with cached byobRequest after enqueue() should not crash promise_test: Unhandled rejection with value: object "ReferenceError: Can't find private variable: PrivateSymbol.Uint8Array"
+FAIL byobRequest.respond() after enqueue() with double read should not crash promise_test: Unhandled rejection with value: object "ReferenceError: Can't find private variable: PrivateSymbol.Uint8Array"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.worker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.worker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.worker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any-expected.txt
new file mode 100644
index 0000000..a569360
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any-expected.txt
@@ -0,0 +1,48 @@
+CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'c.byobRequest.view')
+CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'c.byobRequest.view')
+CONSOLE MESSAGE: Unhandled Promise Rejection: [object Object]
+CONSOLE MESSAGE: Unhandled Promise Rejection: [object Object]
+CONSOLE MESSAGE: Unhandled Promise Rejection: [object Object]
+CONSOLE MESSAGE: Unhandled Promise Rejection: [object Object]
+
+Harness Error (FAIL), message = Unhandled rejection
+
+PASS ReadableStream teeing with byte source: rs.tee() returns an array of two ReadableStreams
+FAIL ReadableStream teeing with byte source: should be able to read one branch to the end without affecting the other promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: chunks should be cloned for each branch assert_not_equals: chunks should have different buffers got disallowed value object "[object ArrayBuffer]"
+FAIL ReadableStream teeing with byte source: chunks for BYOB requests from branch 1 should be cloned to branch 2 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: errors in the source should propagate to both branches promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+PASS ReadableStream teeing with byte source: canceling branch1 should not impact branch2
+PASS ReadableStream teeing with byte source: canceling branch2 should not impact branch1
+PASS Running templatedRSTeeCancel with ReadableStream teeing with byte source
+PASS ReadableStream teeing with byte source: canceling both branches should aggregate the cancel reasons into an array
+PASS ReadableStream teeing with byte source: canceling both branches in reverse order should aggregate the cancel reasons into an array
+PASS ReadableStream teeing with byte source: failing to cancel the original stream should cause cancel() to reject on branches
+PASS ReadableStream teeing with byte source: erroring a teed stream should properly handle canceled branches
+FAIL ReadableStream teeing with byte source: closing the original should close the branches promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: erroring the original should immediately error the branches promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+PASS ReadableStream teeing with byte source: erroring the original should error pending reads from default reader
+FAIL ReadableStream teeing with byte source: erroring the original should error pending reads from BYOB reader promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: canceling branch1 should finish when branch2 reads until end of stream promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: canceling branch1 should finish when original stream errors promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: should not pull any chunks if no branches are reading assert_array_equals: pull should not be called lengths differ, expected array [] length 0, got ["pull", "pull"] length 2
+FAIL ReadableStream teeing with byte source: should only pull enough to fill the emptiest queue promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: should not pull when original is already errored promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: stops pulling when original stream errors while branch 1 is reading promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: stops pulling when original stream errors while branch 2 is reading promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: stops pulling when original stream errors while both branches are reading promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: canceling both branches in sequence with delay promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: failing to cancel when canceling both branches in sequence with delay promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch1, cancel branch2 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch2, cancel branch1 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch2, enqueue to branch1 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch1, respond to branch2 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: pull with BYOB reader, then pull with default reader promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: pull with default reader, then pull with BYOB reader assert_equals: pull() should be called once expected 1 but got 3
+FAIL ReadableStream teeing with byte source: read from branch2, then read from branch1 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 with default reader, then close while branch2 has pending BYOB read promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch2 with default reader, then close while branch1 has pending BYOB read promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: close when both branches have pending BYOB reads promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+PASS ReadableStream teeing with byte source: enqueue() and close() while both branches are pulling
+FAIL ReadableStream teeing with byte source: respond() and close() while both branches are pulling promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.js
new file mode 100644
index 0000000..13f03f0
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.js
@@ -0,0 +1,936 @@
+// META: global=window,worker,jsshell
+// META: script=../resources/rs-utils.js
+// META: script=../resources/test-utils.js
+// META: script=../resources/recording-streams.js
+// META: script=../resources/rs-test-templates.js
+'use strict';
+
+test(() => {
+
+  const rs = new ReadableStream({ type: 'bytes' });
+  const result = rs.tee();
+
+  assert_true(Array.isArray(result), 'return value should be an array');
+  assert_equals(result.length, 2, 'array should have length 2');
+  assert_equals(result[0].constructor, ReadableStream, '0th element should be a ReadableStream');
+  assert_equals(result[1].constructor, ReadableStream, '1st element should be a ReadableStream');
+
+}, 'ReadableStream teeing with byte source: rs.tee() returns an array of two ReadableStreams');
+
+promise_test(async t => {
+
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      c.enqueue(new Uint8Array([0x01]));
+      c.enqueue(new Uint8Array([0x02]));
+      c.close();
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+  const reader2 = branch2.getReader({ mode: 'byob' });
+
+  reader2.closed.then(t.unreached_func('branch2 should not be closed'));
+
+  {
+    const result = await reader1.read(new Uint8Array(1));
+    assert_equals(result.done, false, 'done');
+    assert_typed_array_equals(result.value, new Uint8Array([0x01]), 'value');
+  }
+
+  {
+    const result = await reader1.read(new Uint8Array(1));
+    assert_equals(result.done, false, 'done');
+    assert_typed_array_equals(result.value, new Uint8Array([0x02]), 'value');
+  }
+
+  {
+    const result = await reader1.read(new Uint8Array(1));
+    assert_equals(result.done, true, 'done');
+    assert_typed_array_equals(result.value, new Uint8Array([0]).subarray(0, 0), 'value');
+  }
+
+  {
+    const result = await reader2.read(new Uint8Array(1));
+    assert_equals(result.done, false, 'done');
+    assert_typed_array_equals(result.value, new Uint8Array([0x01]), 'value');
+  }
+
+  await reader1.closed;
+
+}, 'ReadableStream teeing with byte source: should be able to read one branch to the end without affecting the other');
+
+promise_test(async () => {
+
+  let pullCount = 0;
+  const enqueuedChunk = new Uint8Array([0x01]);
+  const rs = new ReadableStream({
+    type: 'bytes',
+    pull(c) {
+      ++pullCount;
+      if (pullCount === 1) {
+        c.enqueue(enqueuedChunk);
+      }
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader();
+  const reader2 = branch2.getReader();
+
+  const [result1, result2] = await Promise.all([reader1.read(), reader2.read()]);
+  assert_equals(result1.done, false, 'reader1 done');
+  assert_equals(result2.done, false, 'reader2 done');
+
+  const view1 = result1.value;
+  const view2 = result2.value;
+  assert_typed_array_equals(view1, new Uint8Array([0x01]), 'reader1 value');
+  assert_typed_array_equals(view2, new Uint8Array([0x01]), 'reader2 value');
+
+  assert_not_equals(view1.buffer, view2.buffer, 'chunks should have different buffers');
+  assert_not_equals(enqueuedChunk.buffer, view1.buffer, 'enqueued chunk and branch1\'s chunk should have different buffers');
+  assert_not_equals(enqueuedChunk.buffer, view2.buffer, 'enqueued chunk and branch2\'s chunk should have different buffers');
+
+}, 'ReadableStream teeing with byte source: chunks should be cloned for each branch');
+
+promise_test(async () => {
+
+  let pullCount = 0;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    pull(c) {
+      ++pullCount;
+      if (pullCount === 1) {
+        c.byobRequest.view[0] = 0x01;
+        c.byobRequest.respond(1);
+      }
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+  const reader2 = branch2.getReader();
+  const buffer = new Uint8Array([42, 42, 42]).buffer;
+
+  {
+    const result = await reader1.read(new Uint8Array(buffer, 0, 1));
+    assert_equals(result.done, false, 'done');
+    assert_typed_array_equals(result.value, new Uint8Array([0x01, 42, 42]).subarray(0, 1), 'value');
+  }
+
+  {
+    const result = await reader2.read();
+    assert_equals(result.done, false, 'done');
+    assert_typed_array_equals(result.value, new Uint8Array([0x01]), 'value');
+  }
+
+}, 'ReadableStream teeing with byte source: chunks for BYOB requests from branch 1 should be cloned to branch 2');
+
+promise_test(async t => {
+
+  const theError = { name: 'boo!' };
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      c.enqueue(new Uint8Array([0x01]));
+      c.enqueue(new Uint8Array([0x02]));
+    },
+    pull() {
+      throw theError;
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+  const reader2 = branch2.getReader({ mode: 'byob' });
+
+  {
+    const result = await reader1.read(new Uint8Array(1));
+    assert_equals(result.done, false, 'first read from branch1 should not be done');
+    assert_typed_array_equals(result.value, new Uint8Array([0x01]), 'first read from branch1');
+  }
+
+  {
+    const result = await reader1.read(new Uint8Array(1));
+    assert_equals(result.done, false, 'second read from branch1 should not be done');
+    assert_typed_array_equals(result.value, new Uint8Array([0x02]), 'second read from branch1');
+  }
+
+  await promise_rejects_exactly(t, theError, reader1.read(new Uint8Array(1)));
+  await promise_rejects_exactly(t, theError, reader2.read(new Uint8Array(1)));
+
+  await Promise.all([
+    promise_rejects_exactly(t, theError, reader1.closed),
+    promise_rejects_exactly(t, theError, reader2.closed)
+  ]);
+
+}, 'ReadableStream teeing with byte source: errors in the source should propagate to both branches');
+
+promise_test(async () => {
+
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      c.enqueue(new Uint8Array([0x01]));
+      c.enqueue(new Uint8Array([0x02]));
+      c.close();
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  branch1.cancel();
+
+  const [chunks1, chunks2] = await Promise.all([readableStreamToArray(branch1), readableStreamToArray(branch2)]);
+  assert_array_equals(chunks1, [], 'branch1 should have no chunks');
+  assert_equals(chunks2.length, 2, 'branch2 should have two chunks');
+  assert_typed_array_equals(chunks2[0], new Uint8Array([0x01]), 'first chunk from branch2');
+  assert_typed_array_equals(chunks2[1], new Uint8Array([0x02]), 'second chunk from branch2');
+
+}, 'ReadableStream teeing with byte source: canceling branch1 should not impact branch2');
+
+promise_test(async () => {
+
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      c.enqueue(new Uint8Array([0x01]));
+      c.enqueue(new Uint8Array([0x02]));
+      c.close();
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  branch2.cancel();
+
+  const [chunks1, chunks2] = await Promise.all([readableStreamToArray(branch1), readableStreamToArray(branch2)]);
+  assert_equals(chunks1.length, 2, 'branch1 should have two chunks');
+  assert_typed_array_equals(chunks1[0], new Uint8Array([0x01]), 'first chunk from branch1');
+  assert_typed_array_equals(chunks1[1], new Uint8Array([0x02]), 'second chunk from branch1');
+  assert_array_equals(chunks2, [], 'branch2 should have no chunks');
+
+}, 'ReadableStream teeing with byte source: canceling branch2 should not impact branch1');
+
+templatedRSTeeCancel('ReadableStream teeing with byte source', (extras) => {
+  return new ReadableStream({ type: 'bytes', ...extras });
+});
+
+promise_test(async () => {
+
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      controller = c;
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+  const reader2 = branch2.getReader({ mode: 'byob' });
+
+  const promise = Promise.all([reader1.closed, reader2.closed]);
+
+  controller.close();
+
+  // The branches are created with HWM 0, so we need to read from at least one of them
+  // to observe the stream becoming closed.
+  const read1 = await reader1.read(new Uint8Array(1));
+  assert_equals(read1.done, true, 'first read from branch1 should be done');
+
+  await promise;
+
+}, 'ReadableStream teeing with byte source: closing the original should close the branches');
+
+promise_test(async t => {
+
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      controller = c;
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+  const reader2 = branch2.getReader({ mode: 'byob' });
+
+  const theError = { name: 'boo!' };
+  const promise = Promise.all([
+    promise_rejects_exactly(t, theError, reader1.closed),
+    promise_rejects_exactly(t, theError, reader2.closed)
+  ]);
+
+  controller.error(theError);
+  await promise;
+
+}, 'ReadableStream teeing with byte source: erroring the original should immediately error the branches');
+
+promise_test(async t => {
+
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      controller = c;
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader();
+  const reader2 = branch2.getReader();
+
+  const theError = { name: 'boo!' };
+  const promise = Promise.all([
+    promise_rejects_exactly(t, theError, reader1.read()),
+    promise_rejects_exactly(t, theError, reader2.read())
+  ]);
+
+  controller.error(theError);
+  await promise;
+
+}, 'ReadableStream teeing with byte source: erroring the original should error pending reads from default reader');
+
+promise_test(async t => {
+
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      controller = c;
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+  const reader2 = branch2.getReader({ mode: 'byob' });
+
+  const theError = { name: 'boo!' };
+  const promise = Promise.all([
+    promise_rejects_exactly(t, theError, reader1.read(new Uint8Array(1))),
+    promise_rejects_exactly(t, theError, reader2.read(new Uint8Array(1)))
+  ]);
+
+  controller.error(theError);
+  await promise;
+
+}, 'ReadableStream teeing with byte source: erroring the original should error pending reads from BYOB reader');
+
+promise_test(async () => {
+
+  let controller;
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      controller = c;
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+  const reader2 = branch2.getReader({ mode: 'byob' });
+  const cancelPromise = reader2.cancel();
+
+  controller.enqueue(new Uint8Array([0x01]));
+
+  const read1 = await reader1.read(new Uint8Array(1));
+  assert_equals(read1.done, false, 'first read() from branch1 should not be done');
+  assert_typed_array_equals(read1.value, new Uint8Array([0x01]), 'first read() from branch1');
+
+  controller.close();
+
+  const read2 = await reader1.read(new Uint8Array(1));
+  assert_equals(read2.done, true, 'second read() from branch1 should be done');
+
+  await Promise.all([
+    reader1.closed,
+    cancelPromise
+  ]);
+
+}, 'ReadableStream teeing with byte source: canceling branch1 should finish when branch2 reads until end of stream');
+
+promise_test(async t => {
+
+  let controller;
+  const theError = { name: 'boo!' };
+  const rs = new ReadableStream({
+    type: 'bytes',
+    start(c) {
+      controller = c;
+    }
+  });
+
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+  const reader2 = branch2.getReader({ mode: 'byob' });
+  const cancelPromise = reader2.cancel();
+
+  controller.error(theError);
+
+  await Promise.all([
+    promise_rejects_exactly(t, theError, reader1.read(new Uint8Array(1))),
+    cancelPromise
+  ]);
+
+}, 'ReadableStream teeing with byte source: canceling branch1 should finish when original stream errors');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+
+  // Create two branches, each with a HWM of 0. This should result in no chunks being pulled.
+  rs.tee();
+
+  await flushAsyncEvents();
+  assert_array_equals(rs.events, [], 'pull should not be called');
+
+}, 'ReadableStream teeing with byte source: should not pull any chunks if no branches are reading');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({
+    type: 'bytes',
+    pull(controller) {
+      controller.enqueue(new Uint8Array([0x01]));
+    }
+  });
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+  await Promise.all([
+    reader1.read(new Uint8Array(1)),
+    reader2.read(new Uint8Array(1))
+  ]);
+  assert_array_equals(rs.events, ['pull'], 'pull should be called once');
+
+}, 'ReadableStream teeing with byte source: should only pull enough to fill the emptiest queue');
+
+promise_test(async t => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+  const theError = { name: 'boo!' };
+
+  rs.controller.error(theError);
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+  await flushAsyncEvents();
+  assert_array_equals(rs.events, [], 'pull should not be called');
+
+  await Promise.all([
+    promise_rejects_exactly(t, theError, reader1.closed),
+    promise_rejects_exactly(t, theError, reader2.closed)
+  ]);
+
+}, 'ReadableStream teeing with byte source: should not pull when original is already errored');
+
+for (const branch of [1, 2]) {
+  promise_test(async t => {
+
+    const rs = recordingReadableStream({ type: 'bytes' });
+    const theError = { name: 'boo!' };
+
+    const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+    await flushAsyncEvents();
+    assert_array_equals(rs.events, [], 'pull should not be called');
+
+    const reader = (branch === 1) ? reader1 : reader2;
+    const read1 = reader.read(new Uint8Array(1));
+
+    await flushAsyncEvents();
+    assert_array_equals(rs.events, ['pull'], 'pull should be called once');
+
+    rs.controller.error(theError);
+
+    await Promise.all([
+      promise_rejects_exactly(t, theError, read1),
+      promise_rejects_exactly(t, theError, reader1.closed),
+      promise_rejects_exactly(t, theError, reader2.closed)
+    ]);
+
+    await flushAsyncEvents();
+    assert_array_equals(rs.events, ['pull'], 'pull should be called once');
+
+  }, `ReadableStream teeing with byte source: stops pulling when original stream errors while branch ${branch} is reading`);
+}
+
+promise_test(async t => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+  const theError = { name: 'boo!' };
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+  await flushAsyncEvents();
+  assert_array_equals(rs.events, [], 'pull should not be called');
+
+  const read1 = reader1.read(new Uint8Array(1));
+  const read2 = reader2.read(new Uint8Array(1));
+
+  await flushAsyncEvents();
+  assert_array_equals(rs.events, ['pull'], 'pull should be called once');
+
+  rs.controller.error(theError);
+
+  await Promise.all([
+    promise_rejects_exactly(t, theError, read1),
+    promise_rejects_exactly(t, theError, read2),
+    promise_rejects_exactly(t, theError, reader1.closed),
+    promise_rejects_exactly(t, theError, reader2.closed)
+  ]);
+
+  await flushAsyncEvents();
+  assert_array_equals(rs.events, ['pull'], 'pull should be called once');
+
+}, 'ReadableStream teeing with byte source: stops pulling when original stream errors while both branches are reading');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+  const read1 = reader1.read(new Uint8Array([0x11]));
+  const read2 = reader2.read(new Uint8Array([0x22]));
+
+  const cancel1 = reader1.cancel();
+  await flushAsyncEvents();
+  const cancel2 = reader2.cancel();
+
+  const result1 = await read1;
+  assert_object_equals(result1, { value: undefined, done: true });
+  const result2 = await read2;
+  assert_object_equals(result2, { value: undefined, done: true });
+
+  await Promise.all([cancel1, cancel2]);
+
+}, 'ReadableStream teeing with byte source: canceling both branches in sequence with delay');
+
+promise_test(async t => {
+
+  const theError = { name: 'boo!' };
+  const rs = new ReadableStream({
+    type: 'bytes',
+    cancel() {
+      throw theError;
+    }
+  });
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+  const read1 = reader1.read(new Uint8Array([0x11]));
+  const read2 = reader2.read(new Uint8Array([0x22]));
+
+  const cancel1 = reader1.cancel();
+  await flushAsyncEvents();
+  const cancel2 = reader2.cancel();
+
+  const result1 = await read1;
+  assert_object_equals(result1, { value: undefined, done: true });
+  const result2 = await read2;
+  assert_object_equals(result2, { value: undefined, done: true });
+
+  await Promise.all([
+    promise_rejects_exactly(t, theError, cancel1),
+    promise_rejects_exactly(t, theError, cancel2)
+  ]);
+
+}, 'ReadableStream teeing with byte source: failing to cancel when canceling both branches in sequence with delay');
+
+promise_test(async () => {
+
+  let cancelResolve;
+  const cancelCalled = new Promise((resolve) => {
+    cancelResolve = resolve;
+  });
+  const rs = recordingReadableStream({
+    type: 'bytes',
+    cancel() {
+      cancelResolve();
+    }
+  });
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+  const read1 = reader1.read(new Uint8Array([0x11]));
+  await flushAsyncEvents();
+  const read2 = reader2.read(new Uint8Array([0x22]));
+  await flushAsyncEvents();
+
+  // We are reading into branch1's buffer.
+  const byobRequest1 = rs.controller.byobRequest;
+  assert_not_equals(byobRequest1, null);
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([0x11]), 'byobRequest1.view');
+
+  // Cancelling branch1 should not affect the BYOB request.
+  const cancel1 = reader1.cancel();
+  const result1 = await read1;
+  assert_equals(result1.done, true);
+  assert_equals(result1.value, undefined);
+  await flushAsyncEvents();
+  const byobRequest2 = rs.controller.byobRequest;
+  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11]), 'byobRequest2.view');
+
+  // Cancelling branch1 should invalidate the BYOB request.
+  const cancel2 = reader2.cancel();
+  await cancelCalled;
+  const byobRequest3 = rs.controller.byobRequest;
+  assert_equals(byobRequest3, null);
+  const result2 = await read2;
+  assert_equals(result2.done, true);
+  assert_equals(result2.value, undefined);
+
+  await Promise.all([cancel1, cancel2]);
+
+}, 'ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch1, cancel branch2');
+
+promise_test(async () => {
+
+  let cancelResolve;
+  const cancelCalled = new Promise((resolve) => {
+    cancelResolve = resolve;
+  });
+  const rs = recordingReadableStream({
+    type: 'bytes',
+    cancel() {
+      cancelResolve();
+    }
+  });
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+  const read1 = reader1.read(new Uint8Array([0x11]));
+  await flushAsyncEvents();
+  const read2 = reader2.read(new Uint8Array([0x22]));
+  await flushAsyncEvents();
+
+  // We are reading into branch1's buffer.
+  const byobRequest1 = rs.controller.byobRequest;
+  assert_not_equals(byobRequest1, null);
+  assert_typed_array_equals(byobRequest1.view, new Uint8Array([0x11]), 'byobRequest1.view');
+
+  // Cancelling branch2 should not affect the BYOB request.
+  const cancel2 = reader2.cancel();
+  const result2 = await read2;
+  assert_equals(result2.done, true);
+  assert_equals(result2.value, undefined);
+  await flushAsyncEvents();
+  const byobRequest2 = rs.controller.byobRequest;
+  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11]), 'byobRequest2.view');
+
+  // Cancelling branch1 should invalidate the BYOB request.
+  const cancel1 = reader1.cancel();
+  await cancelCalled;
+  const byobRequest3 = rs.controller.byobRequest;
+  assert_equals(byobRequest3, null);
+  const result1 = await read1;
+  assert_equals(result1.done, true);
+  assert_equals(result1.value, undefined);
+
+  await Promise.all([cancel1, cancel2]);
+
+}, 'ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch2, cancel branch1');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+  const read1 = reader1.read(new Uint8Array([0x11]));
+  await flushAsyncEvents();
+  const read2 = reader2.read(new Uint8Array([0x22]));
+  await flushAsyncEvents();
+
+  // We are reading into branch1's buffer.
+  assert_typed_array_equals(rs.controller.byobRequest.view, new Uint8Array([0x11]), 'first byobRequest.view');
+
+  // Cancelling branch2 should not affect the BYOB request.
+  reader2.cancel();
+  const result2 = await read2;
+  assert_equals(result2.done, true);
+  assert_equals(result2.value, undefined);
+  await flushAsyncEvents();
+  assert_typed_array_equals(rs.controller.byobRequest.view, new Uint8Array([0x11]), 'second byobRequest.view');
+
+  // Respond to the BYOB request.
+  rs.controller.byobRequest.view[0] = 0x33;
+  rs.controller.byobRequest.respond(1);
+
+  // branch1 should receive the read chunk.
+  const result1 = await read1;
+  assert_equals(result1.done, false);
+  assert_typed_array_equals(result1.value, new Uint8Array([0x33]), 'first read() from branch1');
+
+}, 'ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch2, enqueue to branch1');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+  const read1 = reader1.read(new Uint8Array([0x11]));
+  await flushAsyncEvents();
+  const read2 = reader2.read(new Uint8Array([0x22]));
+  await flushAsyncEvents();
+
+  // We are reading into branch1's buffer.
+  assert_typed_array_equals(rs.controller.byobRequest.view, new Uint8Array([0x11]), 'first byobRequest.view');
+
+  // Cancelling branch1 should not affect the BYOB request.
+  reader1.cancel();
+  const result1 = await read1;
+  assert_equals(result1.done, true);
+  assert_equals(result1.value, undefined);
+  await flushAsyncEvents();
+  assert_typed_array_equals(rs.controller.byobRequest.view, new Uint8Array([0x11]), 'second byobRequest.view');
+
+  // Respond to the BYOB request.
+  rs.controller.byobRequest.view[0] = 0x33;
+  rs.controller.byobRequest.respond(1);
+
+  // branch2 should receive the read chunk.
+  const result2 = await read2;
+  assert_equals(result2.done, false);
+  assert_typed_array_equals(result2.value, new Uint8Array([0x33]), 'first read() from branch2');
+
+}, 'ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch1, respond to branch2');
+
+promise_test(async () => {
+
+  let pullCount = 0;
+  const byobRequestDefined = [];
+  const rs = new ReadableStream({
+    type: 'bytes',
+    pull(c) {
+      ++pullCount;
+      byobRequestDefined.push(c.byobRequest !== null);
+      c.enqueue(new Uint8Array([pullCount]));
+    }
+  });
+
+  const [branch1, _] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+
+  const result1 = await reader1.read(new Uint8Array([0x11]));
+  assert_equals(result1.done, false, 'first read should not be done');
+  assert_typed_array_equals(result1.value, new Uint8Array([0x1]), 'first read');
+  assert_equals(pullCount, 1, 'pull() should be called once');
+  assert_equals(byobRequestDefined[0], true, 'should have created a BYOB request for first read');
+
+  reader1.releaseLock();
+  const reader2 = branch1.getReader();
+
+  const result2 = await reader2.read();
+  assert_equals(result2.done, false, 'second read should not be done');
+  assert_typed_array_equals(result2.value, new Uint8Array([0x2]), 'second read');
+  assert_equals(pullCount, 2, 'pull() should be called twice');
+  assert_equals(byobRequestDefined[1], false, 'should not have created a BYOB request for second read');
+
+}, 'ReadableStream teeing with byte source: pull with BYOB reader, then pull with default reader');
+
+promise_test(async () => {
+
+  let pullCount = 0;
+  const byobRequestDefined = [];
+  const rs = new ReadableStream({
+    type: 'bytes',
+    pull(c) {
+      ++pullCount;
+      byobRequestDefined.push(c.byobRequest !== null);
+      c.enqueue(new Uint8Array([pullCount]));
+    }
+  });
+
+  const [branch1, _] = rs.tee();
+  const reader1 = branch1.getReader();
+
+  const result1 = await reader1.read();
+  assert_equals(result1.done, false, 'first read should not be done');
+  assert_typed_array_equals(result1.value, new Uint8Array([0x1]), 'first read');
+  assert_equals(pullCount, 1, 'pull() should be called once');
+  assert_equals(byobRequestDefined[0], false, 'should not have created a BYOB request for first read');
+
+  reader1.releaseLock();
+  const reader2 = branch1.getReader({ mode: 'byob' });
+
+  const result2 = await reader2.read(new Uint8Array([0x22]));
+  assert_equals(result2.done, false, 'second read should not be done');
+  assert_typed_array_equals(result2.value, new Uint8Array([0x2]), 'second read');
+  assert_equals(pullCount, 2, 'pull() should be called twice');
+  assert_equals(byobRequestDefined[1], true, 'should have created a BYOB request for second read');
+
+}, 'ReadableStream teeing with byte source: pull with default reader, then pull with BYOB reader');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({
+    type: 'bytes'
+  });
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+
+  // Wait for each branch's start() promise to resolve.
+  await flushAsyncEvents();
+
+  const read2 = reader2.read(new Uint8Array([0x22]));
+  const read1 = reader1.read(new Uint8Array([0x11]));
+  await flushAsyncEvents();
+
+  // branch2 should provide the BYOB request.
+  const byobRequest = rs.controller.byobRequest;
+  assert_typed_array_equals(byobRequest.view, new Uint8Array([0x22]), 'first BYOB request');
+  byobRequest.view[0] = 0x01;
+  byobRequest.respond(1);
+
+  const result1 = await read1;
+  assert_equals(result1.done, false, 'first read should not be done');
+  assert_typed_array_equals(result1.value, new Uint8Array([0x1]), 'first read');
+
+  const result2 = await read2;
+  assert_equals(result2.done, false, 'second read should not be done');
+  assert_typed_array_equals(result2.value, new Uint8Array([0x1]), 'second read');
+
+}, 'ReadableStream teeing with byte source: read from branch2, then read from branch1');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader();
+  const reader2 = branch2.getReader({ mode: 'byob' });
+  await flushAsyncEvents();
+
+  const read1 = reader1.read();
+  const read2 = reader2.read(new Uint8Array([0x22]));
+  await flushAsyncEvents();
+
+  // There should be no BYOB request.
+  assert_equals(rs.controller.byobRequest, null, 'first BYOB request');
+
+  // Close the stream.
+  rs.controller.close();
+
+  const result1 = await read1;
+  assert_equals(result1.done, true, 'read from branch1 should be done');
+  assert_equals(result1.value, undefined, 'read from branch1');
+
+  // branch2 should get its buffer back.
+  const result2 = await read2;
+  assert_equals(result2.done, true, 'read from branch2 should be done');
+  assert_typed_array_equals(result2.value, new Uint8Array([0x22]).subarray(0, 0), 'read from branch2');
+
+}, 'ReadableStream teeing with byte source: read from branch1 with default reader, then close while branch2 has pending BYOB read');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+  const [branch1, branch2] = rs.tee();
+  const reader1 = branch1.getReader({ mode: 'byob' });
+  const reader2 = branch2.getReader();
+  await flushAsyncEvents();
+
+  const read2 = reader2.read();
+  const read1 = reader1.read(new Uint8Array([0x11]));
+  await flushAsyncEvents();
+
+  // There should be no BYOB request.
+  assert_equals(rs.controller.byobRequest, null, 'first BYOB request');
+
+  // Close the stream.
+  rs.controller.close();
+
+  const result2 = await read2;
+  assert_equals(result2.done, true, 'read from branch2 should be done');
+  assert_equals(result2.value, undefined, 'read from branch2');
+
+  // branch1 should get its buffer back.
+  const result1 = await read1;
+  assert_equals(result1.done, true, 'read from branch1 should be done');
+  assert_typed_array_equals(result1.value, new Uint8Array([0x11]).subarray(0, 0), 'read from branch1');
+
+}, 'ReadableStream teeing with byte source: read from branch2 with default reader, then close while branch1 has pending BYOB read');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+  await flushAsyncEvents();
+
+  const read1 = reader1.read(new Uint8Array([0x11]));
+  const read2 = reader2.read(new Uint8Array([0x22]));
+  await flushAsyncEvents();
+
+  // branch1 should provide the BYOB request.
+  const byobRequest = rs.controller.byobRequest;
+  assert_typed_array_equals(byobRequest.view, new Uint8Array([0x11]), 'first BYOB request');
+
+  // Close the stream.
+  rs.controller.close();
+  byobRequest.respond(0);
+
+  // Both branches should get their buffers back.
+  const result1 = await read1;
+  assert_equals(result1.done, true, 'first read should be done');
+  assert_typed_array_equals(result1.value, new Uint8Array([0x11]).subarray(0, 0), 'first read');
+
+  const result2 = await read2;
+  assert_equals(result2.done, true, 'second read should be done');
+  assert_typed_array_equals(result2.value, new Uint8Array([0x22]).subarray(0, 0), 'second read');
+
+}, 'ReadableStream teeing with byte source: close when both branches have pending BYOB reads');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader());
+  const branch1Reads = [reader1.read(), reader1.read()];
+  const branch2Reads = [reader2.read(), reader2.read()];
+
+  await flushAsyncEvents();
+  rs.controller.enqueue(new Uint8Array([0x11]));
+  rs.controller.close();
+
+  const result1 = await branch1Reads[0];
+  assert_equals(result1.done, false, 'first read() from branch1 should be not done');
+  assert_typed_array_equals(result1.value, new Uint8Array([0x11]), 'first chunk from branch1 should be correct');
+  const result2 = await branch2Reads[0];
+  assert_equals(result2.done, false, 'first read() from branch2 should be not done');
+  assert_typed_array_equals(result2.value, new Uint8Array([0x11]), 'first chunk from branch2 should be correct');
+
+  assert_object_equals(await branch1Reads[1], { value: undefined, done: true }, 'second read() from branch1 should be done');
+  assert_object_equals(await branch2Reads[1], { value: undefined, done: true }, 'second read() from branch2 should be done');
+
+}, 'ReadableStream teeing with byte source: enqueue() and close() while both branches are pulling');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream({ type: 'bytes' });
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader({ mode: 'byob' }));
+  const branch1Reads = [reader1.read(new Uint8Array(1)), reader1.read(new Uint8Array(1))];
+  const branch2Reads = [reader2.read(new Uint8Array(1)), reader2.read(new Uint8Array(1))];
+
+  await flushAsyncEvents();
+  rs.controller.byobRequest.view[0] = 0x11;
+  rs.controller.byobRequest.respond(1);
+  rs.controller.close();
+
+  const result1 = await branch1Reads[0];
+  assert_equals(result1.done, false, 'first read() from branch1 should be not done');
+  assert_typed_array_equals(result1.value, new Uint8Array([0x11]), 'first chunk from branch1 should be correct');
+  const result2 = await branch2Reads[0];
+  assert_equals(result2.done, false, 'first read() from branch2 should be not done');
+  assert_typed_array_equals(result2.value, new Uint8Array([0x11]), 'first chunk from branch2 should be correct');
+
+  const result3 = await branch1Reads[1];
+  assert_equals(result3.done, true, 'second read() from branch1 should be done');
+  assert_typed_array_equals(result3.value, new Uint8Array([0]).subarray(0, 0), 'second chunk from branch1 should be correct');
+  const result4 = await branch2Reads[1];
+  assert_equals(result4.done, true, 'second read() from branch2 should be done');
+  assert_typed_array_equals(result4.value, new Uint8Array([0]).subarray(0, 0), 'second chunk from branch2 should be correct');
+
+}, 'ReadableStream teeing with byte source: respond() and close() while both branches are pulling');
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.serviceworker-expected.txt
new file mode 100644
index 0000000..5819a8f
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.serviceworker-expected.txt
@@ -0,0 +1,42 @@
+
+Harness Error (FAIL), message = Unhandled rejection
+
+PASS ReadableStream teeing with byte source: rs.tee() returns an array of two ReadableStreams
+FAIL ReadableStream teeing with byte source: should be able to read one branch to the end without affecting the other promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: chunks should be cloned for each branch assert_not_equals: chunks should have different buffers got disallowed value object "[object ArrayBuffer]"
+FAIL ReadableStream teeing with byte source: chunks for BYOB requests from branch 1 should be cloned to branch 2 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: errors in the source should propagate to both branches promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+PASS ReadableStream teeing with byte source: canceling branch1 should not impact branch2
+PASS ReadableStream teeing with byte source: canceling branch2 should not impact branch1
+PASS Running templatedRSTeeCancel with ReadableStream teeing with byte source
+PASS ReadableStream teeing with byte source: canceling both branches should aggregate the cancel reasons into an array
+PASS ReadableStream teeing with byte source: canceling both branches in reverse order should aggregate the cancel reasons into an array
+PASS ReadableStream teeing with byte source: failing to cancel the original stream should cause cancel() to reject on branches
+PASS ReadableStream teeing with byte source: erroring a teed stream should properly handle canceled branches
+FAIL ReadableStream teeing with byte source: closing the original should close the branches promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: erroring the original should immediately error the branches promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+PASS ReadableStream teeing with byte source: erroring the original should error pending reads from default reader
+FAIL ReadableStream teeing with byte source: erroring the original should error pending reads from BYOB reader promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: canceling branch1 should finish when branch2 reads until end of stream promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: canceling branch1 should finish when original stream errors promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: should not pull any chunks if no branches are reading assert_array_equals: pull should not be called lengths differ, expected array [] length 0, got ["pull", "pull"] length 2
+FAIL ReadableStream teeing with byte source: should only pull enough to fill the emptiest queue promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: should not pull when original is already errored promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: stops pulling when original stream errors while branch 1 is reading promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: stops pulling when original stream errors while branch 2 is reading promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: stops pulling when original stream errors while both branches are reading promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: canceling both branches in sequence with delay promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: failing to cancel when canceling both branches in sequence with delay promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch1, cancel branch2 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch2, cancel branch1 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch2, enqueue to branch1 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch1, respond to branch2 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: pull with BYOB reader, then pull with default reader promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: pull with default reader, then pull with BYOB reader assert_equals: pull() should be called once expected 1 but got 3
+FAIL ReadableStream teeing with byte source: read from branch2, then read from branch1 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 with default reader, then close while branch2 has pending BYOB read promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch2 with default reader, then close while branch1 has pending BYOB read promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: close when both branches have pending BYOB reads promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+PASS ReadableStream teeing with byte source: enqueue() and close() while both branches are pulling
+FAIL ReadableStream teeing with byte source: respond() and close() while both branches are pulling promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.worker-expected.txt
new file mode 100644
index 0000000..5819a8f
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.worker-expected.txt
@@ -0,0 +1,42 @@
+
+Harness Error (FAIL), message = Unhandled rejection
+
+PASS ReadableStream teeing with byte source: rs.tee() returns an array of two ReadableStreams
+FAIL ReadableStream teeing with byte source: should be able to read one branch to the end without affecting the other promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: chunks should be cloned for each branch assert_not_equals: chunks should have different buffers got disallowed value object "[object ArrayBuffer]"
+FAIL ReadableStream teeing with byte source: chunks for BYOB requests from branch 1 should be cloned to branch 2 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: errors in the source should propagate to both branches promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+PASS ReadableStream teeing with byte source: canceling branch1 should not impact branch2
+PASS ReadableStream teeing with byte source: canceling branch2 should not impact branch1
+PASS Running templatedRSTeeCancel with ReadableStream teeing with byte source
+PASS ReadableStream teeing with byte source: canceling both branches should aggregate the cancel reasons into an array
+PASS ReadableStream teeing with byte source: canceling both branches in reverse order should aggregate the cancel reasons into an array
+PASS ReadableStream teeing with byte source: failing to cancel the original stream should cause cancel() to reject on branches
+PASS ReadableStream teeing with byte source: erroring a teed stream should properly handle canceled branches
+FAIL ReadableStream teeing with byte source: closing the original should close the branches promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: erroring the original should immediately error the branches promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+PASS ReadableStream teeing with byte source: erroring the original should error pending reads from default reader
+FAIL ReadableStream teeing with byte source: erroring the original should error pending reads from BYOB reader promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: canceling branch1 should finish when branch2 reads until end of stream promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: canceling branch1 should finish when original stream errors promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: should not pull any chunks if no branches are reading assert_array_equals: pull should not be called lengths differ, expected array [] length 0, got ["pull", "pull"] length 2
+FAIL ReadableStream teeing with byte source: should only pull enough to fill the emptiest queue promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: should not pull when original is already errored promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: stops pulling when original stream errors while branch 1 is reading promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: stops pulling when original stream errors while branch 2 is reading promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: stops pulling when original stream errors while both branches are reading promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: canceling both branches in sequence with delay promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: failing to cancel when canceling both branches in sequence with delay promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch1, cancel branch2 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch2, cancel branch1 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch2, enqueue to branch1 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 and branch2, cancel branch1, respond to branch2 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: pull with BYOB reader, then pull with default reader promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: pull with default reader, then pull with BYOB reader assert_equals: pull() should be called once expected 1 but got 3
+FAIL ReadableStream teeing with byte source: read from branch2, then read from branch1 promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch1 with default reader, then close while branch2 has pending BYOB read promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: read from branch2 with default reader, then close while branch1 has pending BYOB read promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+FAIL ReadableStream teeing with byte source: close when both branches have pending BYOB reads promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+PASS ReadableStream teeing with byte source: enqueue() and close() while both branches are pulling
+FAIL ReadableStream teeing with byte source: respond() and close() while both branches are pulling promise_test: Unhandled rejection with value: object "TypeError: ReadableStreamBYOBReader needs a ReadableByteStreamController"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.worker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.worker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.worker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/w3c-import.log
index 0192f11..ad22726 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/w3c-import.log
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/w3c-import.log
@@ -16,4 +16,8 @@
 List of files:
 /LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.js
 /LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.any.js
+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/enqueue-with-detached-buffer.window.js
 /LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.js
+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.js
+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.js
+/LayoutTests/imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.js
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/async-iterator.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/async-iterator.any.serviceworker-expected.txt
new file mode 100644
index 0000000..ae66976
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/async-iterator.any.serviceworker-expected.txt
@@ -0,0 +1,41 @@
+
+FAIL Async iterator instances should have the correct list of properties s.values is not a function. (In 's.values()', 's.values' is undefined)
+FAIL Async-iterating a push source promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Async-iterating a pull source promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Async-iterating a push source with undefined values promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Async-iterating a pull source with undefined values promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Async-iterating a pull source manually promise_test: Unhandled rejection with value: object "TypeError: s.values is not a function. (In 's.values()', 's.values' is undefined)"
+FAIL Async-iterating an errored stream throws assert_equals: expected (string) "e" but got (object) object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Async-iterating a closed stream never executes the loop body, but works fine promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Async-iterating a partially consumed stream promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Cancellation behavior when throwing inside loop body; preventCancel = false assert_array_equals: cancel() should be called lengths differ, expected array ["pull", "cancel", undefined] length 3, got [] length 0
+FAIL Cancellation behavior when throwing inside loop body; preventCancel = true assert_array_equals: cancel() should not be called lengths differ, expected array ["pull"] length 1, got [] length 0
+FAIL Cancellation behavior when breaking inside loop body; preventCancel = false assert_array_equals: cancel() should be called lengths differ, expected array ["pull", "cancel", undefined] length 3, got [] length 0
+FAIL Cancellation behavior when breaking inside loop body; preventCancel = true assert_array_equals: cancel() should not be called lengths differ, expected array ["pull"] length 1, got [] length 0
+FAIL Cancellation behavior when returning inside loop body; preventCancel = false assert_array_equals: cancel() should be called lengths differ, expected array ["pull", "cancel", undefined] length 3, got [] length 0
+FAIL Cancellation behavior when returning inside loop body; preventCancel = true assert_array_equals: cancel() should not be called lengths differ, expected array ["pull"] length 1, got [] length 0
+FAIL Cancellation behavior when manually calling return(); preventCancel = false promise_test: Unhandled rejection with value: object "TypeError: s.values is not a function. (In 's.values({ preventCancel })', 's.values' is undefined)"
+FAIL Cancellation behavior when manually calling return(); preventCancel = true promise_test: Unhandled rejection with value: object "TypeError: s.values is not a function. (In 's.values({ preventCancel })', 's.values' is undefined)"
+FAIL next() rejects if the stream errors promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]()', 's[Symbol.asyncIterator]' is undefined)"
+FAIL return() does not rejects if the stream has not errored yet promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]()', 's[Symbol.asyncIterator]' is undefined)"
+FAIL return() rejects if the stream has errored promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]()', 's[Symbol.asyncIterator]' is undefined)"
+FAIL next() that succeeds; next() that reports an error; next() promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]()', 's[Symbol.asyncIterator]' is undefined)"
+FAIL next() that succeeds; next() that reports an error(); next() [no awaiting] promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]()', 's[Symbol.asyncIterator]' is undefined)"
+FAIL next() that succeeds; next() that reports an error(); return() promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]()', 's[Symbol.asyncIterator]' is undefined)"
+FAIL next() that succeeds; next() that reports an error(); return() [no awaiting] promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]()', 's[Symbol.asyncIterator]' is undefined)"
+FAIL next() that succeeds; return() promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]()', 's[Symbol.asyncIterator]' is undefined)"
+FAIL next() that succeeds; return() [no awaiting] promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]()', 's[Symbol.asyncIterator]' is undefined)"
+FAIL return(); next() promise_test: Unhandled rejection with value: object "TypeError: rs.values is not a function. (In 'rs.values()', 'rs.values' is undefined)"
+FAIL return(); next() [no awaiting] promise_test: Unhandled rejection with value: object "TypeError: rs.values is not a function. (In 'rs.values()', 'rs.values' is undefined)"
+FAIL return(); return() promise_test: Unhandled rejection with value: object "TypeError: rs.values is not a function. (In 'rs.values()', 'rs.values' is undefined)"
+FAIL return(); return() [no awaiting] promise_test: Unhandled rejection with value: object "TypeError: rs.values is not a function. (In 'rs.values()', 'rs.values' is undefined)"
+FAIL values() throws if there's already a lock s.values is not a function. (In 's.values()', 's.values' is undefined)
+FAIL Acquiring a reader after exhaustively async-iterating a stream promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Acquiring a reader after return()ing from a stream that errors promise_test: Unhandled rejection with value: object "TypeError: s[Symbol.asyncIterator] is not a function. (In 's[Symbol.asyncIterator]({ preventCancel: true })', 's[Symbol.asyncIterator]' is undefined)"
+FAIL Acquiring a reader after partially async-iterating a stream promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of s...')"
+FAIL Acquiring a reader and reading the remaining chunks after partially async-iterating a stream with preventCancel = true promise_test: Unhandled rejection with value: object "TypeError: s.values is not a function. (In 's.values({preventCancel: true})', 's.values' is undefined)"
+FAIL return() should unlock the stream synchronously when preventCancel = false rs.values is not a function. (In 'rs.values({ preventCancel })', 'rs.values' is undefined)
+FAIL return() should unlock the stream synchronously when preventCancel = true rs.values is not a function. (In 'rs.values({ preventCancel })', 'rs.values' is undefined)
+FAIL close() while next() is pending promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of rs...')"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/async-iterator.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/async-iterator.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/async-iterator.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.any.serviceworker-expected.txt
new file mode 100644
index 0000000..c360edd
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.any.serviceworker-expected.txt
@@ -0,0 +1,9 @@
+
+PASS Readable stream: throwing strategy.size getter
+PASS Readable stream: strategy.size errors the stream and then throws
+PASS Readable stream: strategy.size errors the stream and then returns Infinity
+PASS Readable stream: throwing strategy.size method
+PASS Readable stream: throwing strategy.highWaterMark getter
+PASS Readable stream: invalid strategy.highWaterMark
+PASS Readable stream: invalid strategy.size return value
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.any.serviceworker-expected.txt
new file mode 100644
index 0000000..82769dc
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.any.serviceworker-expected.txt
@@ -0,0 +1,24 @@
+
+PASS Underlying source start: throwing getter
+PASS Underlying source start: throwing method
+PASS Underlying source: throwing pull getter (initial pull)
+PASS Underlying source: throwing pull method (initial pull)
+PASS Underlying source pull: throwing getter (second pull does not result in a second get)
+PASS Underlying source pull: throwing method (second pull)
+PASS Underlying source cancel: throwing getter
+PASS Underlying source cancel: throwing method
+PASS Underlying source: calling enqueue on an empty canceled stream should throw
+PASS Underlying source: calling enqueue on a non-empty canceled stream should throw
+PASS Underlying source: calling enqueue on a closed stream should throw
+PASS Underlying source: calling enqueue on an errored stream should throw
+PASS Underlying source: calling close twice on an empty stream should throw the second time
+PASS Underlying source: calling close twice on a non-empty stream should throw the second time
+PASS Underlying source: calling close on an empty canceled stream should throw
+PASS Underlying source: calling close on a non-empty canceled stream should throw
+PASS Underlying source: calling close after error should throw
+PASS Underlying source: calling error twice should not throw
+PASS Underlying source: calling error after close should not throw
+PASS Underlying source: calling error and returning a rejected promise from start should cause the stream to error with the first error
+PASS Underlying source: calling error and returning a rejected promise from pull should cause the stream to error with the first error
+PASS read should not error if it dequeues and pull() throws
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.any.serviceworker-expected.txt
new file mode 100644
index 0000000..220a495
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.any.serviceworker-expected.txt
@@ -0,0 +1,12 @@
+
+PASS ReadableStream cancellation: integration test on an infinite stream derived from a random push source
+PASS ReadableStream cancellation: cancel(reason) should pass through the given reason to the underlying source
+PASS ReadableStream cancellation: cancel() on a locked stream should fail and not call the underlying source cancel
+PASS ReadableStream cancellation: should fulfill promise when cancel callback went fine
+PASS ReadableStream cancellation: returning a value from the underlying source's cancel should not affect the fulfillment value of the promise returned by the stream's cancel
+PASS ReadableStream cancellation: should reject promise when cancel callback raises an exception
+PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (1)
+PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (2)
+PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should reject when that one does
+PASS ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.any.serviceworker-expected.txt
new file mode 100644
index 0000000..1d3b3a7
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.any.serviceworker-expected.txt
@@ -0,0 +1,3 @@
+
+PASS underlyingSource argument should be converted after queuingStrategy argument
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/constructor.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.any.serviceworker-expected.txt
new file mode 100644
index 0000000..62aa4f3
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.any.serviceworker-expected.txt
@@ -0,0 +1,6 @@
+
+PASS Can construct a readable stream with a valid CountQueuingStrategy
+PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 0)
+PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 1)
+PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 4)
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any-expected.txt
index d194cbf..494c37c 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any-expected.txt
@@ -31,4 +31,5 @@
 PASS Reading twice on a stream that gets errored
 PASS getReader() should call ToString() on mode
 PASS controller.close() should clear the list of pending read requests
+FAIL Second reader can read chunks after first reader was released with pending read requests There are still pending read requests, cannot release the lock
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.js
index 60c740a..664853e 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.js
@@ -512,3 +512,28 @@
     reader.releaseLock();
   });
 }, 'controller.close() should clear the list of pending read requests');
+
+promise_test(t => {
+
+  let controller;
+  const rs = new ReadableStream({
+    start(c) {
+      controller = c;
+    }
+  });
+
+  const reader1 = rs.getReader();
+  const promise1 = promise_rejects_js(t, TypeError, reader1.read(), 'read() from reader1 should reject when reader1 is released');
+  reader1.releaseLock();
+
+  controller.enqueue('a');
+
+  const reader2 = rs.getReader();
+  const promise2 = reader2.read().then(r => {
+    assert_object_equals(r, { value: 'a', done: false }, 'read() from reader2 should resolve with enqueued chunk');
+  })
+  reader2.releaseLock();
+
+  return Promise.all([promise1, promise2]);
+
+}, 'Second reader can read chunks after first reader was released with pending read requests');
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.serviceworker-expected.txt
new file mode 100644
index 0000000..494c37c
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.serviceworker-expected.txt
@@ -0,0 +1,35 @@
+
+FAIL ReadableStreamDefaultReader constructor should get a ReadableStream object as argument assert_throws_js: function "() => new ReadableStreamDefaultReader('potato')" threw object "ReferenceError: Can't find variable: ReadableStreamDefaultReader" ("ReferenceError") expected instance of function "function TypeError() {
+    [native code]
+}" ("TypeError")
+FAIL ReadableStreamDefaultReader closed should always return the same promise object Can't find variable: ReadableStreamDefaultReader
+FAIL Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct construction) Can't find variable: ReadableStreamDefaultReader
+FAIL Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct construction) Can't find variable: ReadableStreamDefaultReader
+FAIL Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader) assert_throws_js: constructing directly should fail function "() => new ReadableStreamDefaultReader(rs)" threw object "ReferenceError: Can't find variable: ReadableStreamDefaultReader" ("ReferenceError") expected instance of function "function TypeError() {
+    [native code]
+}" ("TypeError")
+PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader)
+FAIL Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed Can't find variable: ReadableStreamDefaultReader
+FAIL Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored Can't find variable: ReadableStreamDefaultReader
+PASS Reading from a reader for an empty stream will wait until a chunk is available
+PASS cancel() on a reader does not release the reader
+PASS closed should be fulfilled after stream is closed (.closed access before acquiring)
+PASS closed should be rejected after reader releases its lock (multiple stream locks)
+PASS closed is replaced when stream closes and reader releases its lock
+PASS closed is replaced when stream errors and reader releases its lock
+PASS Multiple readers can access the stream in sequence
+PASS Cannot use an already-released reader to unlock a stream again
+PASS cancel() on a released reader is a no-op and does not pass through
+PASS Getting a second reader after erroring the stream and releasing the reader should succeed
+PASS ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error
+PASS ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined error
+PASS Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise
+PASS Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise
+PASS Reading twice on a stream that gets closed
+PASS Reading twice on a closed stream
+PASS Reading twice on an errored stream
+PASS Reading twice on a stream that gets errored
+PASS getReader() should call ToString() on mode
+PASS controller.close() should clear the list of pending read requests
+FAIL Second reader can read chunks after first reader was released with pending read requests There are still pending read requests, cannot release the lock
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.worker-expected.txt
index d194cbf..494c37c 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.worker-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.worker-expected.txt
@@ -31,4 +31,5 @@
 PASS Reading twice on a stream that gets errored
 PASS getReader() should call ToString() on mode
 PASS controller.close() should clear the list of pending read requests
+FAIL Second reader can read chunks after first reader was released with pending read requests There are still pending read requests, cannot release the lock
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/floating-point-total-queue-size.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/floating-point-total-queue-size.any.serviceworker-expected.txt
new file mode 100644
index 0000000..1a27a6c
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/floating-point-total-queue-size.any.serviceworker-expected.txt
@@ -0,0 +1,6 @@
+
+PASS Floating point arithmetic must manifest near NUMBER.MAX_SAFE_INTEGER (total ends up positive)
+PASS Floating point arithmetic must manifest near 0 (total ends up positive, but clamped)
+PASS Floating point arithmetic must manifest near 0 (total ends up positive, and not clamped)
+PASS Floating point arithmetic must manifest near 0 (total ends up zero)
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/floating-point-total-queue-size.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/floating-point-total-queue-size.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/floating-point-total-queue-size.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.any.serviceworker-expected.txt
new file mode 100644
index 0000000..aa41efc
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.any.serviceworker-expected.txt
@@ -0,0 +1,6 @@
+
+PASS ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream
+PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost
+PASS ReadableStream closed promise should reject even if stream and reader JS references are lost
+PASS Garbage-collecting a ReadableStreamDefaultReader should not unlock its stream
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.any.serviceworker-expected.txt
new file mode 100644
index 0000000..42a3084
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.any.serviceworker-expected.txt
@@ -0,0 +1,42 @@
+
+PASS ReadableStream can be constructed with no errors
+PASS ReadableStream can't be constructed with garbage
+FAIL ReadableStream can't be constructed with an invalid type assert_throws_js: constructor should throw when the type is null function "() => new ReadableStream({ type: null })" threw object "RangeError: Invalid type for underlying source" ("RangeError") expected instance of function "function TypeError() {
+    [native code]
+}" ("TypeError")
+PASS ReadableStream constructor should throw for non-function start arguments
+FAIL ReadableStream constructor will not tolerate initial garbage as cancel argument assert_throws_js: constructor should throw function "() => new ReadableStream({ cancel: '2' })" did not throw
+FAIL ReadableStream constructor will not tolerate initial garbage as pull argument assert_throws_js: constructor should throw function "() => new ReadableStream({ pull: { } })" did not throw
+PASS ReadableStream start should be called with the proper thisArg
+PASS ReadableStream start controller parameter should be extensible
+PASS default ReadableStream getReader() should only accept mode:undefined
+PASS ReadableStream should be able to call start method within prototype chain of its source
+PASS ReadableStream start should be able to return a promise
+PASS ReadableStream start should be able to return a promise and reject it
+PASS ReadableStream should be able to enqueue different objects.
+FAIL ReadableStream: if pull rejects, it should error the stream assert_true: expected true got false
+PASS ReadableStream: should only call pull once upon starting the stream
+PASS ReadableStream: should call pull when trying to read from a started, empty stream
+PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills
+PASS ReadableStream: should only call pull once on a non-empty stream read from after start fulfills
+PASS ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining
+PASS ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining
+PASS ReadableStream: should not call pull until the previous pull call's promise fulfills
+PASS ReadableStream: should pull after start, and after every read
+PASS ReadableStream: should not call pull after start if the stream is now closed
+PASS ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows
+PASS ReadableStream pull should be able to close a stream.
+PASS ReadableStream pull should be able to error a stream.
+PASS ReadableStream pull should be able to error a stream and throw.
+PASS ReadableStream: enqueue should throw when the stream is readable but draining
+PASS ReadableStream: enqueue should throw when the stream is closed
+PASS ReadableStream: should call underlying source methods as methods
+PASS ReadableStream: desiredSize when closed
+PASS ReadableStream: desiredSize when errored
+PASS Subclassing ReadableStream should work
+PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue
+PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately
+PASS ReadableStream integration test: adapting a random push source
+PASS ReadableStream integration test: adapting a sync pull source
+PASS ReadableStream integration test: adapting an async pull source
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.any.serviceworker-expected.txt
new file mode 100644
index 0000000..0805293
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.any.serviceworker-expected.txt
@@ -0,0 +1,7 @@
+
+PASS ReadableStream tee() should not touch Object.prototype properties
+PASS ReadableStream tee() should not call the global ReadableStream
+FAIL ReadableStream async iterator should use the original values of getReader() and ReadableStreamDefaultReader methods promise_test: Unhandled rejection with value: object "TypeError: undefined is not a function (near '...chunk of rs...')"
+PASS tee() should not call Promise.prototype.then()
+PASS pipeTo() should not call Promise.prototype.then()
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/patched-global.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.any.serviceworker-expected.txt
new file mode 100644
index 0000000..a0460e4
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.any.serviceworker-expected.txt
@@ -0,0 +1,12 @@
+
+PASS enqueue() inside size() should work
+PASS close() inside size() should not crash
+PASS close request inside size() should work
+PASS error() inside size() should work
+PASS desiredSize inside size() should work
+PASS cancel() inside size() should work
+PASS pipeTo() inside size() should behave as expected
+PASS read() inside of size() should behave as expected
+PASS getReader() inside size() should work
+PASS tee() inside size() should work
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any-expected.txt
index b65def9..b6d5ca0 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any-expected.txt
@@ -14,6 +14,7 @@
 PASS ReadableStream teeing: errors in the source should propagate to both branches
 PASS ReadableStream teeing: canceling branch1 should not impact branch2
 PASS ReadableStream teeing: canceling branch2 should not impact branch1
+PASS Running templatedRSTeeCancel with ReadableStream teeing
 PASS ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array
 PASS ReadableStream teeing: canceling both branches in reverse order should aggregate the cancel reasons into an array
 PASS ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches
@@ -32,4 +33,5 @@
 FAIL ReadableStreamTee stops pulling when original stream errors while branch 1 is reading assert_array_equals: pull should be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
 FAIL ReadableStreamTee stops pulling when original stream errors while branch 2 is reading assert_array_equals: pull should be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
 FAIL ReadableStreamTee stops pulling when original stream errors while both branches are reading assert_array_equals: pull should be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
+PASS ReadableStream teeing: enqueue() and close() while both branches are pulling
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.js b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.js
index 761f6e9..d6f5061 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.js
@@ -2,6 +2,7 @@
 // META: script=../resources/rs-utils.js
 // META: script=../resources/test-utils.js
 // META: script=../resources/recording-streams.js
+// META: script=../resources/rs-test-templates.js
 'use strict';
 
 test(() => {
@@ -161,92 +162,9 @@
 
 }, 'ReadableStream teeing: canceling branch2 should not impact branch1');
 
-promise_test(() => {
-
-  const reason1 = new Error('We\'re wanted men.');
-  const reason2 = new Error('I have the death sentence on twelve systems.');
-
-  let resolve;
-  const promise = new Promise(r => resolve = r);
-  const rs = new ReadableStream({
-    cancel(reason) {
-      assert_array_equals(reason, [reason1, reason2],
-                          'the cancel reason should be an array containing those from the branches');
-      resolve();
-    }
-  });
-
-  const branch = rs.tee();
-  const branch1 = branch[0];
-  const branch2 = branch[1];
-  branch1.cancel(reason1);
-  branch2.cancel(reason2);
-
-  return promise;
-
-}, 'ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array');
-
-promise_test(() => {
-
-  const reason1 = new Error('This little one\'s not worth the effort.');
-  const reason2 = new Error('Come, let me get you something.');
-
-  let resolve;
-  const promise = new Promise(r => resolve = r);
-  const rs = new ReadableStream({
-    cancel(reason) {
-      assert_array_equals(reason, [reason1, reason2],
-                          'the cancel reason should be an array containing those from the branches');
-      resolve();
-    }
-  });
-
-  const branch = rs.tee();
-  const branch1 = branch[0];
-  const branch2 = branch[1];
-  return Promise.all([
-    branch2.cancel(reason2),
-    branch1.cancel(reason1),
-    promise
-  ]);
-
-}, 'ReadableStream teeing: canceling both branches in reverse order should aggregate the cancel reasons into an array');
-
-promise_test(t => {
-
-  const theError = { name: 'I\'ll be careful.' };
-  const rs = new ReadableStream({
-    cancel() {
-      throw theError;
-    }
-  });
-
-  const branch = rs.tee();
-  const branch1 = branch[0];
-  const branch2 = branch[1];
-
-  return Promise.all([
-    promise_rejects_exactly(t, theError, branch1.cancel()),
-    promise_rejects_exactly(t, theError, branch2.cancel())
-  ]);
-
-}, 'ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches');
-
-promise_test(t => {
-
-  const theError = { name: 'You just watch yourself!' };
-  let controller;
-  const stream = new ReadableStream({ start(c) { controller = c; } });
-  const [branch1, branch2] = stream.tee();
-
-  controller.error(theError);
-
-  return Promise.all([
-    promise_rejects_exactly(t, theError, branch1.cancel()),
-    promise_rejects_exactly(t, theError, branch2.cancel())
-  ]);
-
-}, 'ReadableStream teeing: erroring a teed stream should properly handle canceled branches');
+templatedRSTeeCancel('ReadableStream teeing', (extras) => {
+  return new ReadableStream({ ...extras });
+});
 
 promise_test(t => {
 
@@ -539,3 +457,23 @@
   });
 
 }, 'ReadableStreamTee stops pulling when original stream errors while both branches are reading');
+
+promise_test(async () => {
+
+  const rs = recordingReadableStream();
+
+  const [reader1, reader2] = rs.tee().map(branch => branch.getReader());
+  const branch1Reads = [reader1.read(), reader1.read()];
+  const branch2Reads = [reader2.read(), reader2.read()];
+
+  await flushAsyncEvents();
+  rs.controller.enqueue('a');
+  rs.controller.close();
+
+  assert_object_equals(await branch1Reads[0], { value: 'a', done: false }, 'first chunk from branch1 should be correct');
+  assert_object_equals(await branch2Reads[0], { value: 'a', done: false }, 'first chunk from branch2 should be correct');
+
+  assert_object_equals(await branch1Reads[1], { value: undefined, done: true }, 'second read() from branch1 should be done');
+  assert_object_equals(await branch2Reads[1], { value: undefined, done: true }, 'second read() from branch2 should be done');
+
+}, 'ReadableStream teeing: enqueue() and close() while both branches are pulling');
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.serviceworker-expected.txt
new file mode 100644
index 0000000..b2fd9c3
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.serviceworker-expected.txt
@@ -0,0 +1,30 @@
+
+Harness Error (FAIL), message = Unhandled rejection
+
+PASS ReadableStream teeing: rs.tee() returns an array of two ReadableStreams
+PASS ReadableStream teeing: should be able to read one branch to the end without affecting the other
+PASS ReadableStream teeing: values should be equal across each branch
+PASS ReadableStream teeing: errors in the source should propagate to both branches
+PASS ReadableStream teeing: canceling branch1 should not impact branch2
+PASS ReadableStream teeing: canceling branch2 should not impact branch1
+PASS Running templatedRSTeeCancel with ReadableStream teeing
+PASS ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array
+PASS ReadableStream teeing: canceling both branches in reverse order should aggregate the cancel reasons into an array
+PASS ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches
+PASS ReadableStream teeing: erroring a teed stream should properly handle canceled branches
+PASS ReadableStream teeing: erroring a teed stream should error both branches
+PASS ReadableStream teeing: closing the original should immediately close the branches
+PASS ReadableStream teeing: erroring the original should immediately error the branches
+PASS ReadableStream teeing: canceling branch1 should finish when branch2 reads until end of stream
+PASS ReadableStream teeing: canceling branch1 should finish when original stream errors
+PASS ReadableStream teeing: canceling both branches in sequence with delay
+PASS ReadableStream teeing: failing to cancel when canceling both branches in sequence with delay
+PASS ReadableStreamTee should not use a modified ReadableStream constructor from the global object
+FAIL ReadableStreamTee should not pull more chunks than can fit in the branch queue assert_array_equals: pull should only be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
+FAIL ReadableStreamTee should only pull enough to fill the emptiest queue assert_array_equals: pull should be called twice lengths differ, expected array ["pull", "pull"] length 2, got ["pull", "pull", "pull", "pull"] length 4
+PASS ReadableStreamTee should not pull when original is already errored
+FAIL ReadableStreamTee stops pulling when original stream errors while branch 1 is reading assert_array_equals: pull should be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
+FAIL ReadableStreamTee stops pulling when original stream errors while branch 2 is reading assert_array_equals: pull should be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
+FAIL ReadableStreamTee stops pulling when original stream errors while both branches are reading assert_array_equals: pull should be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
+PASS ReadableStream teeing: enqueue() and close() while both branches are pulling
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.worker-expected.txt
index b866eaf..b2fd9c3 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.worker-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.any.worker-expected.txt
@@ -7,6 +7,7 @@
 PASS ReadableStream teeing: errors in the source should propagate to both branches
 PASS ReadableStream teeing: canceling branch1 should not impact branch2
 PASS ReadableStream teeing: canceling branch2 should not impact branch1
+PASS Running templatedRSTeeCancel with ReadableStream teeing
 PASS ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array
 PASS ReadableStream teeing: canceling both branches in reverse order should aggregate the cancel reasons into an array
 PASS ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches
@@ -25,4 +26,5 @@
 FAIL ReadableStreamTee stops pulling when original stream errors while branch 1 is reading assert_array_equals: pull should be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
 FAIL ReadableStreamTee stops pulling when original stream errors while branch 2 is reading assert_array_equals: pull should be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
 FAIL ReadableStreamTee stops pulling when original stream errors while both branches are reading assert_array_equals: pull should be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2
+PASS ReadableStream teeing: enqueue() and close() while both branches are pulling
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any-expected.txt
index f0571fd..1eb6fcd 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any-expected.txt
@@ -9,7 +9,7 @@
 PASS ReadableStream (empty) reader: two read()s should both never settle
 PASS ReadableStream (empty) reader: read() should return distinct promises each time
 PASS ReadableStream (empty) reader: getReader() again on the stream should fail
-PASS ReadableStream (empty) reader: releasing the lock with pending read requests should throw but the read requests should stay pending
+FAIL ReadableStream (empty) reader: releasing the lock should reject all pending read requests promise_test: Unhandled rejection with value: object "TypeError: There are still pending read requests, cannot release the lock"
 PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError
 PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError
 PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.serviceworker-expected.txt
new file mode 100644
index 0000000..1eb6fcd
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.serviceworker-expected.txt
@@ -0,0 +1,88 @@
+
+PASS Running templatedRSEmpty with ReadableStream (empty)
+PASS ReadableStream (empty): instances have the correct methods and properties
+PASS ReadableStream (empty): calling getReader with invalid arguments should throw appropriate errors
+PASS Running templatedRSEmptyReader with ReadableStream (empty) reader
+PASS ReadableStream (empty) reader: instances have the correct methods and properties
+PASS ReadableStream (empty) reader: locked should be true
+PASS ReadableStream (empty) reader: read() should never settle
+PASS ReadableStream (empty) reader: two read()s should both never settle
+PASS ReadableStream (empty) reader: read() should return distinct promises each time
+PASS ReadableStream (empty) reader: getReader() again on the stream should fail
+FAIL ReadableStream (empty) reader: releasing the lock should reject all pending read requests promise_test: Unhandled rejection with value: object "TypeError: There are still pending read requests, cannot release the lock"
+PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError
+PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError
+PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false
+PASS ReadableStream (empty) reader: canceling via the reader should cause the reader to act closed
+PASS ReadableStream (empty) reader: canceling via the stream should fail
+PASS Running templatedRSClosed with ReadableStream (closed via call in start)
+PASS ReadableStream (closed via call in start): cancel() should return a distinct fulfilled promise each time
+PASS ReadableStream (closed via call in start): locked should be false
+PASS ReadableStream (closed via call in start): getReader() should be OK
+PASS ReadableStream (closed via call in start): should be able to acquire multiple readers if they are released in succession
+PASS ReadableStream (closed via call in start): should not be able to acquire a second reader if we don't release the first one
+PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader)
+PASS ReadableStream reader (closed before getting reader): read() should fulfill with { value: undefined, done: true }
+PASS ReadableStream reader (closed before getting reader): read() multiple times should fulfill with { value: undefined, done: true }
+PASS ReadableStream reader (closed before getting reader): read() should work when used within another read() fulfill callback
+PASS ReadableStream reader (closed before getting reader): closed should fulfill with undefined
+PASS ReadableStream reader (closed before getting reader): releasing the lock should cause closed to reject and change identity
+PASS ReadableStream reader (closed before getting reader): cancel() should return a distinct fulfilled promise each time
+PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader)
+PASS ReadableStream reader (closed after getting reader): read() should fulfill with { value: undefined, done: true }
+PASS ReadableStream reader (closed after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
+PASS ReadableStream reader (closed after getting reader): read() should work when used within another read() fulfill callback
+PASS ReadableStream reader (closed after getting reader): closed should fulfill with undefined
+PASS ReadableStream reader (closed after getting reader): releasing the lock should cause closed to reject and change identity
+PASS ReadableStream reader (closed after getting reader): cancel() should return a distinct fulfilled promise each time
+PASS Running templatedRSClosed with ReadableStream (closed via cancel)
+PASS ReadableStream (closed via cancel): cancel() should return a distinct fulfilled promise each time
+PASS ReadableStream (closed via cancel): locked should be false
+PASS ReadableStream (closed via cancel): getReader() should be OK
+PASS ReadableStream (closed via cancel): should be able to acquire multiple readers if they are released in succession
+PASS ReadableStream (closed via cancel): should not be able to acquire a second reader if we don't release the first one
+PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader)
+PASS ReadableStream reader (closed via cancel after getting reader): read() should fulfill with { value: undefined, done: true }
+PASS ReadableStream reader (closed via cancel after getting reader): read() multiple times should fulfill with { value: undefined, done: true }
+PASS ReadableStream reader (closed via cancel after getting reader): read() should work when used within another read() fulfill callback
+PASS ReadableStream reader (closed via cancel after getting reader): closed should fulfill with undefined
+PASS ReadableStream reader (closed via cancel after getting reader): releasing the lock should cause closed to reject and change identity
+PASS ReadableStream reader (closed via cancel after getting reader): cancel() should return a distinct fulfilled promise each time
+PASS Running templatedRSErrored with ReadableStream (errored via call in start)
+PASS ReadableStream (errored via call in start): getReader() should return a reader that acts errored
+PASS ReadableStream (errored via call in start): read() twice should give the error each time
+PASS ReadableStream (errored via call in start): locked should be false
+PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start)
+PASS ReadableStream (errored via call in start): should be able to obtain a second reader, with the correct closed promise
+PASS ReadableStream (errored via call in start): should not be able to obtain additional readers if we don't release the first lock
+PASS ReadableStream (errored via call in start): cancel() should return a distinct rejected promise each time
+PASS ReadableStream (errored via call in start): reader cancel() should return a distinct rejected promise each time
+PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start)
+PASS ReadableStream (errored via returning a rejected promise in start): getReader() should return a reader that acts errored
+PASS ReadableStream (errored via returning a rejected promise in start): read() twice should give the error each time
+PASS ReadableStream (errored via returning a rejected promise in start): locked should be false
+PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader
+PASS ReadableStream (errored via returning a rejected promise in start) reader: closed should reject with the error
+PASS ReadableStream (errored via returning a rejected promise in start) reader: releasing the lock should cause closed to reject and change identity
+PASS ReadableStream (errored via returning a rejected promise in start) reader: read() should reject with the error
+PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader)
+PASS ReadableStream reader (errored before getting reader): closed should reject with the error
+PASS ReadableStream reader (errored before getting reader): releasing the lock should cause closed to reject and change identity
+PASS ReadableStream reader (errored before getting reader): read() should reject with the error
+PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader)
+PASS ReadableStream reader (errored after getting reader): closed should reject with the error
+PASS ReadableStream reader (errored after getting reader): releasing the lock should cause closed to reject and change identity
+PASS ReadableStream reader (errored after getting reader): read() should reject with the error
+PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader
+PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (sequential)
+PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (nested)
+PASS ReadableStream (two chunks enqueued, still open) reader: read() should return distinct promises each time
+PASS ReadableStream (two chunks enqueued, still open) reader: cancel() after a read() should still give that single read result
+PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader
+PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (sequential)
+PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (nested)
+PASS ReadableStream (two chunks enqueued, then closed) reader: draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true
+PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock after the stream is closed should cause locked to become false
+PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock should cause further read() calls to reject with a TypeError
+PASS ReadableStream (two chunks enqueued, then closed) reader: reader's closed property always returns the same promise
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.worker-expected.txt
index f0571fd..1eb6fcd 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.worker-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.any.worker-expected.txt
@@ -9,7 +9,7 @@
 PASS ReadableStream (empty) reader: two read()s should both never settle
 PASS ReadableStream (empty) reader: read() should return distinct promises each time
 PASS ReadableStream (empty) reader: getReader() again on the stream should fail
-PASS ReadableStream (empty) reader: releasing the lock with pending read requests should throw but the read requests should stay pending
+FAIL ReadableStream (empty) reader: releasing the lock should reject all pending read requests promise_test: Unhandled rejection with value: object "TypeError: There are still pending read requests, cannot release the lock"
 PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError
 PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError
 PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/recording-streams.js b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/recording-streams.js
index 34d02a1..661fe51 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/recording-streams.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/recording-streams.js
@@ -3,6 +3,7 @@
 self.recordingReadableStream = (extras = {}, strategy) => {
   let controllerToCopyOver;
   const stream = new ReadableStream({
+    type: extras.type,
     start(controller) {
       controllerToCopyOver = controller;
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-test-templates.js b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-test-templates.js
index 700bd9c..25751c4 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-test-templates.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-test-templates.js
@@ -251,34 +251,27 @@
 
   }, label + ': getReader() again on the stream should fail');
 
-  promise_test(t => {
+  promise_test(async t => {
 
     const streamAndReader = factory();
     const stream = streamAndReader.stream;
     const reader = streamAndReader.reader;
 
-    reader.read().then(
-      t.unreached_func('first read() should not fulfill'),
-      t.unreached_func('first read() should not reject')
-    );
+    const read1 = reader.read();
+    const read2 = reader.read();
+    const closed = reader.closed;
 
-    reader.read().then(
-      t.unreached_func('second read() should not fulfill'),
-      t.unreached_func('second read() should not reject')
-    );
+    reader.releaseLock();
 
-    reader.closed.then(
-      t.unreached_func('closed should not fulfill'),
-      t.unreached_func('closed should not reject')
-    );
+    assert_false(stream.locked, 'the stream should be unlocked');
 
-    assert_throws_js(TypeError, () => reader.releaseLock(), 'releaseLock should throw a TypeError');
+    await Promise.all([
+      promise_rejects_js(t, TypeError, read1, 'first read should reject'),
+      promise_rejects_js(t, TypeError, read2, 'second read should reject'),
+      promise_rejects_js(t, TypeError, closed, 'closed should reject')
+    ]);
 
-    assert_true(stream.locked, 'the stream should still be locked');
-
-    return delay(500);
-
-  }, label + ': releasing the lock with pending read requests should throw but the read requests should stay pending');
+  }, label + ': releasing the lock should reject all pending read requests');
 
   promise_test(t => {
 
@@ -636,3 +629,93 @@
 
   }, label + ': reader\'s closed property always returns the same promise');
 };
+
+self.templatedRSTeeCancel = (label, factory) => {
+  test(() => {}, `Running templatedRSTeeCancel with ${label}`);
+
+  promise_test(async () => {
+
+    const reason1 = new Error('We\'re wanted men.');
+    const reason2 = new Error('I have the death sentence on twelve systems.');
+
+    let resolve;
+    const promise = new Promise(r => resolve = r);
+    const rs = factory({
+      cancel(reason) {
+        assert_array_equals(reason, [reason1, reason2],
+          'the cancel reason should be an array containing those from the branches');
+        resolve();
+      }
+    });
+
+    const [branch1, branch2] = rs.tee();
+    await Promise.all([
+      branch1.cancel(reason1),
+      branch2.cancel(reason2),
+      promise
+    ]);
+
+  }, `${label}: canceling both branches should aggregate the cancel reasons into an array`);
+
+  promise_test(async () => {
+
+    const reason1 = new Error('This little one\'s not worth the effort.');
+    const reason2 = new Error('Come, let me get you something.');
+
+    let resolve;
+    const promise = new Promise(r => resolve = r);
+    const rs = factory({
+      cancel(reason) {
+        assert_array_equals(reason, [reason1, reason2],
+          'the cancel reason should be an array containing those from the branches');
+        resolve();
+      }
+    });
+
+    const [branch1, branch2] = rs.tee();
+    await Promise.all([
+      branch2.cancel(reason2),
+      branch1.cancel(reason1),
+      promise
+    ]);
+
+  }, `${label}: canceling both branches in reverse order should aggregate the cancel reasons into an array`);
+
+  promise_test(async t => {
+
+    const theError = { name: 'I\'ll be careful.' };
+    const rs = factory({
+      cancel() {
+        throw theError;
+      }
+    });
+
+    const [branch1, branch2] = rs.tee();
+    await Promise.all([
+      promise_rejects_exactly(t, theError, branch1.cancel()),
+      promise_rejects_exactly(t, theError, branch2.cancel())
+    ]);
+
+  }, `${label}: failing to cancel the original stream should cause cancel() to reject on branches`);
+
+  promise_test(async t => {
+
+    const theError = { name: 'You just watch yourself!' };
+    let controller;
+    const stream = factory({
+      start(c) {
+        controller = c;
+      }
+    });
+
+    const [branch1, branch2] = stream.tee();
+    controller.error(theError);
+
+    await Promise.all([
+      promise_rejects_exactly(t, theError, branch1.cancel()),
+      promise_rejects_exactly(t, theError, branch2.cancel())
+    ]);
+
+  }, `${label}: erroring a teed stream should properly handle canceled branches`);
+
+};
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-utils.js b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-utils.js
index a62012c..f1a0142 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-utils.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-utils.js
@@ -177,9 +177,21 @@
     return stream;
   }
 
+  function transferArrayBufferView(view) {
+    const noopByteStream = new ReadableStream({
+      type: 'bytes',
+      pull(c) {
+        c.byobRequest.respond(c.byobRequest.view.byteLength);
+        c.close();
+      }
+    });
+    const reader = noopByteStream.getReader({ mode: 'byob' });
+    return reader.read(view).then((result) => result.value);
+  }
 
   self.RandomPushSource = RandomPushSource;
   self.readableStreamToArray = readableStreamToArray;
   self.sequentialReadableStream = sequentialReadableStream;
+  self.transferArrayBufferView = transferArrayBufferView;
 
 }());
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/test-utils.js b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/test-utils.js
index 0593980..0b112a3 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/test-utils.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/resources/test-utils.js
@@ -72,3 +72,14 @@
 // Some tests include promise resolutions which may mean the test code takes a couple of event loop visits itself. So go
 // around an extra 2 times to avoid complicating those tests.
 self.flushAsyncEvents = () => delay(0).then(() => delay(0)).then(() => delay(0)).then(() => delay(0));
+
+self.assert_typed_array_equals = (actual, expected, message) => {
+  const prefix = message === undefined ? '' : `${message} `;
+  assert_equals(typeof actual, 'object', `${prefix}type is object`);
+  assert_equals(actual.constructor, expected.constructor, `${prefix}constructor`);
+  assert_equals(actual.byteOffset, expected.byteOffset, `${prefix}byteOffset`);
+  assert_equals(actual.byteLength, expected.byteLength, `${prefix}byteLength`);
+  assert_equals(actual.buffer.byteLength, expected.buffer.byteLength, `${prefix}buffer.byteLength`);
+  assert_array_equals([...actual], [...expected], `${prefix}contents`);
+  assert_array_equals([...new Uint8Array(actual.buffer)], [...new Uint8Array(expected.buffer)], `${prefix}buffer contents`);
+};
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.any.serviceworker-expected.txt
new file mode 100644
index 0000000..bc04c17
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.any.serviceworker-expected.txt
@@ -0,0 +1,16 @@
+
+PASS backpressure allows no transforms with a default identity transform and no reader
+PASS backpressure only allows one transform() with a identity transform with a readable HWM of 1 and no reader
+PASS transform() should keep being called as long as there is no backpressure
+PASS writes should resolve as soon as transform completes
+PASS calling pull() before the first write() with backpressure should work
+PASS transform() should be able to read the chunk it just enqueued
+PASS blocking transform() should cause backpressure
+PASS writer.closed should resolve after readable is canceled during start
+PASS writer.closed should resolve after readable is canceled with backpressure
+PASS writer.closed should resolve after readable is canceled with no backpressure
+PASS cancelling the readable should cause a pending write to resolve
+PASS cancelling the readable side of a TransformStream should abort an empty pipe
+PASS cancelling the readable side of a TransformStream should abort an empty pipe after startup
+PASS cancelling the readable side of a TransformStream should abort a full pipe
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/backpressure.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.any.serviceworker-expected.txt
new file mode 100644
index 0000000..2db9995
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.any.serviceworker-expected.txt
@@ -0,0 +1,22 @@
+
+PASS TransformStream errors thrown in transform put the writable and readable in an errored state
+PASS TransformStream errors thrown in flush put the writable and readable in an errored state
+PASS errored TransformStream should not enqueue new chunks
+PASS TransformStream transformer.start() rejected promise should error the stream
+PASS when controller.error is followed by a rejection, the error reason should come from controller.error
+PASS TransformStream constructor should throw when start does
+PASS when strategy.size throws inside start(), the constructor should throw the same error
+PASS when strategy.size calls controller.error() then throws, the constructor should throw the first error
+PASS cancelling the readable side should error the writable
+PASS it should be possible to error the readable between close requested and complete
+PASS an exception from transform() should error the stream if terminate has been requested but not completed
+PASS abort should set the close reason for the writable when it happens before cancel during start, but cancel should still succeed
+PASS abort should set the close reason for the writable when it happens before cancel during underlying sink write, but cancel should still succeed
+PASS controller.error() should do nothing the second time it is called
+PASS controller.error() should do nothing after readable.cancel()
+PASS controller.error() should do nothing after writable.abort() has completed
+PASS controller.error() should do nothing after a transformer method has thrown an exception
+PASS erroring during write with backpressure should result in the write failing
+PASS a write() that was waiting for backpressure should reject if the writable is aborted
+PASS the readable should be errored with the reason passed to the writable abort() method
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/errors.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.any.serviceworker-expected.txt
new file mode 100644
index 0000000..52b172a
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.any.serviceworker-expected.txt
@@ -0,0 +1,7 @@
+
+PASS TransformStream flush is called immediately when the writable is closed, if no writes are queued
+PASS TransformStream flush is called after all queued writes finish, once the writable is closed
+PASS TransformStream flush gets a chance to enqueue more into the readable
+PASS TransformStream flush gets a chance to enqueue more into the readable, and can then async close
+PASS error() during flush should cause writer.close() to reject
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/flush.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.any.serviceworker-expected.txt
new file mode 100644
index 0000000..a208a14
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.any.serviceworker-expected.txt
@@ -0,0 +1,27 @@
+
+PASS TransformStream can be constructed with a transform function
+PASS TransformStream can be constructed with no transform function
+PASS TransformStream writable starts in the writable state
+PASS Identity TransformStream: can read from readable what is put into writable
+PASS Uppercaser sync TransformStream: can read from readable transformed version of what is put into writable
+PASS Uppercaser-doubler sync TransformStream: can read both chunks put into the readable
+PASS Uppercaser async TransformStream: can read from readable transformed version of what is put into writable
+PASS Uppercaser-doubler async TransformStream: can read both chunks put into the readable
+PASS TransformStream: by default, closing the writable closes the readable (when there are no queued writes)
+PASS TransformStream: by default, closing the writable waits for transforms to finish before closing both
+PASS TransformStream: by default, closing the writable closes the readable after sync enqueues and async done
+PASS TransformStream: by default, closing the writable closes the readable after async enqueues and async done
+PASS Transform stream should call transformer methods as methods
+PASS methods should not not have .apply() or .call() called
+PASS TransformStream start, transform, and flush should be strictly ordered
+PASS it should be possible to call transform() synchronously
+PASS closing the writable should close the readable when there are no queued chunks, even with backpressure
+PASS enqueue() should throw after controller.terminate()
+PASS enqueue() should throw after readable.cancel()
+PASS controller.terminate() should do nothing the second time it is called
+PASS terminate() should do nothing after readable.cancel()
+PASS start() should not be called twice
+PASS specifying a defined readableType should throw
+PASS specifying a defined writableType should throw
+PASS Subclassing TransformStream should work
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/general.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.any.serviceworker-expected.txt
new file mode 100644
index 0000000..325c97f
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.any.serviceworker-expected.txt
@@ -0,0 +1,22 @@
+
+PASS testing "" (length 1)
+PASS testing "" (length 0)
+PASS testing "{{in1}}" (length 1)
+PASS testing "z{{in1}}" (length 1)
+PASS testing "{{in1}}q" (length 1)
+PASS testing "{{in1}}{{in1}" (length 1)
+PASS testing "{{in1}}{{in1},}" (length 2)
+PASS testing "{{in1,}}" (length 2)
+PASS testing "{{,in1}}" (length 2)
+PASS testing "{,{in1}}" (length 2)
+PASS testing "{{,in1}" (length 2)
+PASS testing "{" (length 1)
+PASS testing "{," (length 2)
+PASS testing "{,{,i,n,1,},}" (length 7)
+PASS testing "{{in1}}{{in2}}{{in1}}" (length 1)
+PASS testing "{{wrong}}" (length 1)
+PASS testing "{{wron,g}}" (length 2)
+PASS testing "{{quine}}" (length 1)
+PASS testing "{{bogusPartial}}" (length 1)
+PASS testing "{{bogusPartial}}}" (length 1)
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.any.serviceworker-expected.txt
new file mode 100644
index 0000000..907e239
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.any.serviceworker-expected.txt
@@ -0,0 +1,4 @@
+
+FAIL TransformStream constructor should not call setters for highWaterMark or size highWaterMark value is negative or not a number
+PASS TransformStream should use the original value of ReadableStream and WritableStream
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/patched-global.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.any.serviceworker-expected.txt
new file mode 100644
index 0000000..2a4ee86
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.any.serviceworker-expected.txt
@@ -0,0 +1,8 @@
+
+PASS transformer method start should be called with the right number of arguments
+PASS transformer method start should be called even when it's located on the prototype chain
+PASS transformer method transform should be called with the right number of arguments
+PASS transformer method transform should be called even when it's located on the prototype chain
+PASS transformer method flush should be called with the right number of arguments
+PASS transformer method flush should be called even when it's located on the prototype chain
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/properties.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.any.serviceworker-expected.txt
new file mode 100644
index 0000000..6900196
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.any.serviceworker-expected.txt
@@ -0,0 +1,13 @@
+
+PASS enqueue() inside size() should work
+PASS terminate() inside size() should work
+PASS error() inside size() should work
+PASS desiredSize inside size() should work
+PASS readable cancel() inside size() should work
+PASS pipeTo() inside size() should work
+PASS read() inside of size() should work
+PASS writer.write() inside size() should work
+PASS synchronous writer.write() inside size() should work
+PASS writer.close() inside size() should work
+PASS writer.abort() inside size() should work
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.any.serviceworker-expected.txt
new file mode 100644
index 0000000..d7a2449
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.any.serviceworker-expected.txt
@@ -0,0 +1,12 @@
+
+PASS writableStrategy highWaterMark should work
+PASS readableStrategy highWaterMark should work
+PASS writable should have the correct size() function
+PASS default writable strategy should be equivalent to { highWaterMark: 1 }
+PASS default readable strategy should be equivalent to { highWaterMark: 0 }
+PASS a RangeError should be thrown for an invalid highWaterMark
+PASS writableStrategy highWaterMark should be converted to a number
+PASS readableStrategy highWaterMark should be converted to a number
+PASS a bad readableStrategy size function should cause writer.write() to reject on an identity transform
+PASS a bad readableStrategy size function should error the stream on enqueue even when transformer.transform() catches the exception
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/strategies.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.any.serviceworker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.any.serviceworker-expected.txt
new file mode 100644
index 0000000..f8c23cc
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.any.serviceworker-expected.txt
@@ -0,0 +1,10 @@
+
+Harness Error (FAIL), message = Unhandled rejection: the stream has been terminated
+
+PASS controller.terminate() should error pipeTo()
+PASS controller.terminate() should prevent remaining chunks from being processed
+PASS controller.enqueue() should throw after controller.terminate()
+PASS controller.error() after controller.terminate() with queued chunk should error the readable
+PASS controller.error() after controller.terminate() without queued chunk should do nothing
+PASS controller.terminate() inside flush() should not prevent writer.close() from succeeding
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.any.serviceworker.html b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.any.serviceworker.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/streams/transform-streams/terminate.any.serviceworker.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/platform/mac-wk1/TestExpectations b/LayoutTests/platform/mac-wk1/TestExpectations
index 87e4000..7d36901 100644
--- a/LayoutTests/platform/mac-wk1/TestExpectations
+++ b/LayoutTests/platform/mac-wk1/TestExpectations
@@ -408,6 +408,50 @@
 http/wpt/webrtc/transfer-datachannel-service-worker.https.html [ Skip ]
 imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-strict_dynamic_worker.https.html [ Skip ]
 imported/w3c/web-platform-tests/notifications/idlharness.https.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/idlharness.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/abort.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/close-propagation-backward.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/close-propagation-forward.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/error-propagation-backward.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/error-propagation-forward.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/flow-control.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/general.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/multiple-propagation.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/pipe-through.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/then-interception.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/throwing-options.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/piping/transform-streams.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/queuing-strategies.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-byte-streams/bad-buffers-and-views.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-byte-streams/construct-byob-request.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-byte-streams/general.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-byte-streams/non-transferable-buffers.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-byte-streams/respond-after-enqueue.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-byte-streams/tee.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/async-iterator.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/cancel.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/constructor.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/default-reader.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/floating-point-total-queue-size.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/general.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/patched-global.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/reentrant-strategies.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/tee.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/readable-streams/templated.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/backpressure.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/errors.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/flush.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/general.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/lipfuzz.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/patched-global.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/properties.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/reentrant-strategies.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/strategies.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/streams/transform-streams/terminate.any.serviceworker.html [ Skip ]
 
 # No Cross-Origin-Opener-Policy / Cross-Origin-Embedder-Policy in WK1.
 imported/w3c/web-platform-tests/html/cross-origin-embedder-policy [ Skip ]