Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'linux' && os_version == '18.04' && processor == 'x86_64'
- Manifest: toolkit/components/pictureinpicture/tests/browser.toml
/* Any copyright is dedicated to the Public Domain.
"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.outerWidth;
let defaultPiPHeight = pipWin.outerHeight;
// 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.outerHeight,
defaultPiPHeight,
ACCEPTABLE_DIFFERENCE,
"Default PiP height"
);
isfuzzy(
pipWin.outerWidth,
defaultPiPWidth,
ACCEPTABLE_DIFFERENCE,
"Default PiP width"
);
let top = defaultY;
let left = defaultX;
pipWin.moveTo(left, top);
let height = pipWin.outerHeight / 2;
let width = pipWin.outerWidth / 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.outerHeight,
height,
ACCEPTABLE_DIFFERENCE,
"Opened with 1/2 default height"
);
isfuzzy(
pipWin.outerWidth,
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.outerWidth / 4, pipWin.outerHeight / 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.outerWidth,
defaultPiPWidth,
ACCEPTABLE_DIFFERENCE,
"Opened at default PiP width"
);
isfuzzy(
pipWin.outerHeight,
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
if (AppConstants.platform != "linux") {
// Save width and height for when aspect ratio is changed
height = pipWin.outerHeight;
width = pipWin.outerWidth;
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.outerHeight,
height,
ACCEPTABLE_DIFFERENCE,
"Opened height with previous width"
);
isfuzzy(
pipWin.outerWidth,
height * (pipWin.outerWidth / pipWin.outerHeight),
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.outerHeight;
// 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.outerHeight,
height,
ACCEPTABLE_DIFFERENCE,
"Opened with previous height"
);
isfuzzy(
pipWin.outerWidth,
height * (pipWin.outerWidth / pipWin.outerHeight),
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.outerWidth) / 4);
top = bottomEdge - Math.round((3 * pipWin.outerHeight) / 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.outerWidth;
top = bottomEdge - pipWin.outerHeight;
// 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.outerWidth / 4);
top = defaultY - Math.round(pipWin.outerHeight / 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.outerWidth;
top = Math.round(bottomEdge / 4);
pipWin.moveTo(left, top);
// Used to ensure that video width decreases for next PiP window
width = pipWin.outerWidth;
isfuzzy(
pipWin.outerWidth + 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.");
Assert.less(pipWin.outerWidth, width, "New video width is smaller");
isfuzzy(
pipWin.outerWidth + 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();
});