summaryrefslogtreecommitdiffstats
path: root/browser/extensions/pictureinpicture/tests/browser/browser_mock_wrapper.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/extensions/pictureinpicture/tests/browser/browser_mock_wrapper.js')
-rw-r--r--browser/extensions/pictureinpicture/tests/browser/browser_mock_wrapper.js205
1 files changed, 205 insertions, 0 deletions
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 },
+ });
+});