summaryrefslogtreecommitdiffstats
path: root/toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js')
-rw-r--r--toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js362
1 files changed, 362 insertions, 0 deletions
diff --git a/toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js b/toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js
new file mode 100644
index 0000000000..fbdf7fb456
--- /dev/null
+++ b/toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js
@@ -0,0 +1,362 @@
+/* Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * This function tests that the browser saves the last location of size of
+ * the PiP window and will open the next PiP window in the same location
+ * with the size. It adjusts for aspect ratio by keeping the same height and
+ * adjusting the width of the PiP window.
+ */
+
+add_task(async () => {
+ await BrowserTestUtils.withNewTab(
+ {
+ url: TEST_PAGE,
+ gBrowser,
+ },
+ // Function to switch video source.
+ async browser => {
+ async function switchVideoSource(src) {
+ let videoResized = BrowserTestUtils.waitForEvent(pipWin, "resize");
+ await ContentTask.spawn(browser, { src }, async ({ src }) => {
+ let doc = content.document;
+ let video = doc.getElementById("with-controls");
+ video.src = src;
+ });
+ await videoResized;
+ }
+ // This function is used because the rounding of the width can be off
+ // by about 1 pixel sometimes so this checks that val1 and val2 are
+ // within 1 pixel
+ function checkIfEqual(val1, val2, str) {
+ let equal = Math.abs(val1 - val2);
+ if (equal <= 1) {
+ is(equal <= 1, true, str);
+ } else {
+ is(val1, val2, str);
+ }
+ }
+
+ // Used for clearing the size and location of the PiP window
+ const PLAYER_URI =
+ "chrome://global/content/pictureinpicture/player.xhtml";
+
+ // The PiP window now stores information between tests and needs to be
+ // cleared before the test begins
+ function clearSaved() {
+ let xulStore = Services.xulStore;
+ xulStore.setValue(PLAYER_URI, "picture-in-picture", "left", NaN);
+ xulStore.setValue(PLAYER_URI, "picture-in-picture", "top", NaN);
+ xulStore.setValue(PLAYER_URI, "picture-in-picture", "width", NaN);
+ xulStore.setValue(PLAYER_URI, "picture-in-picture", "height", NaN);
+ }
+
+ function getAvailScreenSize(screen) {
+ let screenLeft = {},
+ screenTop = {},
+ screenWidth = {},
+ screenHeight = {};
+ screen.GetAvailRectDisplayPix(
+ screenLeft,
+ screenTop,
+ screenWidth,
+ screenHeight
+ );
+ let fullLeft = {},
+ fullTop = {},
+ fullWidth = {},
+ fullHeight = {};
+ screen.GetRectDisplayPix(fullLeft, fullTop, fullWidth, fullHeight);
+
+ // We have to divide these dimensions by the CSS scale factor for the
+ // display in order for the video to be positioned correctly on displays
+ // that are not at a 1.0 scaling.
+ let scaleFactor =
+ screen.contentsScaleFactor / screen.defaultCSSScaleFactor;
+ screenWidth.value *= scaleFactor;
+ screenHeight.value *= scaleFactor;
+ screenLeft.value =
+ (screenLeft.value - fullLeft.value) * scaleFactor + fullLeft.value;
+ screenTop.value =
+ (screenTop.value - fullTop.value) * scaleFactor + fullTop.value;
+
+ return [
+ screenLeft.value,
+ screenTop.value,
+ screenWidth.value,
+ screenHeight.value,
+ ];
+ }
+
+ let screen = Cc["@mozilla.org/gfx/screenmanager;1"]
+ .getService(Ci.nsIScreenManager)
+ .screenForRect(1, 1, 1, 1);
+
+ let [
+ defaultX,
+ defaultY,
+ defaultWidth,
+ defaultHeight,
+ ] = getAvailScreenSize(screen);
+
+ // Default size of PiP window
+ let rightEdge = defaultX + defaultWidth;
+ let bottomEdge = defaultY + defaultHeight;
+
+ // tab height
+ // Used only for Linux as the PiP window has a tab
+ let tabHeight = 35;
+
+ // clear already saved information
+ clearSaved();
+
+ // Open PiP
+ let pipWin = await triggerPictureInPicture(browser, "with-controls");
+ ok(pipWin, "Got Picture-in-Picture window.");
+
+ let defaultPiPWidth = pipWin.innerWidth;
+ let defaultPiPHeight = pipWin.innerHeight;
+
+ // Check that it is opened at default location
+ checkIfEqual(
+ pipWin.screenX,
+ rightEdge - defaultPiPWidth,
+ "Default PiP X location"
+ );
+ if (AppConstants.platform == "linux") {
+ checkIfEqual(
+ pipWin.screenY,
+ bottomEdge - defaultPiPHeight - tabHeight,
+ "Default PiP Y location"
+ );
+ } else {
+ checkIfEqual(
+ pipWin.screenY,
+ bottomEdge - defaultPiPHeight,
+ "Default PiP Y location"
+ );
+ }
+ checkIfEqual(pipWin.innerHeight, defaultPiPHeight, "Default PiP height");
+ checkIfEqual(pipWin.innerWidth, defaultPiPWidth, "Default PiP width");
+
+ let top = defaultY;
+ let left = defaultX;
+ pipWin.moveTo(left, top);
+ let height = pipWin.innerHeight / 2;
+ let width = pipWin.innerWidth / 2;
+ pipWin.resizeTo(width, height);
+
+ // CLose first PiP window and open another
+ await ensureMessageAndClosePiP(browser, "with-controls", pipWin, true);
+ pipWin = await triggerPictureInPicture(browser, "with-controls");
+ ok(pipWin, "Got Picture-in-Picture window.");
+
+ // PiP is opened at 0, 0 with size 1/4 default width and 1/4 default height
+ checkIfEqual(pipWin.screenX, left, "Opened at last X location");
+ checkIfEqual(pipWin.screenY, top, "Opened at last Y location");
+ checkIfEqual(
+ pipWin.innerHeight,
+ height,
+ "Opened with 1/2 default height"
+ );
+ checkIfEqual(pipWin.innerWidth, width, "Opened with 1/2 default width");
+
+ // Mac and Linux did not allow moving to coordinates offscreen so this
+ // test is skipped on those platforms
+ if (AppConstants.platform == "win") {
+ // Move to -1111, -1111 and adjust size to 1/4 width and 1/4 height
+ left = -11111;
+ top = -11111;
+ pipWin.moveTo(left, top);
+ pipWin.resizeTo(pipWin.innerWidth / 4, pipWin.innerHeight / 4);
+
+ await ensureMessageAndClosePiP(browser, "with-controls", pipWin, true);
+ pipWin = await triggerPictureInPicture(browser, "with-controls");
+ ok(pipWin, "Got Picture-in-Picture window.");
+
+ // because the coordinates are off screen, the default size and location will be used
+ checkIfEqual(
+ pipWin.screenX,
+ rightEdge - defaultPiPWidth,
+ "Opened at default X location"
+ );
+ checkIfEqual(
+ pipWin.screenY,
+ bottomEdge - defaultPiPHeight,
+ "Opened at default Y location"
+ );
+ checkIfEqual(
+ pipWin.innerWidth,
+ defaultPiPWidth,
+ "Opened at default PiP width"
+ );
+ checkIfEqual(
+ pipWin.innerHeight,
+ defaultPiPHeight,
+ "Opened at default PiP height"
+ );
+ }
+
+ // Linux doesn't handle switching the video source well and it will
+ // cause the tests to failed in unexpected ways. Possibly caused by
+ // bug 1594223 https://bugzilla.mozilla.org/show_bug.cgi?id=1594223
+ if (AppConstants.platform != "linux") {
+ // Save width and height for when aspect ratio is changed
+ height = pipWin.innerHeight;
+ width = pipWin.innerWidth;
+
+ left = 200;
+ top = 100;
+ pipWin.moveTo(left, top);
+
+ // Now switch the video so the video ratio is different
+ await switchVideoSource("test-video-cropped.mp4");
+ await ensureMessageAndClosePiP(browser, "with-controls", pipWin, true);
+ pipWin = await triggerPictureInPicture(browser, "with-controls");
+ ok(pipWin, "Got Picture-in-Picture window.");
+
+ checkIfEqual(pipWin.screenX, left, "Opened at last X location");
+ checkIfEqual(pipWin.screenY, top, "Opened at last Y location");
+ checkIfEqual(
+ pipWin.innerHeight,
+ height,
+ "Opened height with previous width"
+ );
+ checkIfEqual(
+ pipWin.innerWidth,
+ height * (pipWin.innerWidth / pipWin.innerHeight),
+ "Width is changed to adjust for aspect ration"
+ );
+
+ left = 300;
+ top = 300;
+ pipWin.moveTo(left, top);
+ pipWin.resizeTo(defaultPiPWidth / 2, defaultPiPHeight / 2);
+
+ // Save height for when aspect ratio is changed
+ height = pipWin.innerHeight;
+
+ // Now switch the video so the video ratio is different
+ await switchVideoSource("test-video.mp4");
+ await ensureMessageAndClosePiP(browser, "with-controls", pipWin, true);
+ pipWin = await triggerPictureInPicture(browser, "with-controls");
+ ok(pipWin, "Got Picture-in-Picture window.");
+
+ checkIfEqual(pipWin.screenX, left, "Opened at last X location");
+ checkIfEqual(pipWin.screenY, top, "Opened at last Y location");
+ checkIfEqual(pipWin.innerHeight, height, "Opened with previous height");
+ checkIfEqual(
+ pipWin.innerWidth,
+ height * (pipWin.innerWidth / pipWin.innerHeight),
+ "Width is changed to adjust for aspect ration"
+ );
+ }
+
+ // Move so that part of PiP is off screen (bottom right)
+
+ left = rightEdge - Math.round((3 * pipWin.innerWidth) / 4);
+ top = bottomEdge - Math.round((3 * pipWin.innerHeight) / 4);
+
+ let movePromise = BrowserTestUtils.waitForEvent(
+ pipWin.windowRoot,
+ "MozUpdateWindowPos"
+ );
+ pipWin.moveTo(left, top);
+ await movePromise;
+
+ await ensureMessageAndClosePiP(browser, "with-controls", pipWin, true);
+ pipWin = await triggerPictureInPicture(browser, "with-controls");
+ ok(pipWin, "Got Picture-in-Picture window.");
+
+ // Redefine top and left to where the PiP windop will open
+ left = rightEdge - pipWin.innerWidth;
+ top = bottomEdge - pipWin.innerHeight;
+
+ // await new Promise(r => setTimeout(r, 5000));
+ // PiP is opened bottom right but not off screen
+ checkIfEqual(
+ pipWin.screenX,
+ left,
+ "Opened at last X location but shifted back on screen"
+ );
+ if (AppConstants.platform == "linux") {
+ checkIfEqual(
+ pipWin.screenY,
+ top - tabHeight,
+ "Opened at last Y location but shifted back on screen"
+ );
+ } else {
+ checkIfEqual(
+ pipWin.screenY,
+ top,
+ "Opened at last Y location but shifted back on screen"
+ );
+ }
+
+ // Move so that part of PiP is off screen (top left)
+ left = defaultX - Math.round(pipWin.innerWidth / 4);
+ top = defaultY - Math.round(pipWin.innerHeight / 4);
+
+ movePromise = BrowserTestUtils.waitForEvent(
+ pipWin.windowRoot,
+ "MozUpdateWindowPos"
+ );
+ pipWin.moveTo(left, top);
+ await movePromise;
+
+ await ensureMessageAndClosePiP(browser, "with-controls", pipWin, true);
+ pipWin = await triggerPictureInPicture(browser, "with-controls");
+ ok(pipWin, "Got Picture-in-Picture window.");
+
+ // PiP is opened top left on screen
+ checkIfEqual(
+ pipWin.screenX,
+ defaultX,
+ "Opened at last X location but shifted back on screen"
+ );
+ checkIfEqual(
+ pipWin.screenY,
+ defaultY,
+ "Opened at last Y location but shifted back on screen"
+ );
+
+ if (AppConstants.platform != "linux") {
+ // test that if video is on right edge and new video with smaller width
+ // is opened next, it is still on the right edge
+ left = rightEdge - pipWin.innerWidth;
+ top = Math.round(bottomEdge / 4);
+
+ pipWin.moveTo(left, top);
+
+ // Used to ensure that video width decreases for next PiP window
+ width = pipWin.innerWidth;
+ checkIfEqual(
+ pipWin.innerWidth + pipWin.screenX,
+ rightEdge,
+ "Video is on right edge before video is changed"
+ );
+
+ // Now switch the video so the video width is smaller
+ await switchVideoSource("test-video-cropped.mp4");
+ await ensureMessageAndClosePiP(browser, "with-controls", pipWin, true);
+ pipWin = await triggerPictureInPicture(browser, "with-controls");
+ ok(pipWin, "Got Picture-in-Picture window.");
+
+ checkIfEqual(
+ pipWin.innerWidth < width,
+ true,
+ "New video width is smaller"
+ );
+ checkIfEqual(
+ pipWin.innerWidth + pipWin.screenX,
+ rightEdge,
+ "Video is on right edge after video is changed"
+ );
+ }
+
+ await ensureMessageAndClosePiP(browser, "with-controls", pipWin, true);
+ }
+ );
+});