diff options
Diffstat (limited to 'browser/base/content/test/permissions/browser_autoplay_blocked.js')
-rw-r--r-- | browser/base/content/test/permissions/browser_autoplay_blocked.js | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/browser/base/content/test/permissions/browser_autoplay_blocked.js b/browser/base/content/test/permissions/browser_autoplay_blocked.js new file mode 100644 index 0000000000..04b0316345 --- /dev/null +++ b/browser/base/content/test/permissions/browser_autoplay_blocked.js @@ -0,0 +1,357 @@ +/* + * Test that a blocked request to autoplay media is shown to the user + */ + +const AUTOPLAY_PAGE = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" + ) + "browser_autoplay_blocked.html"; + +const AUTOPLAY_JS_PAGE = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" + ) + "browser_autoplay_js.html"; + +const SLOW_AUTOPLAY_PAGE = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" + ) + "browser_autoplay_blocked_slow.sjs"; + +const MUTED_AUTOPLAY_PAGE = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" + ) + "browser_autoplay_muted.html"; + +const EMPTY_PAGE = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" + ) + "empty.html"; + +const AUTOPLAY_PREF = "media.autoplay.default"; +const AUTOPLAY_PERM = "autoplay-media"; + +function autoplayBlockedIcon() { + return document.querySelector( + "#blocked-permissions-container " + + ".blocked-permission-icon.autoplay-media-icon" + ); +} + +function permissionListBlockedIcons() { + return document.querySelectorAll( + "image.permission-popup-permission-icon.blocked-permission-icon" + ); +} + +function sleep(ms) { + /* eslint-disable mozilla/no-arbitrary-setTimeout */ + return new Promise(resolve => setTimeout(resolve, ms)); +} + +async function blockedIconShown() { + await TestUtils.waitForCondition(() => { + return BrowserTestUtils.is_visible(autoplayBlockedIcon()); + }, "Blocked icon is shown"); +} + +async function blockedIconHidden() { + await TestUtils.waitForCondition(() => { + return BrowserTestUtils.is_hidden(autoplayBlockedIcon()); + }, "Blocked icon is hidden"); +} + +function testPermListHasEntries(expectEntries) { + let permissionsList = document.getElementById( + "permission-popup-permission-list" + ); + let listEntryCount = permissionsList.querySelectorAll( + ".permission-popup-permission-item" + ).length; + if (expectEntries) { + ok(listEntryCount, "List of permissions is not empty"); + return; + } + ok(!listEntryCount, "List of permissions is empty"); +} + +add_setup(async function () { + registerCleanupFunction(() => { + Services.perms.removeAll(); + Services.prefs.clearUserPref(AUTOPLAY_PREF); + }); +}); + +add_task(async function testMainViewVisible() { + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.ALLOWED); + + await BrowserTestUtils.withNewTab(AUTOPLAY_PAGE, async function () { + ok( + BrowserTestUtils.is_hidden(autoplayBlockedIcon()), + "Blocked icon not shown" + ); + + await openPermissionPopup(); + testPermListHasEntries(false); + await closePermissionPopup(); + }); + + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED); + + await BrowserTestUtils.withNewTab(AUTOPLAY_PAGE, async function (browser) { + let permissionsList = document.getElementById( + "permission-popup-permission-list" + ); + + await blockedIconShown(); + + await openPermissionPopup(); + testPermListHasEntries(true); + + let labelText = SitePermissions.getPermissionLabel(AUTOPLAY_PERM); + let labels = permissionsList.querySelectorAll( + ".permission-popup-permission-label" + ); + is(labels.length, 1, "One permission visible in main view"); + is(labels[0].textContent, labelText, "Correct value"); + + let menulist = document.getElementById("permission-popup-menulist"); + Assert.equal(menulist.label, "Block Audio"); + + await EventUtils.synthesizeMouseAtCenter(menulist, { type: "mousedown" }); + await TestUtils.waitForCondition(() => { + return ( + menulist.getElementsByTagName("menuitem")[0].label === + "Allow Audio and Video" + ); + }); + + let menuitem = menulist.getElementsByTagName("menuitem")[0]; + Assert.equal(menuitem.getAttribute("label"), "Allow Audio and Video"); + + menuitem.click(); + menulist.menupopup.hidePopup(); + await closePermissionPopup(); + + let uri = Services.io.newURI(AUTOPLAY_PAGE); + let state = PermissionTestUtils.getPermissionObject( + uri, + AUTOPLAY_PERM + ).capability; + Assert.equal(state, Services.perms.ALLOW_ACTION); + }); + + Services.perms.removeAll(); +}); + +add_task(async function testGloballyBlockedOnNewWindow() { + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED); + + let principal = + Services.scriptSecurityManager.createContentPrincipalFromOrigin( + AUTOPLAY_PAGE + ); + + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + AUTOPLAY_PAGE + ); + await blockedIconShown(); + + Assert.deepEqual( + SitePermissions.getForPrincipal( + principal, + AUTOPLAY_PERM, + tab.linkedBrowser + ), + { + state: SitePermissions.BLOCK, + scope: SitePermissions.SCOPE_PERSISTENT, + } + ); + + let promiseWin = BrowserTestUtils.waitForNewWindow(); + gBrowser.replaceTabWithWindow(tab); + let win = await promiseWin; + tab = win.gBrowser.selectedTab; + + Assert.deepEqual( + SitePermissions.getForPrincipal( + principal, + AUTOPLAY_PERM, + tab.linkedBrowser + ), + { + state: SitePermissions.BLOCK, + scope: SitePermissions.SCOPE_PERSISTENT, + } + ); + + SitePermissions.removeFromPrincipal( + principal, + AUTOPLAY_PERM, + tab.linkedBrowser + ); + await BrowserTestUtils.closeWindow(win); +}); + +add_task(async function testBFCache() { + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED); + + await BrowserTestUtils.withNewTab("about:home", async function (browser) { + BrowserTestUtils.loadURIString(browser, AUTOPLAY_PAGE); + await blockedIconShown(); + + gBrowser.goBack(); + await blockedIconHidden(); + + // Not sure why using `gBrowser.goForward()` doesn't trigger document's + // visibility changes in some debug build on try server, which makes us not + // to receive the blocked event. + await SpecialPowers.spawn(browser, [], () => { + content.history.forward(); + }); + await blockedIconShown(); + }); + + Services.perms.removeAll(); +}); + +add_task(async function testBlockedIconFromCORSIframe() { + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED); + + await BrowserTestUtils.withNewTab(EMPTY_PAGE, async browser => { + const blockedIconShownPromise = blockedIconShown(); + const CORS_AUTOPLAY_PAGE = AUTOPLAY_PAGE.replace( + "example.com", + "example.org" + ); + info(`Load CORS autoplay on an iframe`); + await SpecialPowers.spawn(browser, [CORS_AUTOPLAY_PAGE], async url => { + const iframe = content.document.createElement("iframe"); + iframe.src = url; + content.document.body.appendChild(iframe); + info("Wait until iframe finishes loading"); + await new Promise(r => (iframe.onload = r)); + }); + await blockedIconShownPromise; + ok(true, "Blocked icon shown for the CORS autoplay iframe"); + }); + + Services.perms.removeAll(); +}); + +add_task(async function testChangingBlockingSettingDuringNavigation() { + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED); + + await BrowserTestUtils.withNewTab("about:home", async function (browser) { + await blockedIconHidden(); + BrowserTestUtils.loadURIString(browser, AUTOPLAY_PAGE); + await blockedIconShown(); + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.ALLOWED); + + gBrowser.goBack(); + await blockedIconHidden(); + + gBrowser.goForward(); + + // Sleep here to prevent false positives, the icon gets shown with an + // async `GloballyAutoplayBlocked` event. The sleep gives it a little + // time for it to show otherwise there is a chance it passes before it + // would have shown. + await sleep(100); + ok( + BrowserTestUtils.is_hidden(autoplayBlockedIcon()), + "Blocked icon is hidden" + ); + }); + + Services.perms.removeAll(); +}); + +add_task(async function testSlowLoadingPage() { + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED); + + let tab1 = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:home" + ); + let tab2 = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + SLOW_AUTOPLAY_PAGE + ); + await blockedIconShown(); + + await BrowserTestUtils.switchTab(gBrowser, tab1); + // Wait until the blocked icon is hidden by switching tabs + await blockedIconHidden(); + await BrowserTestUtils.switchTab(gBrowser, tab2); + await blockedIconShown(); + + BrowserTestUtils.removeTab(tab1); + BrowserTestUtils.removeTab(tab2); + + Services.perms.removeAll(); +}); + +add_task(async function testBlockedAll() { + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED_ALL); + + await BrowserTestUtils.withNewTab("about:home", async function (browser) { + await blockedIconHidden(); + BrowserTestUtils.loadURIString(browser, MUTED_AUTOPLAY_PAGE); + await blockedIconShown(); + + await openPermissionPopup(); + + Assert.equal( + permissionListBlockedIcons().length, + 1, + "Blocked icon is shown" + ); + + let menulist = document.getElementById("permission-popup-menulist"); + await EventUtils.synthesizeMouseAtCenter(menulist, { type: "mousedown" }); + await TestUtils.waitForCondition(() => { + return ( + menulist.getElementsByTagName("menuitem")[1].label === "Block Audio" + ); + }); + + let menuitem = menulist.getElementsByTagName("menuitem")[0]; + menuitem.click(); + menulist.menupopup.hidePopup(); + await closePermissionPopup(); + gBrowser.reload(); + await blockedIconHidden(); + }); + Services.perms.removeAll(); +}); + +add_task(async function testMultiplePlayNotificationsFromJS() { + Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED); + + await BrowserTestUtils.withNewTab("about:home", async function (browser) { + let count = 0; + browser.addEventListener("GloballyAutoplayBlocked", function () { + is(++count, 1, "Shouldn't get more than one autoplay blocked event"); + }); + + await blockedIconHidden(); + + BrowserTestUtils.loadURIString(browser, AUTOPLAY_JS_PAGE); + + await blockedIconShown(); + + // Sleep here a bit to ensure that multiple events don't arrive. + await sleep(100); + + is(count, 1, "Shouldn't have got more events"); + }); + + Services.perms.removeAll(); +}); |