Index: third_party/WebKit/LayoutTests/media/media-play-promise.html |
diff --git a/third_party/WebKit/LayoutTests/media/media-play-promise.html b/third_party/WebKit/LayoutTests/media/media-play-promise.html |
index 992b0b0654d02553de8649af8a9331bdb229922a..317a4c027fd2630db8696fc2c48fd434c680722f 100644 |
--- a/third_party/WebKit/LayoutTests/media/media-play-promise.html |
+++ b/third_party/WebKit/LayoutTests/media/media-play-promise.html |
@@ -1,441 +1,281 @@ |
-<html> |
-<head> |
-<script src=media-file.js></script> |
-<!-- TODO(mlamouri): use testharness.js, see https://crbug.com/588956 --> |
-<script src=video-test.js></script> |
- |
+<!DOCTYPE html> |
+<title>Test the play() behaviour with regards to the returned promise for media elements.</title> |
+<script src="../resources/testharness.js"></script> |
+<script src="../resources/testharnessreport.js"></script> |
+<script src="media-file.js"></script> |
<script> |
- // This is testing the behavior of play() with regards to the returned |
- // promise. This test file is creating a small framework in order to be able |
- // to test different cases easily and independently of each other. |
- // |
- // All tests have to be part of the TESTS array. When the page is loaded, |
- // first function in the array is run. A test is considered done when the |
- // promise returned by mediaElement.play() is resolved or rejected. Each |
- // test then needs to call play() once which wraps this logic. When a test |
- // is finished, the next test in the array is run until the entire array |
- // was processed. |
- // |
- // Each test should start by printing its name in order to facilitate reading |
- // the output. |
- |
- function runNextTestOrFinish() |
- { |
- currentTest++; |
- if (currentTest >= TESTS.length) { |
- endTest(); |
- return; |
- } |
- |
- consoleWrite(""); |
- TESTS[currentTest](); |
- } |
- |
- function play() |
- { |
- consoleWrite("play()"); |
- mediaElement.play().then(function() { |
- consoleWrite("arguments.length: " + arguments.length); |
- consoleWrite("Promise resolved with " + arguments[0]); |
- }, function(e) { |
- consoleWrite("arguments.length: " + arguments.length); |
- consoleWrite("Promise failed with " + e.name + ": " + e.message); |
- }).then(runNextTestOrFinish); |
- } |
- |
- function playWithUserGesture() |
- { |
- var target = document.querySelector("p"); |
- target.onclick = function() { |
- play(); |
- target.onclick = null; |
- }; |
- |
- var boundingRect = target.getBoundingClientRect(); |
- var x = boundingRect.left + (boundingRect.width / 2); |
- var y = boundingRect.top + (boundingRect.height / 2); |
- |
- // Assuming running in Blink LayoutTests. |
- eventSender.mouseMoveTo(x, y); |
- eventSender.mouseDown(); |
- eventSender.mouseUp(); |
- } |
- |
- var currentTest = -1; |
- |
- var TESTS = [ |
- // Test that play() on an element that doesn't have enough data will |
- // return a promise that resolves successfully. |
- function playBeforeCanPlay() |
- { |
- consoleWrite("playBeforeCanPlay()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('loadedmetadata'); |
- waitForEvent('loadeddata'); |
- waitForEvent('canplay'); |
- waitForEvent('playing'); |
- |
- testExpected("mediaElement.readyState", HTMLMediaElement.HAVE_NOTHING); |
- play(); |
- }, |
- |
- // Test that play() on an element that has enough data will return a |
- // promise that resolves successfully. |
- function playWhenCanPlay() |
- { |
- consoleWrite("playWhenCanPlay()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing'); |
- |
- waitForEvent('canplay', function() { |
- testExpected("mediaElement.readyState", HTMLMediaElement.HAVE_FUTURE_DATA, ">="); |
- testExpected("mediaElement.paused", true); |
- |
- play(); |
- }); |
- }, |
- |
- // Test that play() on an element that is already playing returns a |
- // promise that resolves successfully. |
- function playAfterPlaybackStarted() |
- { |
- consoleWrite("playAfterPlaybackStarted()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- mediaElement.preload = "auto"; |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing', function() { |
- testExpected("mediaElement.readyState", HTMLMediaElement.HAVE_ENOUGH_DATA); |
- testExpected("mediaElement.paused", false); |
- |
- play(); |
- }); |
- |
- waitForEvent('canplaythrough', function() { |
- run("mediaElement.play()"); |
- }); |
- }, |
- |
- // Test that play() on an element when media playback requires a gesture |
- // returns a resolved promise if there is a user gesture. |
- function playRequiresUserGestureAndHasIt() |
- { |
- consoleWrite("playRequiresUserGestureAndHasIt()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(true); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing'); |
- playWithUserGesture(); |
- }, |
- |
- // Test that play() on an element when media playback requires a gesture |
- // returns a rejected promise if there is no user gesture. |
- function playRequiresUserGestureAndDoesNotHaveIt() |
- { |
- consoleWrite("playRequiresUserGestureAndDoesNotHaveIt()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(true); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing'); |
- play(); |
- }, |
- |
- // Test that play() on an element with an unsupported content will |
- // return a rejected promise. |
- function playNotSupportedContent() |
- { |
- consoleWrite("playNotSupportedContent()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "data:,"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing'); |
- waitForEvent('error', function() { |
- testExpected("mediaElement.error", "[object MediaError]"); |
- testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); |
- }); |
- play(); |
- }, |
- |
- // Test that play() returns a resolved promise if called after the |
- // element suffered from a decode error. |
- // This test doesn't test a spec behaviour but tests that the Blink |
- // implementation properly changed after the spec changed. |
- function playDecodeError() |
- { |
- consoleWrite("playDecodeError()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing'); |
- waitForEvent('error', function() { |
- testExpected("mediaElement.error", "[object MediaError]"); |
- testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_DECODE); |
- }); |
- |
- // The setMediaElementNetworkState() method requires metadata to be |
- // available. |
- waitForEvent('loadedmetadata', function() { |
- internals.setMediaElementNetworkState(mediaElement, 6 /* NetworkStateDecodeError */); |
- play(); |
+// This is testing the behavior of play() with regards to the returned |
+// promise. This test file is creating a small framework in order to be able |
+// to test different cases easily and independently of each other. |
+// All tests have to be part of the tests and testsWithUserGesture arrays. |
+// Each test returns a promise for audio.play() which is either resolved or rejected. |
+ |
+var tests = [ |
+ // Test that play() on an element that doesn't have enough data will |
+ // return a promise that resolves successfully. |
+ function playBeforeCanPlay(t, audio) { |
+ audio.src = findMediaFile("audio", "content/test"); |
+ assert_equals(audio.readyState, HTMLMediaElement.HAVE_NOTHING); |
+ playExpectingResolvedPromise(t, audio); |
+ }, |
+ |
+ // Test that play() on an element that has enough data will return a |
+ // promise that resolves successfully. |
+ function playWhenCanPlay(t, audio) { |
+ audio.src = findMediaFile("audio", "content/test"); |
+ |
+ audio.oncanplay = t.step_func(function() { |
+ assert_greater_than_equal(audio.readyState, HTMLMediaElement.HAVE_FUTURE_DATA); |
+ assert_true(audio.paused); |
+ playExpectingResolvedPromise(t, audio); |
+ }); |
+ }, |
+ |
+ // Test that play() on an element that is already playing returns a |
+ // promise that resolves successfully. |
+ function playAfterPlaybackStarted(t, audio) { |
+ audio.preload = "auto"; |
+ audio.src = findMediaFile("audio", "content/test"); |
+ |
+ audio.onplaying = t.step_func(function() { |
+ assert_equals(audio.readyState, HTMLMediaElement.HAVE_ENOUGH_DATA); |
+ assert_false(audio.paused); |
+ playExpectingResolvedPromise(t, audio); |
+ }); |
+ |
+ audio.oncanplaythrough = t.step_func(function() { |
+ audio.play(); |
+ }); |
+ }, |
+ |
+ // Test that play() on an element with an unsupported content will |
+ // return a rejected promise. |
+ function playNotSupportedContent(t, audio) { |
+ audio.src = findMediaFile("audio", "data:,"); |
+ |
+ audio.onerror = t.step_func(function() { |
+ assert_true(audio.error instanceof MediaError); |
+ assert_equals(audio.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); |
+ }); |
+ playExpectingRejectedPromise(t, audio, "NotSupportedError"); |
+ }, |
+ |
+ // Test that play() returns a resolved promise if called after the |
+ // element suffered from a decode error. |
+ // This test doesn't test a spec behaviour but tests that the Blink |
+ // implementation properly changed after the spec changed. |
+ function playDecodeError(t, audio) { |
+ audio.src = findMediaFile("audio", "content/test"); |
+ |
+ audio.onerror = t.step_func(function() { |
+ assert_true(audio.error instanceof MediaError); |
+ assert_equals(audio.error.code, MediaError.MEDIA_ERR_DECODE); |
+ }); |
+ |
+ // The setMediaElementNetworkState() method requires metadata to be available. |
+ audio.onloadedmetadata = t.step_func(function() { |
+ internals.setMediaElementNetworkState(audio, 6); // NetworkStateDecodeError. |
+ playExpectingResolvedPromise(t, audio); |
+ }); |
+ }, |
+ |
+ // Test that play() returns a resolved promise if called after the |
+ // element suffered from a network error. |
+ // This test doesn't test a spec behaviour but tests that the Blink |
+ // implementation properly changed after the spec changed |
+ function playNetworkError(t, audio) { |
+ audio.src = findMediaFile("audio", "content/test"); |
+ |
+ audio.onerror = t.step_func(function() { |
+ assert_true(audio.error instanceof MediaError); |
+ assert_equals(audio.error.code, MediaError.MEDIA_ERR_NETWORK); |
+ }); |
+ |
+ // The setMediaElementNetworkState() method requires metadata to be available. |
+ audio.onloadedmetadata = t.step_func(function() { |
+ internals.setMediaElementNetworkState(audio, 5); // NetworkStateNetworkError. |
+ playExpectingResolvedPromise(t, audio); |
+ }); |
+ }, |
+ |
+ // Test that play() returns a rejected promise if the element is |
+ // sufferring from a not supported error. |
+ function playWithErrorAlreadySet(t, audio) { |
+ audio.src = findMediaFile("audio", "data:,"); |
+ |
+ audio.onerror = t.step_func(function() { |
+ assert_true(audio.error instanceof MediaError); |
+ assert_equals(audio.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); |
+ playExpectingRejectedPromise(t, audio, "NotSupportedError"); |
+ }); |
+ }, |
+ |
+ // Test that play() returns a resolved promise if the element had its |
+ // source changed after suffering from an error. |
+ function playSrcChangedAfterError(t, audio) { |
+ audio.src = findMediaFile("audio", "data:,"); |
+ |
+ audio.onerror = t.step_func(function() { |
+ assert_true(audio.error instanceof MediaError); |
+ assert_equals(audio.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); |
+ audio.src = findMediaFile("audio", "content/test"); |
+ |
+ audio.onloadedmetadata = t.step_func(function() { |
+ playExpectingResolvedPromise(t, audio); |
}); |
- }, |
- |
- // Test that play() returns a resolved promise if called after the |
- // element suffered from a network error. |
- // This test doesn't test a spec behaviour but tests that the Blink |
- // implementation properly changed after the spec changed |
- function playNetworkError() |
- { |
- consoleWrite("playNetworkError()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing'); |
- waitForEvent('error', function() { |
- testExpected("mediaElement.error", "[object MediaError]"); |
- testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_NETWORK); |
- }); |
- |
- // The setMediaElementNetworkState() method requires metadata to be |
- // available. |
- waitForEvent('loadedmetadata', function() { |
- internals.setMediaElementNetworkState(mediaElement, 5 /* NetworkStateNetworkError */); |
- play(); |
- }); |
- }, |
- |
- // Test that play() returns a rejected promise if the element is |
- // suferring from a not supported error. |
- function playWithErrorAlreadySet() |
- { |
- consoleWrite("playWithErrorAlreadySet()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "data:,"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing'); |
- waitForEvent('error', function() { |
- testExpected("mediaElement.error", "[object MediaError]"); |
- testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); |
- play(); |
- }); |
- }, |
- |
- // Test that play() returns a resolved promise if the element had its |
- // source changed after suffering from an error. |
- function playSrcChangedAfterError() |
- { |
- consoleWrite("playSrcChangedAfterError()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "data:,"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('error', function() { |
- testExpected("mediaElement.error", "[object MediaError]"); |
- testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); |
- |
- mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing'); |
- waitForEvent('loadedmetadata', function() { |
- play(); |
- }); |
- }); |
- }, |
- |
- // Test that play() returns a rejected promise if the element had an |
- // error and just changed its source. |
- function playRaceWithSrcChangeError() |
- { |
- consoleWrite("playRaceWithSrcChangeError()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "data:,"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('error', function() { |
- testExpected("mediaElement.error", "[object MediaError]"); |
- testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); |
- |
- mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- testExpected("mediaElement.error", null); |
- testExpected("mediaElement.readyState", HTMLMediaElement.HAVE_NOTHING); |
- |
- waitForEvent('playing'); |
- play(); |
- }); |
- }, |
- |
- // Test that play() returns a resolved promise when calling play() then |
- // pause() on an element that already has enough data to play. In other |
- // words, pause() doesn't cancel play() because it was resolved |
- // immediately. |
- function playAndPauseWhenCanPlay() |
- { |
- consoleWrite("playAndPauseWhenCanPlay()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('canplaythrough', function() { |
- waitForEvent('playing'); |
- testExpected("mediaElement.readyState", HTMLMediaElement.HAVE_ENOUGH_DATA); |
- play(); |
- testExpected("mediaElement.paused", false); |
- mediaElement.pause(); |
- testExpected("mediaElement.paused", true); |
- }); |
- }, |
- |
- // Test that play() returns a rejected promise when calling play() then |
- // pause() on an element that doesn't have enough data to play. In other |
- // words, pause() cancels play() before it can be resolved. |
- function playAndPauseBeforeCanPlay() |
- { |
- consoleWrite("playAndPauseBeforeCanPlay()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- |
- waitForEvent('playing'); |
- testExpected("mediaElement.readyState", HTMLMediaElement.HAVE_NOTHING); |
- play(); |
- testExpected("mediaElement.paused", false); |
- mediaElement.pause(); |
- testExpected("mediaElement.paused", true); |
- }, |
- |
- // Test that load() rejects all the pending play() promises. |
- // This might be tested by other tests in this file but it is present in |
- // order to be explicit. |
- function loadRejectsPendingPromises() |
- { |
- consoleWrite("loadRejectsPendingPromises()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- |
- play(); // the promise will be left pending. |
- |
- waitForEvent('playing'); |
- run("mediaElement.load()"); |
- }, |
- |
- // Test that changing the src rejects the pending play() promises. |
- function newSrcRejectPendingPromises() |
- { |
- consoleWrite("newSrcRejectPendingPromises()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- |
- play(); // the promise will be left pending. |
- |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- }, |
- |
- // Test ordering of events and promises. |
- // This is testing a bug in Blink, see https://crbug.com/587871 |
- function testEventAndPromiseOrdering() |
- { |
- consoleWrite("testEventAndPromiseOrdering"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- run("mediaElement.src = 'data:,'"); |
- |
- waitForEvent('error', function() { |
- // Until https://crbug.com/587871 is fixed, the events will be |
- // [ volumechange, volumechange, promise ], it should be |
- // [ volumechange, promise, volumechange ]. |
- waitForEvent('volumechange'); |
- run("mediaElement.volume = 0.1"); |
- play(); |
- run("mediaElement.volume = 0.2"); |
- }); |
- |
- }, |
- |
- // Test that calling pause() then play() on an element that is already |
- // playing returns a promise that resolves successfully. |
- function pausePlayAfterPlaybackStarted() |
- { |
- consoleWrite("pausePlayAfterPlaybackStarted()"); |
- internals.settings.setMediaPlaybackRequiresUserGesture(false); |
- |
- run("mediaElement = document.createElement('audio')"); |
- mediaElement.preload = "auto"; |
- var mediaFile = findMediaFile("audio", "content/test"); |
- run("mediaElement.src = '" + mediaFile + "'"); |
- |
- waitForEvent('playing', function() { |
- testExpected("mediaElement.readyState", HTMLMediaElement.HAVE_ENOUGH_DATA); |
- testExpected("mediaElement.paused", false); |
- |
- run("mediaElement.pause()"); |
- play(); |
- }); |
- |
- waitForEvent('canplaythrough', function() { |
- run("mediaElement.play()"); |
- }); |
- }, |
- ]; |
- |
- function start() |
- { |
- if (!('eventSender' in window) || !('internals' in window)) { |
- failTest("Not running in LayoutTests."); |
- return; |
- } |
- runNextTestOrFinish(); |
+ }); |
+ }, |
+ |
+ // Test that play() returns a rejected promise if the element had an |
+ // error and just changed its source. |
+ function playRaceWithSrcChangeError(t, audio) { |
+ audio.src = findMediaFile("audio", "data:,"); |
+ |
+ audio.onerror = t.step_func(function() { |
+ assert_true(audio.error instanceof MediaError); |
+ assert_equals(audio.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED); |
+ audio.src = findMediaFile("audio", "content/test"); |
+ assert_equals(audio.error, null); |
+ assert_equals(audio.readyState, HTMLMediaElement.HAVE_NOTHING); |
+ playExpectingResolvedPromise(t, audio); |
+ }); |
+ }, |
+ |
+ // Test that play() returns a resolved promise when calling play() then |
+ // pause() on an element that already has enough data to play. In other |
+ // words, pause() doesn't cancel play() because it was resolved |
+ // immediately. |
+ function playAndPauseWhenCanplay(t, audio) { |
+ audio.src = findMediaFile("audio", "content/test"); |
+ |
+ audio.oncanplaythrough = t.step_func(function() { |
+ assert_equals(audio.readyState, HTMLMediaElement.HAVE_ENOUGH_DATA); |
+ playExpectingResolvedPromise(t, audio); |
+ assert_false(audio.paused); |
+ audio.pause(); |
+ assert_true(audio.paused); |
+ }); |
+ }, |
+ |
+ // Test that play() returns a rejected promise when calling play() then |
+ // pause() on an element that doesn't have enough data to play. In other |
+ // words, pause() cancels play() before it can be resolved. |
+ function playAndPauseBeforeCanPlay(t, audio) { |
+ assert_equals(audio.readyState, HTMLMediaElement.HAVE_NOTHING); |
+ playExpectingRejectedPromise(t, audio, "AbortError"); |
+ assert_false(audio.paused); |
+ audio.pause(); |
+ assert_true(audio.paused); |
+ }, |
+ |
+ // Test that load() rejects all the pending play() promises. |
+ // This might be tested by other tests in this file but it is present in |
+ // order to be explicit. |
+ function loadRejectsPendingPromises(t, audio) { |
+ playExpectingRejectedPromise(t, audio, "AbortError"); // the promise will be left pending. |
+ audio.load(); |
+ }, |
+ |
+ // Test that changing the src rejects the pending play() promises. |
+ function newSrcRejectPendingPromises(t, audio) { |
+ playExpectingRejectedPromise(t, audio, "AbortError"); // the promise will be left pending. |
+ audio.src = findMediaFile("audio", "content/test"); |
+ }, |
+ |
+ // Test ordering of events and promises. |
+ // This is testing a bug in Blink, see https://crbug.com/587871 |
+ function testEventAndPromiseOrdering(t, audio) { |
+ audio.src = findMediaFile("audio", "data:,"); |
+ |
+ audio.onerror = t.step_func(function() { |
+ // Until https://crbug.com/587871 is fixed, the events will be |
+ // [ promise, volumechange, volumechange ], it should be |
+ // [ volumechange, promise, volumechange ]. Right now test finishes |
+ // as soon as promise is rejected, before "volumechange" is fired. |
+ var numVolumeChangeEvents = 0; |
+ audio.onvolumechange = t.step_func(function() { ++numVolumeChangeEvents; }); |
+ audio.volume = 0.1; |
+ audio.play().then(t.unreached_func(), t.step_func_done(function() { |
+ assert_equals(arguments.length, 1); |
+ assert_equals(arguments[0].name, "NotSupportedError"); |
+ assert_equals(numVolumeChangeEvents, 0); |
+ })); |
+ audio.volume = 0.2; |
+ }); |
+ }, |
+ |
+ // Test that calling pause() then play() on an element that is already |
+ // playing returns a promise that resolves successfully. |
+ function pausePlayAfterPlaybackStarted(t, audio) { |
+ audio.preload = "auto"; |
+ audio.src = findMediaFile("audio", "content/test"); |
+ |
+ audio.onplaying = t.step_func(function() { |
+ assert_equals(audio.readyState, HTMLMediaElement.HAVE_ENOUGH_DATA); |
+ assert_false(audio.paused); |
+ audio.pause(); |
+ playExpectingResolvedPromise(t, audio); |
+ }); |
+ |
+ audio.oncanplaythrough = t.step_func(function() { |
+ audio.play(); |
+ }); |
} |
- |
-</script> |
-</head> |
- |
-<body onload="start()"> |
- |
-<p>Test the play() behaviour with regards to the returned promise for media elements.</p> |
- |
-</body> |
-</html> |
+]; |
+ |
+tests.forEach(function(test) { |
+ internals.settings.setMediaPlaybackRequiresUserGesture(false); |
+ async_test(function(t) { |
+ var audio = document.createElement("audio"); |
+ test(t, audio); |
+ }, test.name); |
+}); |
+ |
+var testsWithUserGesture = [ |
+ // Test that play() on an element when media playback requires a gesture |
+ // returns a resolved promise if there is a user gesture. |
+ function playRequiresUserGestureAndHasIt(t, audio) { |
+ audio.src = findMediaFile("audio", "content/test"); |
+ playWithUserGesture(t, audio); |
+ }, |
+ |
+ // Test that play() on an element when media playback requires a gesture |
+ // returns a rejected promise if there is no user gesture. |
+ function playRequiresUserGestureAndDoesNotHaveIt(t, audio) { |
+ audio.src = findMediaFile("audio", "content/test"); |
+ playExpectingRejectedPromise(t, audio, "NotAllowedError"); |
+ } |
+]; |
+ |
+testsWithUserGesture.forEach(function(test) { |
+ internals.settings.setMediaPlaybackRequiresUserGesture(true); |
+ async_test(function(t) { |
+ var audio = document.createElement("audio"); |
+ test(t, audio); |
+ }, test.name); |
+}); |
+ |
+function playExpectingResolvedPromise(t, audio) { |
+ audio.play().then(t.step_func_done(function() { |
+ assert_equals(arguments.length, 1); |
+ assert_equals(arguments[0], undefined); |
+ }), t.unreached_func()); |
+} |
+ |
+function playExpectingRejectedPromise(t, audio, error) { |
+ audio.play().then(t.unreached_func(), t.step_func_done(function() { |
+ assert_equals(arguments.length, 1); |
+ assert_equals(arguments[0].name, error); |
+ })); |
+} |
+ |
+function playWithUserGesture(t, audio) { |
+ document.onclick = function() { |
+ playExpectingResolvedPromise(t, audio); |
+ document.onclick = null; |
+ }; |
+ |
+ eventSender.mouseDown(); |
+ eventSender.mouseUp(); |
+} |
+</script> |