Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/* Any copyright is dedicated to the Public Domain.
"use strict";
/**
* Tests that the Picture-in-Picture toggle is hidden when videos
* are laid out with dimensions smaller than MIN_VIDEO_DIMENSION (a
* constant that is also defined in videocontrols.js).
*/
add_task(async () => {
// Most of the Picture-in-Picture tests run with the always-show
// preference set to true to avoid the toggle visibility heuristics.
// Since this test actually exercises those heuristics, we have
// to temporarily disable that pref.
//
// We also reduce the minimum video length for displaying the toggle
// to 5 seconds to avoid having to include or generate a 45 second long
// video (which is the default minimum length).
await SpecialPowers.pushPrefEnv({
set: [
[
"media.videocontrols.picture-in-picture.video-toggle.always-show",
false,
],
["media.videocontrols.picture-in-picture.video-toggle.min-video-secs", 5],
],
});
// This is the minimum size of the video in either width or height for
// which we will show the toggle. See videocontrols.js.
const MIN_VIDEO_DIMENSION = 140; // pixels
for (let videoID of ["with-controls", "no-controls"]) {
info(`Testing ${videoID} case.`);
await BrowserTestUtils.withNewTab(
{
url: TEST_PAGE_WITH_SOUND,
gBrowser,
},
async browser => {
// Shrink the video down to less than MIN_VIDEO_DIMENSION.
let targetWidth = MIN_VIDEO_DIMENSION - 1;
await SpecialPowers.spawn(
browser,
[videoID, targetWidth],
async (videoID, targetWidth) => {
let video = content.document.getElementById(videoID);
let shadowRoot = video.openOrClosedShadowRoot;
let resizePromise = ContentTaskUtils.waitForEvent(
shadowRoot.firstChild,
"resizevideocontrols"
);
video.style.width = targetWidth + "px";
await resizePromise;
}
);
// The toggle should be hidden.
await testToggleHelper(browser, videoID, false);
// Now re-expand the video.
await SpecialPowers.spawn(browser, [videoID], async videoID => {
let video = content.document.getElementById(videoID);
let shadowRoot = video.openOrClosedShadowRoot;
let resizePromise = ContentTaskUtils.waitForEvent(
shadowRoot.firstChild,
"resizevideocontrols"
);
video.style.width = "";
await resizePromise;
});
// The toggle should be visible.
await testToggleHelper(browser, videoID, true);
}
);
}
});
/**
* Tests that when using the experimental toggle variations, videos
* under 320px width are given the "small-video" attribute.
*/
add_task(async () => {
const TOGGLE_SMALL = {
rootID: "pictureInPictureToggle",
stages: {
hoverVideo: {
opacities: {
".pip-wrapper": DEFAULT_TOGGLE_OPACITY,
},
hidden: [],
},
hoverToggle: {
opacities: {
".pip-wrapper": 1.0,
},
hidden: [".pip-expanded"],
},
},
};
const TOGGLE_LARGE = {
rootID: "pictureInPictureToggle",
stages: {
hoverVideo: {
opacities: {
".pip-small": 0.0,
".pip-wrapper": DEFAULT_TOGGLE_OPACITY,
".pip-expanded": 0.0,
},
hidden: [".pip-explainer", ".pip-icon-label > .pip-icon"],
},
hoverToggle: {
opacities: {
".pip-small": 0.0,
".pip-wrapper": 1.0,
},
hidden: [
".pip-explainer",
".pip-icon-label > .pip-icon",
".pip-expanded",
],
},
},
};
// Most of the Picture-in-Picture tests run with the always-show
// preference set to true to avoid the toggle visibility heuristics.
// Since this test actually exercises those heuristics, we have
// to temporarily disable that pref.
//
// We also reduce the minimum video length for displaying the toggle
// to 5 seconds to avoid having to include or generate a 45 second long
// video (which is the default minimum length).
await SpecialPowers.pushPrefEnv({
set: [
[
"media.videocontrols.picture-in-picture.video-toggle.always-show",
false,
],
["media.videocontrols.picture-in-picture.video-toggle.min-video-secs", 5],
["media.videocontrols.picture-in-picture.video-toggle.mode", 1],
],
});
// Videos that are thinner than MIN_VIDEO_WIDTH should have the small-video
// attribute set on the experimental toggle.
const MIN_VIDEO_WIDTH = 320; // pixels
for (let videoID of ["with-controls", "no-controls"]) {
info(`Testing ${videoID} case.`);
await BrowserTestUtils.withNewTab(
{
url: TEST_PAGE_WITH_SOUND,
gBrowser,
},
async browser => {
// Shrink the video down to less than MIN_VIDEO_WIDTH.
let targetWidth = MIN_VIDEO_WIDTH - 1;
let isSmallVideo = await SpecialPowers.spawn(
browser,
[videoID, targetWidth],
async (videoID, targetWidth) => {
let video = content.document.getElementById(videoID);
let shadowRoot = video.openOrClosedShadowRoot;
let resizePromise = ContentTaskUtils.waitForEvent(
shadowRoot.firstChild,
"resizevideocontrols"
);
video.style.width = targetWidth + "px";
await resizePromise;
let toggle = shadowRoot.getElementById("pictureInPictureToggle");
return toggle.hasAttribute("small-video");
}
);
Assert.ok(isSmallVideo, "Video should have small-video attribute");
await testToggleHelper(browser, videoID, true, undefined, TOGGLE_SMALL);
// Now re-expand the video.
isSmallVideo = await SpecialPowers.spawn(
browser,
[videoID],
async videoID => {
let video = content.document.getElementById(videoID);
let shadowRoot = video.openOrClosedShadowRoot;
let resizePromise = ContentTaskUtils.waitForEvent(
shadowRoot.firstChild,
"resizevideocontrols"
);
video.style.width = "";
await resizePromise;
let toggle = shadowRoot.getElementById("pictureInPictureToggle");
return toggle.hasAttribute("small-video");
}
);
Assert.ok(!isSmallVideo, "Video should not have small-video attribute");
await testToggleHelper(browser, videoID, true, undefined, TOGGLE_LARGE);
}
);
}
});