summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/remote-playback
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/remote-playback
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/remote-playback')
-rw-r--r--testing/web-platform/tests/remote-playback/META.yml4
-rw-r--r--testing/web-platform/tests/remote-playback/README.md20
-rw-r--r--testing/web-platform/tests/remote-playback/cancel-watch-availability.html63
-rw-r--r--testing/web-platform/tests/remote-playback/disable-remote-playback-cancel-watch-availability-throws.html33
-rw-r--r--testing/web-platform/tests/remote-playback/disable-remote-playback-prompt-throws.html18
-rw-r--r--testing/web-platform/tests/remote-playback/disable-remote-playback-watch-availability-throws.html22
-rw-r--r--testing/web-platform/tests/remote-playback/event-handlers-manual.html58
-rw-r--r--testing/web-platform/tests/remote-playback/idlharness.window.js29
-rw-r--r--testing/web-platform/tests/remote-playback/prepare-device.js10
-rw-r--r--testing/web-platform/tests/remote-playback/prompt-and-cancel-selection-manual.html37
-rw-r--r--testing/web-platform/tests/remote-playback/prompt-and-select-device-manual.html38
-rw-r--r--testing/web-platform/tests/remote-playback/prompt-and-watch-availability-no-device-manual.html50
-rw-r--r--testing/web-platform/tests/remote-playback/prompt-and-watch-availability-with-device-manual.html56
-rw-r--r--testing/web-platform/tests/remote-playback/prompt-in-detached-iframe.html17
-rw-r--r--testing/web-platform/tests/remote-playback/remote-video-control-pausing-manual.html72
-rw-r--r--testing/web-platform/tests/remote-playback/remote-video-control-seek-manual.html78
-rw-r--r--testing/web-platform/tests/remote-playback/remote-video-playback-manual.html61
-rw-r--r--testing/web-platform/tests/remote-playback/state-attribute-changes-when-selecting-device-manual.html53
-rw-r--r--testing/web-platform/tests/remote-playback/styles.css3
-rw-r--r--testing/web-platform/tests/remote-playback/watch-availability-callback-parameter.html30
-rw-r--r--testing/web-platform/tests/remote-playback/watch-availability-initial-callback.html26
-rw-r--r--testing/web-platform/tests/remote-playback/watch-availability-promise-return-callback-id.html24
22 files changed, 802 insertions, 0 deletions
diff --git a/testing/web-platform/tests/remote-playback/META.yml b/testing/web-platform/tests/remote-playback/META.yml
new file mode 100644
index 0000000000..a234398b8b
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/META.yml
@@ -0,0 +1,4 @@
+spec: https://w3c.github.io/remote-playback/
+suggested_reviewers:
+ - mfoltzgoogle
+ - louaybassbouss
diff --git a/testing/web-platform/tests/remote-playback/README.md b/testing/web-platform/tests/remote-playback/README.md
new file mode 100644
index 0000000000..da9bbc387f
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/README.md
@@ -0,0 +1,20 @@
+# Remote Playback API specification Tests
+
+The Remote Playback API can be found here:
+
+GitHub repository: https://github.com/w3c/remote-playback/
+
+File an issue: https://github.com/w3c/remote-playback/issues/new
+
+## Hardware/network dependency
+
+The Remote Playback API requires communication with a device over the network.
+Tests that end in `-manual.html` require a compatible device available on the
+local area network to run the tests; these tests must be run manually.
+
+Known browser/device combinations that can be used to run manual tests:
+
+| Browser | Device |
+| ------- | ------ |
+| Chrome for Android | [Chromecast](https://store.google.com/product/chromecast_google_tv?pli=1&hl=en-US) |
+| Safari | Apple TV |
diff --git a/testing/web-platform/tests/remote-playback/cancel-watch-availability.html b/testing/web-platform/tests/remote-playback/cancel-watch-availability.html
new file mode 100644
index 0000000000..41cad7c272
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/cancel-watch-availability.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+ <title>Tests cancelWatchAvailability()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ async_test(t => {
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ v.remote
+ .watchAvailability(() => {})
+ .then(
+ t.step_func(id => {
+ v.remote.cancelWatchAvailability(id).then(
+ t.step_func(() => {
+ v.remote.cancelWatchAvailability(id).then(
+ t.unreached_func(),
+ t.step_func_done(e => {
+ assert_equals(e.name, "NotFoundError");
+ })
+ );
+ }),
+ t.unreached_func()
+ );
+ }),
+ t.unreached_func()
+ );
+ }, "Test that calling cancelWatchAvailability() with an id does remove the callback, and calling cancelWatchAvailability with a removed id throws NotFoundError.");
+
+ async_test(t => {
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ Promise.all([
+ v.remote.watchAvailability(() => {}),
+ v.remote.watchAvailability(() => {}),
+ ]).then(
+ t.step_func(ids =>
+ v.remote.cancelWatchAvailability().then(
+ t.step_func(() =>
+ v.remote.cancelWatchAvailability(ids[0]).then(
+ t.unreached_func(),
+ t.step_func(e => {
+ assert_equals(e.name, "NotFoundError");
+ v.remote.cancelWatchAvailability(ids[1]).then(
+ t.unreached_func(),
+ t.step_func_done(e =>
+ assert_equals(e.name, "NotFoundError")
+ )
+ );
+ })
+ )
+ ),
+ t.unreached_func()
+ )
+ ),
+ t.unreached_func()
+ );
+ }, "Test that calling cancelWatchAvailability() without an id removes all the callbacks, and calling cancelWatchAvailability() with a removed id throws NotFoundError.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/disable-remote-playback-cancel-watch-availability-throws.html b/testing/web-platform/tests/remote-playback/disable-remote-playback-cancel-watch-availability-throws.html
new file mode 100644
index 0000000000..7b93f8e3af
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/disable-remote-playback-cancel-watch-availability-throws.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that calling cancelWatchAvailability() when disableRemotePlayback attribute is set throws InvalidStateError
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ async_test(t => {
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ v.remote
+ .watchAvailability(() => {})
+ .then(id => {
+ v.disableRemotePlayback = true;
+ v.remote.cancelWatchAvailability(id).then(
+ t.unreached_func(),
+ t.step_func(e => {
+ assert_equals(e.name, "InvalidStateError");
+ v.remote.cancelWatchAvailability().then(
+ t.unreached_func(),
+ t.step_func_done(e => {
+ assert_equals(e.name, "InvalidStateError");
+ })
+ );
+ })
+ );
+ }, t.unreached_func());
+ }, "Test that calling cancelWatchAvailability() when disableRemotePlayback attribute is set throws InvalidStateError.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/disable-remote-playback-prompt-throws.html b/testing/web-platform/tests/remote-playback/disable-remote-playback-prompt-throws.html
new file mode 100644
index 0000000000..b47e30eeba
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/disable-remote-playback-prompt-throws.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that calling prompt() when disableRemotePlayback attribute is set throws an exception
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ promise_test(t => {
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+ v.disableRemotePlayback = true;
+
+ return promise_rejects_dom(t, "InvalidStateError", v.remote.prompt());
+ }, "Test that calling prompt() when disableRemotePlayback attribute is set throws an exception.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/disable-remote-playback-watch-availability-throws.html b/testing/web-platform/tests/remote-playback/disable-remote-playback-watch-availability-throws.html
new file mode 100644
index 0000000000..7496b86fcd
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/disable-remote-playback-watch-availability-throws.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that calling watchAvailability() when disableRemotePlayback attribute is set throws an exception
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ promise_test(t => {
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+ v.disableRemotePlayback = true;
+
+ return promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ v.remote.watchAvailability(() => {})
+ );
+ }, "Test that calling watchAvailability() when disableRemotePlayback attribute is set throws an exception.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/event-handlers-manual.html b/testing/web-platform/tests/remote-playback/event-handlers-manual.html
new file mode 100644
index 0000000000..49252ec738
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/event-handlers-manual.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that all event handlers are called when a remote playback device is connected
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ setup({ explicit_timeout: true });
+ </script>
+ <body>
+ <div id="prep">
+ <p>Please make sure a device for remote playback is <b>available.</b></p>
+ <button id="prompt-button-prep">Show devices</button>
+ <button id="start-button">Start test</button>
+ </div>
+ <div id="pick-device" style="display: none">
+ <p>
+ Click the button below to prompt for a remote playback device and select
+ one! After connecting to the device, please click again and disconnect
+ from device.
+ </p>
+ <button id="prompt-button">Pick device</button>
+ <button id="disconnect-button" style="display: none">
+ Disconnect device
+ </button>
+ </div>
+ </body>
+ <script src="./prepare-device.js"></script>
+ <script>
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ async_test(t => {
+ let promptButton = document.getElementById("prompt-button");
+ let disconnectButton = document.getElementById("disconnect-button");
+
+ const w = new EventWatcher(t, v.remote, ['connecting', 'connect', 'disconnect']);
+ w.wait_for(['connecting', 'connect', 'disconnect']).then(t.step_func_done());
+
+ promptButton.onclick = () => {
+ promise_test(() => {
+ return v.remote.prompt().then(() => {
+ promptButton.style.display = "none";
+ disconnectButton.style.display = "inline";
+ });
+ }, "Prompt to connect to the device");
+ };
+
+ disconnectButton.onclick = () => {
+ promise_test(() => {
+ return v.remote.prompt()
+ }, "Prompt to disconnect from the device")
+ };
+ }, "Test that all event handlers are called when a remote playback device is connected.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/idlharness.window.js b/testing/web-platform/tests/remote-playback/idlharness.window.js
new file mode 100644
index 0000000000..458bfd0c60
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/idlharness.window.js
@@ -0,0 +1,29 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+// META: script=/common/media.js
+// META: timeout=long
+
+'use strict';
+
+// https://w3c.github.io/remoteplayback/
+
+idl_test(
+ ['remote-playback'],
+ ['html', 'dom'],
+ idl_array => {
+ try {
+ const media = document.createElement('video');
+ media.src = getVideoURI('/media/movie_5');
+ media.width = media.height = 10;
+ document.body.appendChild(media);
+ self.media = media;
+ } catch (e) {
+ // Will be surfaced when media is undefined below.
+ }
+
+ idl_array.add_objects({
+ HTMLVideoElement: ['media'],
+ RemotePlayback: ['media.remote']
+ });
+ }
+);
diff --git a/testing/web-platform/tests/remote-playback/prepare-device.js b/testing/web-platform/tests/remote-playback/prepare-device.js
new file mode 100644
index 0000000000..a12dbaf287
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/prepare-device.js
@@ -0,0 +1,10 @@
+document.getElementById("start-button").onclick = () => {
+ document.getElementById("prep").style.display = "none";
+ document.getElementById("pick-device").style.display = "block";
+};
+document.getElementById("prompt-button-prep").onclick = () => {
+ v.remote
+ .prompt()
+ .then(() => {})
+ .catch(() => {});
+};
diff --git a/testing/web-platform/tests/remote-playback/prompt-and-cancel-selection-manual.html b/testing/web-platform/tests/remote-playback/prompt-and-cancel-selection-manual.html
new file mode 100644
index 0000000000..89a73730ef
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/prompt-and-cancel-selection-manual.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that the Promise returned by prompt() is rejected when user cancels device selection
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ setup({ explicit_timeout: true });
+ </script>
+ <body>
+ <p>
+ Click the button below to prompt for a remote playback device and
+ <b>cancel the selection</b> of a device!
+ </p>
+ <button id="prompt-button">Pick device</button>
+ </body>
+ <script>
+ async_test(t => {
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ let button = document.getElementById("prompt-button");
+ button.onclick = t.step_func(() =>
+ v.remote
+ .prompt()
+ .then(t.unreached_func())
+ .catch(
+ t.step_func_done(error =>
+ assert_equals(error.name, "NotAllowedError")
+ )
+ )
+ );
+ }, "Test that the Promise returned by prompt() is rejected when user cancels device selection.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/prompt-and-select-device-manual.html b/testing/web-platform/tests/remote-playback/prompt-and-select-device-manual.html
new file mode 100644
index 0000000000..77973af666
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/prompt-and-select-device-manual.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <title>Test that the Promise returned by prompt() is resolved when user selects a device</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ setup({ explicit_timeout: true });
+ </script>
+ <body>
+ <div id="prep">
+ <p>Please make sure a device for remote playback is <b>available.</b></p>
+ <button id="prompt-button-prep">Show devices</button>
+ <button id="start-button">Start test</button>
+ </div>
+ <div id="pick-device" style="display: none">
+ <p>
+ Click the button below to prompt for a remote playback device and select
+ one!
+ </p>
+ <button id="prompt-button">Pick device</button>
+ </div>
+ </body>
+ <script src="./prepare-device.js"></script>
+ <script>
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ async_test(t => {
+ let button = document.getElementById("prompt-button");
+ button.onclick = t.step_func_done(() => {
+ promise_test(() => {
+ return v.remote.prompt();
+ }, "Prompt resolves");
+ });
+ }, "Test that the Promise returned by prompt() is resolved when user selects a device.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/prompt-and-watch-availability-no-device-manual.html b/testing/web-platform/tests/remote-playback/prompt-and-watch-availability-no-device-manual.html
new file mode 100644
index 0000000000..fb3e1231bd
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/prompt-and-watch-availability-no-device-manual.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that watchAvailability() runs the callback with false when there is no device for the user to select
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ setup({ explicit_timeout: true });
+ </script>
+ <body>
+ <div id="prep">
+ <p>Please make sure <b>no device is available</b> for remote playback.</p>
+ <button id="prompt-button-prep">Show devices</button>
+ <button id="start-button">Start test</button>
+ </div>
+ <div id="pick-device" style="display: none">
+ <p>
+ Click the button below to prompt for a remote playback device and
+ cancel!
+ </p>
+ <button id="prompt-button">Pick device</button>
+ </div>
+ </body>
+ <script src="./prepare-device.js"></script>
+ <script>
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ async_test(t => {
+ let deviceAvailable = false;
+ let button = document.getElementById("prompt-button");
+ button.onclick = function () {
+ v.remote
+ .watchAvailability(t.step_func(avail => (deviceAvailable = avail)))
+ .then(
+ t.step_func(() => {
+ assert_false(deviceAvailable);
+ promise_rejects_dom(t, 'NotFoundError', v.remote.prompt())
+ .then(() => {
+ t.done();
+ });
+ }),
+ t.unreached_func()
+ );
+ };
+ }, "Test that watchAvailability() runs the callback with false when there is no device for the user to select.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/prompt-and-watch-availability-with-device-manual.html b/testing/web-platform/tests/remote-playback/prompt-and-watch-availability-with-device-manual.html
new file mode 100644
index 0000000000..fa8644931b
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/prompt-and-watch-availability-with-device-manual.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that watchAvailability() runs the callback with true when user selects a device
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ setup({ explicit_timeout: true });
+ </script>
+ <body>
+ <div id="prep">
+ <p>Please make sure a device for remote playback is <b>available.</b></p>
+ <button id="prompt-button-prep">Show devices</button>
+ <button id="start-button">Start test</button>
+ </div>
+ <div id="pick-device" style="display: none">
+ <p>
+ Click the button below to prompt for a remote playback device and select
+ one!
+ </p>
+ <button id="prompt-button">Pick device</button>
+ </div>
+ </body>
+ <script src="./prepare-device.js"></script>
+ <script>
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ async_test(t => {
+ let deviceAvailable = false;
+ let button = document.getElementById("prompt-button");
+ button.onclick = () => {
+ v.remote
+ .watchAvailability(t.step_func(avail => (deviceAvailable = avail)))
+ .then(
+ t.step_func(() => {
+ v.remote
+ .prompt()
+ .then(() => {
+ assert_true(deviceAvailable);
+ t.done();
+ })
+ .catch(
+ t.unreached_func(
+ "Selecting a remote device was not successful."
+ )
+ );
+ }),
+ t.unreached_func()
+ );
+ };
+ }, "Test that watchAvailability() runs the callback with true when user selects a device.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/prompt-in-detached-iframe.html b/testing/web-platform/tests/remote-playback/prompt-in-detached-iframe.html
new file mode 100644
index 0000000000..501471755a
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/prompt-in-detached-iframe.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(t => {
+ let i = document.createElement("iframe");
+ document.body.appendChild(i);
+ let audio = document.createElement("audio");
+ i.contentDocument.body.appendChild(audio);
+ let remote = audio.remote;
+ i.remove();
+ return promise_rejects_dom(t, "InvalidAccessError", remote.prompt());
+}, 'Calling remote.prompt() in a detached context should throw InvalidAccessError');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/remote-video-control-pausing-manual.html b/testing/web-platform/tests/remote-playback/remote-video-control-pausing-manual.html
new file mode 100644
index 0000000000..8dfc19bf77
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/remote-video-control-pausing-manual.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+ <link rel="stylesheet" href="styles.css" />
+ <title>Test that pause() on the local video is reflected on the remote device</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ setup({ explicit_timeout: true });
+ </script>
+ <body>
+ <div id="pick-device">
+ <p>
+ Click the button below to prompt for a remote playback device and select
+ one!
+ </p>
+ <p>
+ <button id="prompt-button">Pick device</button>
+ </p>
+ </div>
+ <video src="/media/green-at-15.mp4" id="video"></video>
+ <div id="evaluate" style="display: none">
+ <p>
+ Did the playback on the remote device pause and show the following
+ timestamp? (can vary by some frames)
+ </p>
+ <p id="timestamp" style="font-weight: bold"></p>
+ <p>
+ <button id="yes">Yes</button>
+ </p>
+ <p>
+ <button id="no">No</button>
+ </p>
+ </div>
+ </body>
+ <script>
+ let v = document.getElementById("video");
+
+ async_test(t => {
+ let button = document.getElementById("prompt-button");
+ button.onclick = t.step_func(() => {
+ promise_test(() => {
+ return v.remote.prompt().then(() => {
+ v.play();
+ });
+ }, "Prompt resolves");
+ });
+
+ let timestampLabel = document.getElementById("timestamp");
+ v.ontimeupdate = () => {
+ let seconds = Math.floor(v.currentTime) + "";
+ let frames = Math.ceil((v.currentTime - seconds) * 30) + "";
+ timestampLabel.innerText =
+ seconds.padStart(2, "0") + ":" + frames.padStart(2, "0");
+ if (v.currentTime >= 2) {
+ v.pause();
+ document.getElementById("evaluate").style.display = "block";
+ }
+ };
+
+ let evaluate = success =>
+ assert_true(success, "Video paused and has correct play position.");
+
+ document.getElementById("yes").onclick = t.step_func_done(() =>
+ evaluate(true)
+ );
+ document.getElementById("no").onclick = t.step_func_done(() =>
+ evaluate(false)
+ );
+ }, "Test that pause() on the local video is reflected on the remote device.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/remote-video-control-seek-manual.html b/testing/web-platform/tests/remote-playback/remote-video-control-seek-manual.html
new file mode 100644
index 0000000000..56156d9871
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/remote-video-control-seek-manual.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+ <link rel="stylesheet" href="styles.css" />
+ <title>Test that seek() on the local video is reflected on the remote device</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ setup({ explicit_timeout: true });
+ </script>
+ <body>
+ <div id="pick-device">
+ <p>
+ Click the button below to prompt for a remote playback device and select
+ one!
+ </p>
+ <p>
+ Wait a few seconds for the video to initialize, play and seek.
+ </p>
+ <p>
+ <button id="prompt-button">Pick device</button>
+ </p>
+ </div>
+ <video src="/media/green-at-15.mp4" id="video"></video>
+ <div id="evaluate" style="display: none">
+ <p>
+ Did the playback on the remote device pause and show the following
+ timestamp? (can vary by some frames)
+ </p>
+ <p id="timestamp" style="font-weight: bold"></p>
+ <p>
+ <button id="yes">Yes</button>
+ </p>
+ <p>
+ <button id="no">No</button>
+ </p>
+ </div>
+ </body>
+ <script>
+ let v = document.getElementById("video");
+
+ async_test(t => {
+ let button = document.getElementById("prompt-button");
+ button.onclick = t.step_func(() => {
+ promise_test(() => {
+ return v.remote.prompt().then(() => {
+ v.play();
+ });
+ }, "Prompt resolves");
+ });
+
+ let timestampLabel = document.getElementById("timestamp");
+ v.ontimeupdate = () => {
+ let seconds = Math.floor(v.currentTime) + "";
+ let frames = Math.ceil((v.currentTime - seconds) * 30) + "";
+ timestampLabel.innerText =
+ seconds.padStart(2, "0") + ":" + frames.padStart(2, "0");
+ if (v.currentTime >= 2 && v.currentTime < 18) {
+ v.currentTime = 18;
+ }
+ if (v.currentTime >= 20) {
+ v.pause();
+ document.getElementById("evaluate").style.display = "block";
+ }
+ };
+
+ let evaluate = success =>
+ assert_true(success, "Video paused and has correct play position.");
+
+ document.getElementById("yes").onclick = t.step_func_done(() =>
+ evaluate(true)
+ );
+ document.getElementById("no").onclick = t.step_func_done(() =>
+ evaluate(false)
+ );
+ }, "Test that seek() on the local video is reflected on the remote device.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/remote-video-playback-manual.html b/testing/web-platform/tests/remote-playback/remote-video-playback-manual.html
new file mode 100644
index 0000000000..223a5b4a28
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/remote-video-playback-manual.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+ <title>Test if video is playing on remote device</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ setup({ explicit_timeout: true });
+ </script>
+ <style>
+ button {
+ padding: 2em;
+ }
+ </style>
+ <body>
+ <div id="pick-device">
+ <p>
+ Click the button below to prompt for a remote playback device and select
+ one!
+ </p>
+ <p>
+ <button id="prompt-button">Pick device</button>
+ </p>
+ </div>
+ <video src="/media/green-at-15.mp4" id="video"></video>
+ <div id="evaluate" style="display: none">
+ <p>Does the video play back on the remote device?</p>
+ <p>
+ <button id="yes">Yes</button>
+ </p>
+ <p>
+ <button id="no">No</button>
+ </p>
+ </div>
+ </body>
+ <script>
+ let v = document.getElementById("video");
+
+ async_test(t => {
+ let button = document.getElementById("prompt-button");
+ button.onclick = t.step_func(() => {
+ promise_test(() => {
+ return v.remote.prompt().then(() => {
+ v.play();
+ document.getElementById("evaluate").style.display = "block";
+ });
+ }, "Prompt resolves");
+ });
+
+ let evaluate = success =>
+ assert_true(success, "Video paused and has correct play position.");
+
+ document.getElementById("yes").onclick = t.step_func_done(() =>
+ evaluate(true)
+ );
+ document.getElementById("no").onclick = t.step_func_done(() =>
+ evaluate(false)
+ );
+ }, "Test if video is playing on remote device.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/state-attribute-changes-when-selecting-device-manual.html b/testing/web-platform/tests/remote-playback/state-attribute-changes-when-selecting-device-manual.html
new file mode 100644
index 0000000000..90f51af1d7
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/state-attribute-changes-when-selecting-device-manual.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that the remote playback state changes when selecting a device
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ setup({ explicit_timeout: true });
+ </script>
+ <body>
+ <div id="prep">
+ <p>Please make sure a device for remote playback is <b>available.</b></p>
+ <button id="prompt-button-prep">Show devices</button>
+ <button id="start-button">Start test</button>
+ </div>
+ <div id="pick-device" style="display: none">
+ <p>
+ Click the button below to prompt for a remote playback device and select
+ one!
+ </p>
+ <button id="prompt-button">Pick device</button>
+ </div>
+ </body>
+ <script src="./prepare-device.js"></script>
+ <script>
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ async_test(t => {
+ assert_equals(v.remote.state, "disconnected");
+
+ function callback(available) {
+ promise_test(() => {
+ return v.remote.prompt().then(
+ t.step_func(() => {
+ assert_equals(v.remote.state, "connecting");
+ })
+ );
+ }, "Prompt call resolves");
+ }
+
+ let button = document.getElementById("prompt-button");
+ button.onclick = () => {
+ v.remote.watchAvailability(t.step_func_done(callback)).then(
+ t.step_func(() => {}),
+ t.unreached_func()
+ );
+ };
+ }, "Test that the remote playback state changes when selecting a device.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/styles.css b/testing/web-platform/tests/remote-playback/styles.css
new file mode 100644
index 0000000000..7c3dc81148
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/styles.css
@@ -0,0 +1,3 @@
+button {
+ padding: 2em;
+}
diff --git a/testing/web-platform/tests/remote-playback/watch-availability-callback-parameter.html b/testing/web-platform/tests/remote-playback/watch-availability-callback-parameter.html
new file mode 100644
index 0000000000..fe407a9c03
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/watch-availability-callback-parameter.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that the callback is called with boolean parameter when calling
+ watchAvailability()
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ async_test(t => {
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ v.remote
+ .watchAvailability(
+ t.step_func_done(() => assert_true(typeof available === "boolean"))
+ )
+ .then(
+ t.step_func(() => {}),
+ t.unreached_func()
+ )
+ .catch(
+ t.step_func_done(error =>
+ assert_equals(error.name, "NotSupportedError")
+ )
+ );
+ }, "Test that the callback is called with boolean parameter when calling watchAvailability().");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/watch-availability-initial-callback.html b/testing/web-platform/tests/remote-playback/watch-availability-initial-callback.html
new file mode 100644
index 0000000000..b540d835b9
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/watch-availability-initial-callback.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that the callback is called after the Promise returned by watchAvailability() resolves
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ async_test(t => {
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ let promiseResolved = false;
+
+ v.remote
+ .watchAvailability(t.step_func_done(() => assert_true(promiseResolved)))
+ .then(
+ t.step_func(() => {
+ promiseResolved = true;
+ }),
+ t.unreached_func()
+ );
+ }, "Test that the callback is called after the Promise returned by watchAvailability() resolves.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/remote-playback/watch-availability-promise-return-callback-id.html b/testing/web-platform/tests/remote-playback/watch-availability-promise-return-callback-id.html
new file mode 100644
index 0000000000..c3df0b31f1
--- /dev/null
+++ b/testing/web-platform/tests/remote-playback/watch-availability-promise-return-callback-id.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <title>
+ Test that the Promise returned by watchAvailability() resolves with a numeric callback id
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ <script>
+ async_test(t => {
+ let v = document.createElement("video");
+ v.src = getVideoURI("/media/movie_5");
+
+ v.remote
+ .watchAvailability(() => {})
+ .then(
+ t.step_func_done(callbackId => {
+ assert_true(typeof callbackId === "number");
+ }),
+ t.unreached_func()
+ );
+ }, "Test that the Promise returned by watchAvailability() resolves with a numeric callback id.");
+ </script>
+</html>