diff options
Diffstat (limited to 'dom/media/mediacontrol/tests/browser/browser_stop_control_after_media_reaches_to_end.js')
-rw-r--r-- | dom/media/mediacontrol/tests/browser/browser_stop_control_after_media_reaches_to_end.js | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/dom/media/mediacontrol/tests/browser/browser_stop_control_after_media_reaches_to_end.js b/dom/media/mediacontrol/tests/browser/browser_stop_control_after_media_reaches_to_end.js new file mode 100644 index 0000000000..cc8ccf270a --- /dev/null +++ b/dom/media/mediacontrol/tests/browser/browser_stop_control_after_media_reaches_to_end.js @@ -0,0 +1,108 @@ +const PAGE_URL = + "https://example.com/browser/dom/media/mediacontrol/tests/browser/file_non_looping_media.html"; + +add_task(async function setupTestingPref() { + await SpecialPowers.pushPrefEnv({ + set: [["media.mediacontrol.stopcontrol.aftermediaends", true]], + }); +}); + +/** + * This test is used to ensure that we would stop controlling media after it + * reaches to the end when a controller doesn't have an active media session. + * If a controller has an active media session, it would keep active despite + * media reaches to the end. + */ +add_task(async function testControllerShouldStopAfterMediaReachesToTheEnd() { + info(`open media page and play media until the end`); + const tab = await createLoadedTabWrapper(PAGE_URL); + await Promise.all([ + checkIfMediaControllerBecomeInactiveAfterMediaEnds(tab), + playMediaUntilItReachesToTheEnd(tab), + ]); + + info(`remove tab`); + await tab.close(); +}); + +add_task(async function testControllerWontStopAfterMediaReachesToTheEnd() { + info(`open media page and create media session`); + const tab = await createLoadedTabWrapper(PAGE_URL); + await createMediaSession(tab); + + info(`play media until the end`); + await playMediaUntilItReachesToTheEnd(tab); + + info(`controller is still active because of having active media session`); + await checkControllerIsActive(tab); + + info(`remove tab`); + await tab.close(); +}); + +/** + * The following are helper functions. + */ +function checkIfMediaControllerBecomeInactiveAfterMediaEnds(tab) { + return new Promise(r => { + let activeChangedNums = 0; + const controller = tab.linkedBrowser.browsingContext.mediaController; + controller.onactivated = () => { + is( + ++activeChangedNums, + 1, + `Receive ${activeChangedNums} times 'onactivechange'` + ); + // We activate controller when it becomes playing, which doesn't guarantee + // it's already audible, so we won't check audible state here. + ok(controller.isActive, "controller should be active"); + ok(controller.isPlaying, "controller should be playing"); + }; + controller.ondeactivated = () => { + is( + ++activeChangedNums, + 2, + `Receive ${activeChangedNums} times 'onactivechange'` + ); + ok(!controller.isActive, "controller should be inactive"); + ok(!controller.isAudible, "controller should be inaudible"); + ok(!controller.isPlaying, "controller should be paused"); + r(); + }; + }); +} + +function playMediaUntilItReachesToTheEnd(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], async () => { + const video = content.document.getElementById("video"); + if (!video) { + ok(false, "can't get video"); + } + + if (video.readyState < video.HAVE_METADATA) { + info(`load media to get its duration`); + video.load(); + await new Promise(r => (video.loadedmetadata = r)); + } + + info(`adjust the start position to faster reach to the end`); + ok(video.duration > 1.0, "video's duration is larger than 1.0s"); + video.currentTime = video.duration - 1.0; + + info(`play ${video.id} video`); + video.play(); + await new Promise(r => (video.onended = r)); + }); +} + +function createMediaSession(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], _ => { + // simply create a media session, which would become the active media session later. + content.navigator.mediaSession; + }); +} + +function checkControllerIsActive(tab) { + const controller = tab.linkedBrowser.browsingContext.mediaController; + ok(controller.isActive, `controller is active`); +} |