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";
// Global values for the left and top edge pixel coordinates. These will be written to
// during the add_setup function in this test file.
let gLeftEdge = 0;
let gTopEdge = 0;
/**
* Run the resize test on a player window.
*
* @param browser (xul:browser)
* The browser that has the source video.
*
* @param videoID (string)
* The id of the video in the browser to test.
*
* @param pipWin (player window)
* A player window to run the tests on.
*
* @param opts (object)
* The options for the test.
*
* pinX (boolean):
* If true, the video's X position shouldn't change when resized.
*
* pinY (boolean):
* If true, the video's Y position shouldn't change when resized.
*/
async function testVideo(browser, videoID, pipWin, { pinX, pinY } = {}) {
async function switchVideoSource(src) {
let videoResized = BrowserTestUtils.waitForEvent(pipWin, "resize");
await ContentTask.spawn(
browser,
{ src, videoID },
async ({ src, videoID }) => {
let doc = content.document;
let video = doc.getElementById(videoID);
video.src = src;
}
);
await videoResized;
}
/**
* Check the new screen position against the previous one. When
* pinX or pinY is true then the top left corner is checked in that
* dimension. Otherwise, the bottom right corner is checked.
*
* The video position is determined by the screen edge it's closest
* to, so in the default bottom right its bottom right corner should
* match the previous video's bottom right corner. For the top left,
* the top left corners should match.
*/
function checkPosition(
previousScreenX,
previousScreenY,
previousWidth,
previousHeight,
newScreenX,
newScreenY,
newWidth,
newHeight
) {
if (pinX || previousScreenX == gLeftEdge) {
Assert.equal(
previousScreenX,
newScreenX,
"New video is still in the same X position"
);
} else {
Assert.less(
Math.abs(previousScreenX + previousWidth - (newScreenX + newWidth)),
2,
"New video ends at the same screen X position (within 1 pixel)"
);
}
if (pinY) {
Assert.equal(
previousScreenY,
newScreenY,
"New video is still in the same Y position"
);
} else {
Assert.equal(
previousScreenY + previousHeight,
newScreenY + newHeight,
"New video ends at the same screen Y position"
);
}
}
Assert.ok(pipWin, "Got PiP window.");
let initialWidth = pipWin.outerWidth;
let initialHeight = pipWin.outerHeight;
let initialAspectRatio = initialWidth / initialHeight;
Assert.equal(
Math.floor(initialAspectRatio * 100),
177, // 16 / 9 = 1.777777777
"Original aspect ratio is 16:9"
);
// Store the window position for later.
let initialScreenX = pipWin.screenX;
let initialScreenY = pipWin.screenY;
await switchVideoSource("test-video-cropped.mp4");
let resizedWidth = pipWin.outerWidth;
let resizedHeight = pipWin.outerHeight;
let resizedAspectRatio = resizedWidth / resizedHeight;
Assert.equal(
Math.floor(resizedAspectRatio * 100),
133, // 4 / 3 = 1.333333333
"Resized aspect ratio is 4:3"
);
Assert.less(resizedWidth, initialWidth, "Resized video has smaller width");
Assert.equal(
resizedHeight,
initialHeight,
"Resized video is the same vertically"
);
let resizedScreenX = pipWin.screenX;
let resizedScreenY = pipWin.screenY;
checkPosition(
initialScreenX,
initialScreenY,
initialWidth,
initialHeight,
resizedScreenX,
resizedScreenY,
resizedWidth,
resizedHeight
);
await switchVideoSource("test-video-vertical.mp4");
let verticalWidth = pipWin.outerWidth;
let verticalHeight = pipWin.outerHeight;
let verticalAspectRatio = verticalWidth / verticalHeight;
if (verticalWidth == 136) {
// The video is minimun width allowed
Assert.equal(
Math.floor(verticalAspectRatio * 100),
56, // 1 / 2 = 0.5
"Vertical aspect ratio is 1:2"
);
} else {
Assert.equal(
Math.floor(verticalAspectRatio * 100),
50, // 1 / 2 = 0.5
"Vertical aspect ratio is 1:2"
);
}
Assert.less(verticalWidth, resizedWidth, "Vertical video width shrunk");
Assert.equal(
verticalHeight,
initialHeight,
"Vertical video height matches previous height"
);
let verticalScreenX = pipWin.screenX;
let verticalScreenY = pipWin.screenY;
checkPosition(
resizedScreenX,
resizedScreenY,
resizedWidth,
resizedHeight,
verticalScreenX,
verticalScreenY,
verticalWidth,
verticalHeight
);
await switchVideoSource("test-video.mp4");
let restoredWidth = pipWin.outerWidth;
let restoredHeight = pipWin.outerHeight;
let restoredAspectRatio = restoredWidth / restoredHeight;
Assert.equal(
Math.floor(restoredAspectRatio * 100),
177,
"Restored aspect ratio is still 16:9"
);
Assert.less(
Math.abs(initialWidth - pipWin.outerWidth),
2,
"Restored video has its original width"
);
Assert.equal(
initialHeight,
pipWin.outerHeight,
"Restored video has its original height"
);
let restoredScreenX = pipWin.screenX;
let restoredScreenY = pipWin.screenY;
checkPosition(
initialScreenX,
initialScreenY,
initialWidth,
initialHeight,
restoredScreenX,
restoredScreenY,
restoredWidth,
restoredHeight
);
}
add_setup(async () => {
await BrowserTestUtils.withNewTab(
{
url: TEST_PAGE,
gBrowser,
},
async browser => {
// Reset the saved PiP location to top-left edge of the screen, wherever
// that may be. We record the top-left edge of the screen coordinates into
// global variables to do later coordinate comparisons after resizes.
let clearWin = await triggerPictureInPicture(browser, "with-controls");
let initialScreenX = clearWin.screenX;
let initialScreenY = clearWin.screenY;
let PiPScreen = PictureInPicture.getWorkingScreen(
initialScreenX,
initialScreenY
);
[gLeftEdge, gTopEdge] = PictureInPicture.getAvailScreenSize(PiPScreen);
clearWin.moveTo(gLeftEdge, gTopEdge);
await BrowserTestUtils.closeWindow(clearWin);
}
);
});
/**
* Tests that if a <video> element is resized the Picture-in-Picture window
* will be resized to match the new dimensions.
*/
add_task(async () => {
for (let videoID of ["with-controls", "no-controls"]) {
info(`Testing ${videoID} case.`);
await BrowserTestUtils.withNewTab(
{
url: TEST_PAGE,
gBrowser,
},
async browser => {
let pipWin = await triggerPictureInPicture(browser, videoID);
await testVideo(browser, videoID, pipWin);
pipWin.moveTo(gLeftEdge, gTopEdge);
await testVideo(browser, videoID, pipWin, { pinX: true, pinY: true });
await BrowserTestUtils.closeWindow(pipWin);
}
);
}
});
/**
* Tests that the RTL video starts on the left and is pinned in the X dimension.
*/
add_task(async () => {
await SpecialPowers.pushPrefEnv({ set: [["intl.l10n.pseudo", "bidi"]] });
for (let videoID of ["with-controls", "no-controls"]) {
info(`Testing ${videoID} case.`);
await BrowserTestUtils.withNewTab(
{
url: TEST_PAGE,
gBrowser,
},
async browser => {
let pipWin = await triggerPictureInPicture(browser, videoID);
await testVideo(browser, videoID, pipWin, { pinX: true });
await BrowserTestUtils.closeWindow(pipWin);
}
);
}
await SpecialPowers.popPrefEnv();
});