diff options
Diffstat (limited to 'toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js')
-rw-r--r-- | toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js | 398 |
1 files changed, 398 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..02c006db4a --- /dev/null +++ b/toolkit/components/pictureinpicture/tests/browser_saveLastPiPLoc.js @@ -0,0 +1,398 @@ +/* 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. + */ +async function doTest() { + 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; + } + + function getAvailScreenSize(screen) { + let screenLeft = {}, + screenTop = {}, + screenWidth = {}, + screenHeight = {}; + screen.GetAvailRectDisplayPix( + screenLeft, + screenTop, + screenWidth, + screenHeight + ); + + // 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 *= scaleFactor; + screenTop.value *= scaleFactor; + + 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 + clearSavedPosition(); + + // 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 + isfuzzy( + pipWin.screenX, + rightEdge - defaultPiPWidth, + ACCEPTABLE_DIFFERENCE, + "Default PiP X location" + ); + if (AppConstants.platform == "linux") { + isfuzzy( + pipWin.screenY, + bottomEdge - defaultPiPHeight - tabHeight, + ACCEPTABLE_DIFFERENCE, + "Default PiP Y location" + ); + } else { + isfuzzy( + pipWin.screenY, + bottomEdge - defaultPiPHeight, + ACCEPTABLE_DIFFERENCE, + "Default PiP Y location" + ); + } + isfuzzy( + pipWin.innerHeight, + defaultPiPHeight, + ACCEPTABLE_DIFFERENCE, + "Default PiP height" + ); + isfuzzy( + pipWin.innerWidth, + defaultPiPWidth, + ACCEPTABLE_DIFFERENCE, + "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 + isfuzzy( + pipWin.screenX, + left, + ACCEPTABLE_DIFFERENCE, + "Opened at last X location" + ); + isfuzzy( + pipWin.screenY, + top, + ACCEPTABLE_DIFFERENCE, + "Opened at last Y location" + ); + isfuzzy( + pipWin.innerHeight, + height, + ACCEPTABLE_DIFFERENCE, + "Opened with 1/2 default height" + ); + isfuzzy( + pipWin.innerWidth, + width, + ACCEPTABLE_DIFFERENCE, + "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 + isfuzzy( + pipWin.screenX, + rightEdge - defaultPiPWidth, + ACCEPTABLE_DIFFERENCE, + "Opened at default X location" + ); + isfuzzy( + pipWin.screenY, + bottomEdge - defaultPiPHeight, + ACCEPTABLE_DIFFERENCE, + "Opened at default Y location" + ); + isfuzzy( + pipWin.innerWidth, + defaultPiPWidth, + ACCEPTABLE_DIFFERENCE, + "Opened at default PiP width" + ); + isfuzzy( + pipWin.innerHeight, + defaultPiPHeight, + ACCEPTABLE_DIFFERENCE, + "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."); + + isfuzzy( + pipWin.screenX, + left, + ACCEPTABLE_DIFFERENCE, + "Opened at last X location" + ); + isfuzzy( + pipWin.screenY, + top, + ACCEPTABLE_DIFFERENCE, + "Opened at last Y location" + ); + isfuzzy( + pipWin.innerHeight, + height, + ACCEPTABLE_DIFFERENCE, + "Opened height with previous width" + ); + isfuzzy( + pipWin.innerWidth, + height * (pipWin.innerWidth / pipWin.innerHeight), + ACCEPTABLE_DIFFERENCE, + "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."); + + isfuzzy( + pipWin.screenX, + left, + ACCEPTABLE_DIFFERENCE, + "Opened at last X location" + ); + isfuzzy( + pipWin.screenY, + top, + ACCEPTABLE_DIFFERENCE, + "Opened at last Y location" + ); + isfuzzy( + pipWin.innerHeight, + height, + ACCEPTABLE_DIFFERENCE, + "Opened with previous height" + ); + isfuzzy( + pipWin.innerWidth, + height * (pipWin.innerWidth / pipWin.innerHeight), + ACCEPTABLE_DIFFERENCE, + "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 + isfuzzy( + pipWin.screenX, + left, + ACCEPTABLE_DIFFERENCE, + "Opened at last X location but shifted back on screen" + ); + if (AppConstants.platform == "linux") { + isfuzzy( + pipWin.screenY, + top - tabHeight, + ACCEPTABLE_DIFFERENCE, + "Opened at last Y location but shifted back on screen" + ); + } else { + isfuzzy( + pipWin.screenY, + top, + ACCEPTABLE_DIFFERENCE, + "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 + isfuzzy( + pipWin.screenX, + defaultX, + ACCEPTABLE_DIFFERENCE, + "Opened at last X location but shifted back on screen" + ); + isfuzzy( + pipWin.screenY, + defaultY, + ACCEPTABLE_DIFFERENCE, + "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; + isfuzzy( + pipWin.innerWidth + pipWin.screenX, + rightEdge, + ACCEPTABLE_DIFFERENCE, + "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."); + + ok(pipWin.innerWidth < width, "New video width is smaller"); + isfuzzy( + pipWin.innerWidth + pipWin.screenX, + rightEdge, + ACCEPTABLE_DIFFERENCE, + "Video is on right edge after video is changed" + ); + } + + await ensureMessageAndClosePiP(browser, "with-controls", pipWin, true); + } + ); +} + +add_task(async function test_pip_save_last_loc() { + await doTest(); +}); + +add_task(async function test_pip_save_last_loc_with_os_zoom() { + await SpecialPowers.pushPrefEnv({ set: [["ui.textScaleFactor", 120]] }); + await doTest(); +}); |