Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
*/
"use strict";
const { PermissionTestUtils } = ChromeUtils.importESModule(
);
const VIDEO_PAGE_URI = GetTestWebBasedURL("file_empty.html");
const SAME_ORIGIN_FRAME_URI = GetTestWebBasedURL(
"file_mediaplayback_frame.html"
);
const DIFFERENT_ORIGIN_FRAME_URI = GetTestWebBasedURL(
"file_mediaplayback_frame.html",
{ crossOrigin: true }
);
const gPermissionName = "autoplay-media";
function setTestingPreferences(defaultSetting) {
info(`set default autoplay setting to '${defaultSetting}'`);
let defaultValue =
defaultSetting == "blocked"
? SpecialPowers.Ci.nsIAutoplay.BLOCKED
: SpecialPowers.Ci.nsIAutoplay.ALLOWED;
return SpecialPowers.pushPrefEnv({
set: [
["media.autoplay.default", defaultValue],
["media.autoplay.blocking_policy", 0],
["media.autoplay.block-event.enabled", true],
],
});
}
async function testAutoplayExistingPermission(args) {
info("- Starting '" + args.name + "' -");
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: VIDEO_PAGE_URI,
},
async browser => {
let promptShowing = () =>
PopupNotifications.getNotification("autoplay-media", browser);
PermissionTestUtils.add(
browser.currentURI,
"autoplay-media",
args.permission
);
ok(!promptShowing(), "Should not be showing permission prompt yet");
await loadAutoplayVideo(browser, args);
await checkVideoDidPlay(browser, args);
// Reset permission.
PermissionTestUtils.remove(browser.currentURI, "autoplay-media");
info("- Finished '" + args.name + "' -");
}
);
}
async function testAutoplayExistingPermissionAgainstDefaultSetting(args) {
await setTestingPreferences(args.defaultSetting);
await testAutoplayExistingPermission(args);
}
// Test the simple ALLOW/BLOCK cases; when permission is already set to ALLOW,
// we shoud be able to autoplay via calling play(), or via the autoplay attribute,
// and when it's set to BLOCK, we should not.
add_task(async () => {
await setTestingPreferences("blocked" /* default setting */);
await testAutoplayExistingPermission({
name: "Prexisting allow permission autoplay attribute",
permission: Services.perms.ALLOW_ACTION,
shouldPlay: true,
mode: "autoplay attribute",
});
await testAutoplayExistingPermission({
name: "Prexisting allow permission call play",
permission: Services.perms.ALLOW_ACTION,
shouldPlay: true,
mode: "call play",
});
await testAutoplayExistingPermission({
name: "Prexisting block permission autoplay attribute",
permission: Services.perms.DENY_ACTION,
shouldPlay: false,
mode: "autoplay attribute",
});
await testAutoplayExistingPermission({
name: "Prexisting block permission call play",
permission: Services.perms.DENY_ACTION,
shouldPlay: false,
mode: "call play",
});
});
/**
* These tests are used to ensure the autoplay setting for specific site can
* always override the default autoplay setting.
*/
add_task(async () => {
await testAutoplayExistingPermissionAgainstDefaultSetting({
name: "Site has prexisting allow permission but default setting is 'blocked'",
permission: Services.perms.ALLOW_ACTION,
defaultSetting: "blocked",
shouldPlay: true,
mode: "autoplay attribute",
});
await testAutoplayExistingPermissionAgainstDefaultSetting({
name: "Site has prexisting block permission but default setting is 'allowed'",
permission: Services.perms.DENY_ACTION,
defaultSetting: "allowed",
shouldPlay: false,
mode: "autoplay attribute",
});
});
/**
* The permission of the main page's domain would determine the final autoplay
* result when a page contains multiple iframes which are in the different
* domain from the main pages's.
* That means we would not check the permission of iframe's domain, even if it
* has been set.
*/
add_task(async function testExistingPermissionForIframe() {
await setTestingPreferences("blocked" /* default setting */);
await testAutoplayExistingPermissionForIframe({
name: "Prexisting ALLOW for main page with same origin iframe",
permissionForParent: Services.perms.ALLOW_ACTION,
isIframeDifferentOrgin: true,
shouldPlay: true,
});
await testAutoplayExistingPermissionForIframe({
name: "Prexisting ALLOW for main page with different origin iframe",
permissionForParent: Services.perms.ALLOW_ACTION,
isIframeDifferentOrgin: false,
shouldPlay: true,
});
await testAutoplayExistingPermissionForIframe({
name: "Prexisting ALLOW for main page, prexisting DENY for different origin iframe",
permissionForParent: Services.perms.ALLOW_ACTION,
permissionForChild: Services.perms.DENY_ACTION,
isIframeDifferentOrgin: false,
shouldPlay: true,
});
await testAutoplayExistingPermissionForIframe({
name: "Prexisting DENY for main page, prexisting ALLOW for different origin iframe",
permissionForParent: Services.perms.DENY_ACTION,
permissionForChild: Services.perms.ALLOW_ACTION,
isIframeDifferentOrgin: false,
shouldPlay: false,
});
});
/**
* The following are helper functions.
*/
async function testAutoplayExistingPermissionForIframe(args) {
info(`Start test : ${args.name}`);
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: VIDEO_PAGE_URI,
},
async browser => {
setupSitesPermission(browser, args);
await createIframe(browser, args);
await checkAutplayInIframe(browser, args);
clearSitesPermission(browser, args);
}
);
info(`Finish test : ${args.name}`);
}
function setupSitesPermission(
browser,
{
isIframeDifferentOrgin,
permissionForParent,
permissionForChild = Services.perms.UNKNOWN_ACTION,
}
) {
info(`setupSitesPermission`);
// Set permission for the main page's domain
setPermissionForBrowser(browser, browser.currentURI, permissionForParent);
if (isIframeDifferentOrgin) {
// Set permission for different domain of the iframe
setPermissionForBrowser(
browser,
DIFFERENT_ORIGIN_FRAME_URI,
permissionForChild
);
}
}
function clearSitesPermission(browser, { isIframeDifferentOrgin }) {
info(`clearSitesPermission`);
// Clear permission for the main page's domain
setPermissionForBrowser(
browser,
browser.currentURI,
Services.perms.UNKNOWN_ACTION
);
if (isIframeDifferentOrgin) {
// Clear permission for different domain of the iframe
setPermissionForBrowser(
browser,
DIFFERENT_ORIGIN_FRAME_URI,
Services.perms.UNKNOWN_ACTION
);
}
}
function setPermissionForBrowser(browser, uri, permValue) {
const promptShowing = () =>
PopupNotifications.getNotification(gPermissionName, browser);
PermissionTestUtils.add(uri, gPermissionName, permValue);
ok(!promptShowing(), "Should not be showing permission prompt yet");
is(
PermissionTestUtils.testExactPermission(uri, gPermissionName),
permValue,
"Set permission correctly"
);
}
function createIframe(browser, { isIframeDifferentOrgin }) {
const iframeURL = isIframeDifferentOrgin
? DIFFERENT_ORIGIN_FRAME_URI
: SAME_ORIGIN_FRAME_URI;
return SpecialPowers.spawn(browser, [iframeURL], async url => {
info(`Create iframe and wait until it finsihes loading`);
const iframe = content.document.createElement("iframe");
iframe.src = url;
content.document.body.appendChild(iframe);
await new Promise(r => (iframe.onload = r));
});
}
function checkAutplayInIframe(browser, args) {
return SpecialPowers.spawn(browser, [args], async ({ shouldPlay }) => {
info(`check if media in iframe can start playing`);
const iframe = content.document.getElementsByTagName("iframe")[0];
if (!iframe) {
ok(false, `can not get the iframe!`);
return;
}
iframe.contentWindow.postMessage("play", "*");
await new Promise(r => {
content.onmessage = event => {
if (shouldPlay) {
is(event.data, "played", `played media in iframe`);
} else {
is(event.data, "blocked", `blocked media in iframe`);
}
r();
};
});
});
}