summaryrefslogtreecommitdiffstats
path: root/browser/extensions/pictureinpicture/tests
diff options
context:
space:
mode:
Diffstat (limited to 'browser/extensions/pictureinpicture/tests')
-rw-r--r--browser/extensions/pictureinpicture/tests/browser/.eslintrc.js14
-rw-r--r--browser/extensions/pictureinpicture/tests/browser/browser.ini19
-rw-r--r--browser/extensions/pictureinpicture/tests/browser/browser_mock_wrapper.js205
-rw-r--r--browser/extensions/pictureinpicture/tests/browser/test-mock-wrapper.html22
-rw-r--r--browser/extensions/pictureinpicture/tests/browser/test-mock-wrapper.js31
-rw-r--r--browser/extensions/pictureinpicture/tests/browser/test-toggle-visibility.html22
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>