diff options
Diffstat (limited to 'browser/extensions/pictureinpicture/tests')
6 files changed, 313 insertions, 0 deletions
diff --git a/browser/extensions/pictureinpicture/tests/browser/.eslintrc.js b/browser/extensions/pictureinpicture/tests/browser/.eslintrc.js new file mode 100644 index 0000000000..9bf153d21a --- /dev/null +++ b/browser/extensions/pictureinpicture/tests/browser/.eslintrc.js @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +module.exports = { + globals: { + ensureVideosReady: "readonly", + triggerPictureInPicture: "readonly", + isVideoMuted: "readonly", + isVideoPaused: "readonly", + }, +}; diff --git a/browser/extensions/pictureinpicture/tests/browser/browser.ini b/browser/extensions/pictureinpicture/tests/browser/browser.ini new file mode 100644 index 0000000000..3194c87ca5 --- /dev/null +++ b/browser/extensions/pictureinpicture/tests/browser/browser.ini @@ -0,0 +1,19 @@ +[DEFAULT] +support-files = + test-mock-wrapper.html + test-mock-wrapper.js + test-toggle-visibility.html + ../../../../../toolkit/components/pictureinpicture/tests/click-event-helper.js + ../../../../../toolkit/components/pictureinpicture/tests/head.js + ../../../../../toolkit/components/pictureinpicture/tests/test-video.mp4 + +prefs = + media.videocontrols.picture-in-picture.enabled=true + media.videocontrols.picture-in-picture.video-toggle.enabled=true + media.videocontrols.picture-in-picture.video-toggle.testing=true + media.videocontrols.picture-in-picture.video-toggle.always-show=true + media.videocontrols.picture-in-picture.video-toggle.has-used=true + media.videocontrols.picture-in-picture.video-toggle.position="right" + +[browser_mock_wrapper.js] +skip-if = !nightly_build # Bug 1751793 diff --git a/browser/extensions/pictureinpicture/tests/browser/browser_mock_wrapper.js b/browser/extensions/pictureinpicture/tests/browser/browser_mock_wrapper.js new file mode 100644 index 0000000000..6dcdd7536e --- /dev/null +++ b/browser/extensions/pictureinpicture/tests/browser/browser_mock_wrapper.js @@ -0,0 +1,205 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* import-globals-from ../../../../../toolkit/components/pictureinpicture/tests/head.js */ + +ChromeUtils.defineESModuleGetters(this, { + TOGGLE_POLICIES: "resource://gre/modules/PictureInPictureControls.sys.mjs", +}); + +const TEST_URL = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://mochitest.youtube.com:443" + ) + "test-mock-wrapper.html"; +const TEST_URL_TOGGLE_VISIBILITY = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://mochitest.youtube.com:443" + ) + "test-toggle-visibility.html"; + +/** + * Tests the mock-wrapper.js video wrapper script selects the expected element + * responsible for toggling the video player's mute status. + */ +add_task(async function test_mock_mute_button() { + await BrowserTestUtils.withNewTab(TEST_URL, async browser => { + await ensureVideosReady(browser); + + // Open the video in PiP + let videoID = "mock-video-controls"; + let pipWin = await triggerPictureInPicture(browser, videoID); + ok(pipWin, "Got Picture-in-Picture window."); + + // Mute audio + await toggleMute(browser, pipWin); + ok(await isVideoMuted(browser, videoID), "The audio is muted."); + + await SpecialPowers.spawn(browser, [], async function () { + let muteButton = content.document.querySelector(".mute-button"); + ok( + muteButton.getAttribute("isMuted"), + "muteButton has isMuted attribute." + ); + }); + + // Unmute audio + await toggleMute(browser, pipWin); + ok(!(await isVideoMuted(browser, videoID)), "The audio is playing."); + + await SpecialPowers.spawn(browser, [], async function () { + let muteButton = content.document.querySelector(".mute-button"); + ok( + !muteButton.getAttribute("isMuted"), + "muteButton does not have isMuted attribute" + ); + }); + + // Close PiP window + let pipClosed = BrowserTestUtils.domWindowClosed(pipWin); + let closeButton = pipWin.document.getElementById("close"); + EventUtils.synthesizeMouseAtCenter(closeButton, {}, pipWin); + await pipClosed; + }); +}); + +/** + * Tests the mock-wrapper.js video wrapper script selects the expected element + * responsible for toggling the video player's play/pause status. + */ +add_task(async function test_mock_play_pause_button() { + await BrowserTestUtils.withNewTab(TEST_URL, async browser => { + await ensureVideosReady(browser); + await setupVideoListeners(browser); + + // Open the video in PiP + let videoID = "mock-video-controls"; + let pipWin = await triggerPictureInPicture(browser, videoID); + ok(pipWin, "Got Picture-in-Picture window."); + + info("Test a wrapper method with a correct selector"); + // Play video + let playbackPromise = waitForVideoEvent(browser, "playing"); + let playPause = pipWin.document.getElementById("playpause"); + EventUtils.synthesizeMouseAtCenter(playPause, {}, pipWin); + await playbackPromise; + ok(!(await isVideoPaused(browser, videoID)), "The video is playing."); + + info("Test a wrapper method with an incorrect selector"); + // Pause the video. + let pausePromise = waitForVideoEvent(browser, "pause"); + EventUtils.synthesizeMouseAtCenter(playPause, {}, pipWin); + await pausePromise; + ok(await isVideoPaused(browser, videoID), "The video is paused."); + + // Close PiP window + let pipClosed = BrowserTestUtils.domWindowClosed(pipWin); + let closeButton = pipWin.document.getElementById("close"); + EventUtils.synthesizeMouseAtCenter(closeButton, {}, pipWin); + await pipClosed; + }); +}); + +/** + * Tests the mock-wrapper.js video wrapper script does not toggle mute/umute + * state when increasing/decreasing the volume using the arrow keys. + */ +add_task(async function test_volume_change_with_keyboard() { + await BrowserTestUtils.withNewTab(TEST_URL, async browser => { + await ensureVideosReady(browser); + await setupVideoListeners(browser); + + // Open the video in PiP + let videoID = "mock-video-controls"; + let pipWin = await triggerPictureInPicture(browser, videoID); + ok(pipWin, "Got Picture-in-Picture window."); + + // Initially set video to be muted + await toggleMute(browser, pipWin); + ok(await isVideoMuted(browser, videoID), "The audio is not playing."); + + // Decrease volume with arrow down + EventUtils.synthesizeKey("KEY_ArrowDown", {}, pipWin); + ok(!(await isVideoMuted(browser, videoID)), "The audio is playing."); + + // Increase volume with arrow up + EventUtils.synthesizeKey("KEY_ArrowUp", {}, pipWin); + ok(!(await isVideoMuted(browser, videoID)), "The audio is still playing."); + + await SpecialPowers.spawn(browser, [], async function () { + let video = content.document.querySelector("video"); + ok(!video.muted, "Video should be unmuted."); + }); + + // Close PiP window + let pipClosed = BrowserTestUtils.domWindowClosed(pipWin); + let closeButton = pipWin.document.getElementById("close"); + EventUtils.synthesizeMouseAtCenter(closeButton, {}, pipWin); + await pipClosed; + }); +}); + +function waitForVideoEvent(browser, eventType) { + return BrowserTestUtils.waitForContentEvent(browser, eventType, true); +} + +async function toggleMute(browser, pipWin) { + let mutedPromise = waitForVideoEvent(browser, "volumechange"); + let audioButton = pipWin.document.getElementById("audio"); + EventUtils.synthesizeMouseAtCenter(audioButton, {}, pipWin); + await mutedPromise; +} + +async function setupVideoListeners(browser) { + await SpecialPowers.spawn(browser, [], async function () { + let video = content.document.querySelector("video"); + + // Set a listener for "playing" event + video.addEventListener("playing", async () => { + info("Got playing event!"); + let playPauseButton = + content.document.querySelector(".play-pause-button"); + ok( + !playPauseButton.getAttribute("isPaused"), + "playPauseButton does not have isPaused attribute." + ); + }); + + // Set a listener for "pause" event + video.addEventListener("pause", async () => { + info("Got pause event!"); + let playPauseButton = + content.document.querySelector(".play-pause-button"); + // mock-wrapper's pause() method uses an invalid selector and should throw + // an error. Test that the PiP wrapper uses the fallback pause() method. + // This is to ensure PiP can handle cases where a site wrapper script is + // incorrect, but does not break functionality altogether. + ok( + !playPauseButton.getAttribute("isPaused"), + "playPauseButton still doesn't have isPaused attribute." + ); + }); + }); +} + +/** + * Tests that the mock-wrapper.js video wrapper hides the pip toggle when shouldHideToggle() + * returns true. + */ +add_task(async function test_mock_should_hide_toggle() { + await testToggle(TEST_URL_TOGGLE_VISIBILITY, { + "mock-video-controls": { canToggle: false, policy: TOGGLE_POLICIES.HIDDEN }, + }); +}); + +/** + * Tests that the mock-wrapper.js video wrapper does not hide the pip toggle when shouldHideToggle() + * returns false. + */ +add_task(async function test_mock_should_not_hide_toggle() { + await testToggle(TEST_URL, { + "mock-video-controls": { canToggle: true }, + }); +}); diff --git a/browser/extensions/pictureinpicture/tests/browser/test-mock-wrapper.html b/browser/extensions/pictureinpicture/tests/browser/test-mock-wrapper.html new file mode 100644 index 0000000000..f53e7a1b28 --- /dev/null +++ b/browser/extensions/pictureinpicture/tests/browser/test-mock-wrapper.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Mock Wrapper Test</title> + <script type="text/javascript" src="test-mock-wrapper.js"></script> + <script type="text/javascript" src="click-event-helper.js"></script> +</head> +<style> + video { + display: block; + border: 1px solid black; + } +</style> +<body> + <div id="player"> + <video id="mock-video-controls" src="test-video.mp4" controls loop="true" width="400" height="225"></video> + <button class="play-pause-button" onclick="playPause()">play/pause button</button> + <button class="mute-button" onclick="toggleMute()">mute/unmute button</button> + </div> +</body> +</html> diff --git a/browser/extensions/pictureinpicture/tests/browser/test-mock-wrapper.js b/browser/extensions/pictureinpicture/tests/browser/test-mock-wrapper.js new file mode 100644 index 0000000000..2119122428 --- /dev/null +++ b/browser/extensions/pictureinpicture/tests/browser/test-mock-wrapper.js @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function toggleMute() { + let video = document.getElementById("mock-video-controls"); + let muteButton = document.querySelector(".mute-button"); + let isMuted = video.muted; + video.muted = !isMuted; + + if (video.muted) { + muteButton.setAttribute("isMuted", true); + } else { + muteButton.removeAttribute("isMuted"); + } +} + +function playPause() { + let video = document.getElementById("mock-video-controls"); + let playPauseButton = document.querySelector(".play-pause-button"); + + if (video.paused) { + video.play(); + playPauseButton.removeAttribute("isPaused"); + } else { + video.setAttribute("isPaused", true); + video.pause(); + } +} diff --git a/browser/extensions/pictureinpicture/tests/browser/test-toggle-visibility.html b/browser/extensions/pictureinpicture/tests/browser/test-toggle-visibility.html new file mode 100644 index 0000000000..622ea6c568 --- /dev/null +++ b/browser/extensions/pictureinpicture/tests/browser/test-toggle-visibility.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Mock Wrapper Test</title> + <script type="text/javascript" src="test-mock-wrapper.js"></script> + <script type="text/javascript" src="click-event-helper.js"></script> +</head> +<style> + video { + display: block; + border: 1px solid black; + } +</style> +<body> + <div id="player"> + <video id="mock-video-controls" class="mock-preview-video" src="test-video.mp4" controls loop="true" width="400" height="225"></video> + <button class="play-pause-button" onclick="playPause()">play/pause button</button> + <button class="mute-button" onclick="toggleMute()">mute/unmute button</button> + </div> +</body> +</html> |