summaryrefslogtreecommitdiffstats
path: root/toolkit/components/pictureinpicture/tests/browser_changePiPSrcInFullscreen.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /toolkit/components/pictureinpicture/tests/browser_changePiPSrcInFullscreen.js
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/pictureinpicture/tests/browser_changePiPSrcInFullscreen.js')
-rw-r--r--toolkit/components/pictureinpicture/tests/browser_changePiPSrcInFullscreen.js511
1 files changed, 511 insertions, 0 deletions
diff --git a/toolkit/components/pictureinpicture/tests/browser_changePiPSrcInFullscreen.js b/toolkit/components/pictureinpicture/tests/browser_changePiPSrcInFullscreen.js
new file mode 100644
index 0000000000..e971f17296
--- /dev/null
+++ b/toolkit/components/pictureinpicture/tests/browser_changePiPSrcInFullscreen.js
@@ -0,0 +1,511 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { sinon } = ChromeUtils.importESModule(
+ "resource://testing-common/Sinon.sys.mjs"
+);
+
+const NEW_VIDEO_ASPECT_RATIO = 1.334;
+
+async function switchVideoSource(browser, src) {
+ await ContentTask.spawn(browser, { src }, async ({ src }) => {
+ let doc = content.document;
+ let video = doc.getElementById("no-controls");
+ video.src = src;
+ });
+}
+
+/**
+ *
+ * @param {Object} actual The actual size and position of the window
+ * @param {Object} expected The expected size and position of the window
+ * @param {String} message A message to print before asserting the size and position
+ */
+function assertEvent(actual, expected, message) {
+ info(message);
+ isfuzzy(
+ actual.width,
+ expected.width,
+ ACCEPTABLE_DIFFERENCE,
+ `The actual width: ${actual.width}. The expected width: ${expected.width}`
+ );
+ isfuzzy(
+ actual.height,
+ expected.height,
+ ACCEPTABLE_DIFFERENCE,
+ `The actual height: ${actual.height}. The expected height: ${expected.height}`
+ );
+ isfuzzy(
+ actual.left,
+ expected.left,
+ ACCEPTABLE_DIFFERENCE,
+ `The actual left: ${actual.left}. The expected left: ${expected.left}`
+ );
+ isfuzzy(
+ actual.top,
+ expected.top,
+ ACCEPTABLE_DIFFERENCE,
+ `The actual top: ${actual.top}. The expected top: ${expected.top}`
+ );
+}
+
+/**
+ * This test is our control test. This tests that when the PiP window exits
+ * fullscreen it will return to the size it was before being fullscreened.
+ */
+add_task(async function testNoSrcChangeFullscreen() {
+ // After opening the PiP window, it is resized to 640x360. There is a change
+ // the PiP window will open with that size. To prevent that we override the
+ // last saved position so we open at (0, 0) and 300x300.
+ overrideSavedPosition(0, 0, 300, 300);
+ await BrowserTestUtils.withNewTab(
+ {
+ url: TEST_PAGE,
+ gBrowser,
+ },
+ async browser => {
+ await ensureVideosReady(browser);
+ let pipWin = await triggerPictureInPicture(browser, "no-controls");
+ let controls = pipWin.document.getElementById("controls");
+ const screen = pipWin.screen;
+
+ let resizeEventArray = [];
+ pipWin.addEventListener("resize", event => {
+ let win = event.target;
+ let obj = {
+ width: win.innerWidth,
+ height: win.innerHeight,
+ left: win.screenLeft,
+ top: win.screenTop,
+ };
+ resizeEventArray.push(obj);
+ });
+
+ // Move the PiP window to an unsaved location
+ let left = 100;
+ let top = 100;
+ pipWin.moveTo(left, top);
+
+ await BrowserTestUtils.waitForCondition(
+ () => pipWin.screenLeft === 100 && pipWin.screenTop === 100,
+ "Waiting for PiP to move to 100, 100"
+ );
+
+ let width = 640;
+ let height = 360;
+
+ let resizePromise = BrowserTestUtils.waitForEvent(pipWin, "resize");
+ pipWin.resizeTo(width, height);
+ await resizePromise;
+
+ Assert.equal(
+ resizeEventArray.length,
+ 1,
+ "resizeEventArray should have 1 event"
+ );
+
+ let actualEvent = resizeEventArray.splice(0, 1)[0];
+ let expectedEvent = { width, height, left, top };
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly positioned before fullscreen"
+ );
+
+ await promiseFullscreenEntered(pipWin, async () => {
+ EventUtils.sendMouseEvent(
+ {
+ type: "dblclick",
+ },
+ controls,
+ pipWin
+ );
+ });
+
+ Assert.equal(
+ pipWin.document.fullscreenElement,
+ pipWin.document.body,
+ "Double-click caused us to enter fullscreen."
+ );
+
+ await BrowserTestUtils.waitForCondition(
+ () => resizeEventArray.length === 1,
+ "Waiting for resizeEventArray to have 1 event"
+ );
+
+ actualEvent = resizeEventArray.splice(0, 1)[0];
+ expectedEvent = {
+ width: screen.width,
+ height: screen.height,
+ left: screen.left,
+ top: screen.top,
+ };
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly fullscreened before switching source"
+ );
+
+ await promiseFullscreenExited(pipWin, async () => {
+ EventUtils.sendMouseEvent(
+ {
+ type: "dblclick",
+ },
+ controls,
+ pipWin
+ );
+ });
+
+ Assert.ok(
+ !pipWin.document.fullscreenElement,
+ "Double-click caused us to exit fullscreen."
+ );
+
+ await BrowserTestUtils.waitForCondition(
+ () => resizeEventArray.length >= 1,
+ "Waiting for resizeEventArray to have 1 event, got " +
+ resizeEventArray.length
+ );
+
+ actualEvent = resizeEventArray.splice(0, 1)[0];
+ expectedEvent = { width, height, left, top };
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly positioned after exiting fullscreen"
+ );
+
+ await ensureMessageAndClosePiP(browser, "no-controls", pipWin, false);
+
+ clearSavedPosition();
+ }
+ );
+});
+
+/**
+ * This function tests changing the src of a Picture-in-Picture player while
+ * the player is fullscreened and then ensuring the that video stays
+ * fullscreened after the src change and that the player will resize to the new
+ * video size.
+ */
+add_task(async function testChangingSameSizeVideoSrcFullscreen() {
+ // After opening the PiP window, it is resized to 640x360. There is a change
+ // the PiP window will open with that size. To prevent that we override the
+ // last saved position so we open at (0, 0) and 300x300.
+ overrideSavedPosition(0, 0, 300, 300);
+ await BrowserTestUtils.withNewTab(
+ {
+ url: TEST_PAGE,
+ gBrowser,
+ },
+ async browser => {
+ await ensureVideosReady(browser);
+ let pipWin = await triggerPictureInPicture(browser, "no-controls");
+ let controls = pipWin.document.getElementById("controls");
+ const screen = pipWin.screen;
+ let sandbox = sinon.createSandbox();
+ let resizeToVideoSpy = sandbox.spy(pipWin, "resizeToVideo");
+
+ let resizeEventArray = [];
+ pipWin.addEventListener("resize", event => {
+ let win = event.target;
+ let obj = {
+ width: win.innerWidth,
+ height: win.innerHeight,
+ left: win.screenLeft,
+ top: win.screenTop,
+ };
+ resizeEventArray.push(obj);
+ });
+
+ // Move the PiP window to an unsaved location
+ let left = 100;
+ let top = 100;
+ pipWin.moveTo(left, top);
+
+ await BrowserTestUtils.waitForCondition(
+ () => pipWin.screenLeft === 100 && pipWin.screenTop === 100,
+ "Waiting for PiP to move to 100, 100"
+ );
+
+ let width = 640;
+ let height = 360;
+
+ let resizePromise = BrowserTestUtils.waitForEvent(pipWin, "resize");
+ pipWin.resizeTo(width, height);
+ await resizePromise;
+
+ Assert.equal(
+ resizeEventArray.length,
+ 1,
+ "resizeEventArray should have 1 event"
+ );
+
+ let actualEvent = resizeEventArray.splice(0, 1)[0];
+ let expectedEvent = { width, height, left, top };
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly positioned before fullscreen"
+ );
+
+ await promiseFullscreenEntered(pipWin, async () => {
+ EventUtils.sendMouseEvent(
+ {
+ type: "dblclick",
+ },
+ controls,
+ pipWin
+ );
+ });
+
+ Assert.equal(
+ pipWin.document.fullscreenElement,
+ pipWin.document.body,
+ "Double-click caused us to enter fullscreen."
+ );
+
+ await BrowserTestUtils.waitForCondition(
+ () => resizeEventArray.length === 1,
+ "Waiting for resizeEventArray to have 1 event"
+ );
+
+ actualEvent = resizeEventArray.splice(0, 1)[0];
+ expectedEvent = {
+ width: screen.width,
+ height: screen.height,
+ left: screen.left,
+ top: screen.top,
+ };
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly fullscreened before switching source"
+ );
+
+ await switchVideoSource(browser, "test-video.mp4");
+
+ await BrowserTestUtils.waitForCondition(
+ () => resizeToVideoSpy.calledOnce,
+ "Waiting for deferredResize to be updated"
+ );
+
+ await promiseFullscreenExited(pipWin, async () => {
+ EventUtils.sendMouseEvent(
+ {
+ type: "dblclick",
+ },
+ controls,
+ pipWin
+ );
+ });
+
+ Assert.ok(
+ !pipWin.document.fullscreenElement,
+ "Double-click caused us to exit fullscreen."
+ );
+
+ await BrowserTestUtils.waitForCondition(
+ () => resizeEventArray.length >= 1,
+ "Waiting for resizeEventArray to have 1 event, got " +
+ resizeEventArray.length
+ );
+
+ actualEvent = resizeEventArray.splice(0, 1)[0];
+ expectedEvent = { width, height, left, top };
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly positioned after exiting fullscreen"
+ );
+
+ sandbox.restore();
+ await ensureMessageAndClosePiP(browser, "no-controls", pipWin, false);
+
+ clearSavedPosition();
+ }
+ );
+});
+
+/**
+ * This is similar to the previous test but in this test we switch to a video
+ * with a different aspect ratio to confirm that the PiP window will take the
+ * new aspect ratio after exiting fullscreen. We also exit fullscreen with the
+ * escape key instead of double clicking in this test.
+ */
+add_task(async function testChangingDifferentSizeVideoSrcFullscreen() {
+ // After opening the PiP window, it is resized to 640x360. There is a change
+ // the PiP window will open with that size. To prevent that we override the
+ // last saved position so we open at (0, 0) and 300x300.
+ overrideSavedPosition(0, 0, 300, 300);
+ await BrowserTestUtils.withNewTab(
+ {
+ url: TEST_PAGE,
+ gBrowser,
+ },
+ async browser => {
+ await ensureVideosReady(browser);
+ let pipWin = await triggerPictureInPicture(browser, "no-controls");
+ let controls = pipWin.document.getElementById("controls");
+ const screen = pipWin.screen;
+ let sandbox = sinon.createSandbox();
+ let resizeToVideoSpy = sandbox.spy(pipWin, "resizeToVideo");
+
+ let resizeEventArray = [];
+ pipWin.addEventListener("resize", event => {
+ let win = event.target;
+ let obj = {
+ width: win.innerWidth,
+ height: win.innerHeight,
+ left: win.screenLeft,
+ top: win.screenTop,
+ };
+ resizeEventArray.push(obj);
+ });
+
+ // Move the PiP window to an unsaved location
+ let left = 100;
+ let top = 100;
+ pipWin.moveTo(left, top);
+
+ await BrowserTestUtils.waitForCondition(
+ () => pipWin.screenLeft === 100 && pipWin.screenTop === 100,
+ "Waiting for PiP to move to 100, 100"
+ );
+
+ let width = 640;
+ let height = 360;
+
+ let resizePromise = BrowserTestUtils.waitForEvent(pipWin, "resize");
+ pipWin.resizeTo(width, height);
+ await resizePromise;
+
+ Assert.equal(
+ resizeEventArray.length,
+ 1,
+ "resizeEventArray should have 1 event"
+ );
+
+ let actualEvent = resizeEventArray.splice(0, 1)[0];
+ let expectedEvent = { width, height, left, top };
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly positioned before fullscreen"
+ );
+
+ await promiseFullscreenEntered(pipWin, async () => {
+ EventUtils.sendMouseEvent(
+ {
+ type: "dblclick",
+ },
+ controls,
+ pipWin
+ );
+ });
+
+ Assert.equal(
+ pipWin.document.fullscreenElement,
+ pipWin.document.body,
+ "Double-click caused us to enter fullscreen."
+ );
+
+ await BrowserTestUtils.waitForCondition(
+ () => resizeEventArray.length === 1,
+ "Waiting for resizeEventArray to have 1 event"
+ );
+
+ actualEvent = resizeEventArray.splice(0, 1)[0];
+ expectedEvent = {
+ width: screen.width,
+ height: screen.height,
+ left: screen.left,
+ top: screen.top,
+ };
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly fullscreened before switching source"
+ );
+
+ let previousWidth = pipWin.getDeferredResize().width;
+
+ await switchVideoSource(browser, "test-video-long.mp4");
+
+ // Confirm that we are updating the `deferredResize` and not actually resizing
+ await BrowserTestUtils.waitForCondition(
+ () => resizeToVideoSpy.calledOnce,
+ "Waiting for deferredResize to be updated"
+ );
+
+ // Confirm that we updated the deferredResize to the new width
+ await BrowserTestUtils.waitForCondition(
+ () => previousWidth !== pipWin.getDeferredResize().width,
+ "Waiting for deferredResize to update"
+ );
+
+ await promiseFullscreenExited(pipWin, async () => {
+ EventUtils.synthesizeKey("KEY_Escape", {}, pipWin);
+ });
+
+ Assert.ok(
+ !pipWin.document.fullscreenElement,
+ "Escape key caused us to exit fullscreen."
+ );
+
+ await BrowserTestUtils.waitForCondition(
+ () => resizeEventArray.length >= 1,
+ "Waiting for resizeEventArray to have 1 event, got " +
+ resizeEventArray.length
+ );
+
+ actualEvent = resizeEventArray.splice(0, 1)[0];
+ expectedEvent = {
+ width: height * NEW_VIDEO_ASPECT_RATIO,
+ height,
+ left,
+ top,
+ };
+
+ // When two resize events happen very close together we optimize by
+ // "coalescing" the two resizes into a single resize event. Sometimes
+ // the events aren't "coalesced" together (I don't know why) so I check
+ // if the most recent event is what we are looking for and if it is not
+ // then I'll wait for the resize event we are looking for.
+ if (
+ Math.abs(
+ actualEvent.width - expectedEvent.width <= ACCEPTABLE_DIFFERENCE
+ )
+ ) {
+ // The exit fullscreen resize events were "coalesced".
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly positioned after exiting fullscreen"
+ );
+ } else {
+ // For some reason the exit fullscreen resize events weren't "coalesced"
+ // so we have to wait for the next resize event.
+ await BrowserTestUtils.waitForCondition(
+ () => resizeEventArray.length === 1,
+ "Waiting for resizeEventArray to have 1 event"
+ );
+
+ actualEvent = resizeEventArray.splice(0, 1)[0];
+
+ assertEvent(
+ actualEvent,
+ expectedEvent,
+ "The PiP window has been correctly positioned after exiting fullscreen"
+ );
+ }
+
+ sandbox.restore();
+ await ensureMessageAndClosePiP(browser, "no-controls", pipWin, false);
+
+ clearSavedPosition();
+ }
+ );
+});