tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_autoplay_blocked.js (10237B)


      1 /*
      2 * Test that a blocked request to autoplay media is shown to the user
      3 */
      4 
      5 const AUTOPLAY_PAGE =
      6  getRootDirectory(gTestPath).replace(
      7    "chrome://mochitests/content",
      8    "https://example.com"
      9  ) + "browser_autoplay_blocked.html";
     10 
     11 const AUTOPLAY_JS_PAGE =
     12  getRootDirectory(gTestPath).replace(
     13    "chrome://mochitests/content",
     14    "https://example.com"
     15  ) + "browser_autoplay_js.html";
     16 
     17 const SLOW_AUTOPLAY_PAGE =
     18  getRootDirectory(gTestPath).replace(
     19    "chrome://mochitests/content",
     20    "https://example.com"
     21  ) + "browser_autoplay_blocked_slow.sjs";
     22 
     23 const MUTED_AUTOPLAY_PAGE =
     24  getRootDirectory(gTestPath).replace(
     25    "chrome://mochitests/content",
     26    "https://example.com"
     27  ) + "browser_autoplay_muted.html";
     28 
     29 const EMPTY_PAGE =
     30  getRootDirectory(gTestPath).replace(
     31    "chrome://mochitests/content",
     32    "https://example.com"
     33  ) + "empty.html";
     34 
     35 const AUTOPLAY_PREF = "media.autoplay.default";
     36 const AUTOPLAY_PERM = "autoplay-media";
     37 
     38 function autoplayBlockedIcon() {
     39  return document.querySelector(
     40    "#blocked-permissions-container " +
     41      ".blocked-permission-icon.autoplay-media-icon"
     42  );
     43 }
     44 
     45 function permissionListBlockedIcons() {
     46  return document.querySelectorAll(
     47    "image.permission-popup-permission-icon.blocked-permission-icon"
     48  );
     49 }
     50 
     51 function sleep(ms) {
     52  /* eslint-disable mozilla/no-arbitrary-setTimeout */
     53  return new Promise(resolve => setTimeout(resolve, ms));
     54 }
     55 
     56 async function blockedIconShown() {
     57  await TestUtils.waitForCondition(() => {
     58    return BrowserTestUtils.isVisible(autoplayBlockedIcon());
     59  }, "Blocked icon is shown");
     60 }
     61 
     62 async function blockedIconHidden() {
     63  await TestUtils.waitForCondition(() => {
     64    return BrowserTestUtils.isHidden(autoplayBlockedIcon());
     65  }, "Blocked icon is hidden");
     66 }
     67 
     68 function testPermListHasEntries(expectEntries) {
     69  let permissionsList = document.getElementById(
     70    "permission-popup-permission-list"
     71  );
     72  let listEntryCount = permissionsList.querySelectorAll(
     73    ".permission-popup-permission-item"
     74  ).length;
     75  if (expectEntries) {
     76    ok(listEntryCount, "List of permissions is not empty");
     77    return;
     78  }
     79  ok(!listEntryCount, "List of permissions is empty");
     80 }
     81 
     82 add_setup(async function () {
     83  registerCleanupFunction(() => {
     84    Services.perms.removeAll();
     85    Services.prefs.clearUserPref(AUTOPLAY_PREF);
     86  });
     87 });
     88 
     89 add_task(async function testMainViewVisible() {
     90  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.ALLOWED);
     91 
     92  await BrowserTestUtils.withNewTab(AUTOPLAY_PAGE, async function () {
     93    ok(
     94      BrowserTestUtils.isHidden(autoplayBlockedIcon()),
     95      "Blocked icon not shown"
     96    );
     97 
     98    await openPermissionPopup();
     99    testPermListHasEntries(false);
    100    await closePermissionPopup();
    101  });
    102 
    103  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
    104 
    105  await BrowserTestUtils.withNewTab(AUTOPLAY_PAGE, async function () {
    106    let permissionsList = document.getElementById(
    107      "permission-popup-permission-list"
    108    );
    109 
    110    await blockedIconShown();
    111 
    112    await openPermissionPopup();
    113    testPermListHasEntries(true);
    114 
    115    let labelText = SitePermissions.getPermissionLabel(AUTOPLAY_PERM);
    116    let labels = permissionsList.querySelectorAll(
    117      ".permission-popup-permission-label"
    118    );
    119    is(labels.length, 1, "One permission visible in main view");
    120    is(labels[0].textContent, labelText, "Correct value");
    121 
    122    let menulist = document.getElementById("permission-popup-menulist");
    123    Assert.equal(menulist.label, "Block Audio");
    124 
    125    await EventUtils.synthesizeMouseAtCenter(menulist, { type: "mousedown" });
    126    await TestUtils.waitForCondition(() => {
    127      return (
    128        menulist.getElementsByTagName("menuitem")[0].label ===
    129        "Allow Audio and Video"
    130      );
    131    });
    132 
    133    let menuitem = menulist.getElementsByTagName("menuitem")[0];
    134    Assert.equal(menuitem.getAttribute("label"), "Allow Audio and Video");
    135 
    136    menuitem.click();
    137    menulist.menupopup.hidePopup();
    138    await closePermissionPopup();
    139 
    140    let uri = Services.io.newURI(AUTOPLAY_PAGE);
    141    let state = PermissionTestUtils.getPermissionObject(
    142      uri,
    143      AUTOPLAY_PERM
    144    ).capability;
    145    Assert.equal(state, Services.perms.ALLOW_ACTION);
    146  });
    147 
    148  Services.perms.removeAll();
    149 });
    150 
    151 add_task(async function testGloballyBlockedOnNewWindow() {
    152  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
    153 
    154  let principal =
    155    Services.scriptSecurityManager.createContentPrincipalFromOrigin(
    156      AUTOPLAY_PAGE
    157    );
    158 
    159  let tab = await BrowserTestUtils.openNewForegroundTab(
    160    gBrowser,
    161    AUTOPLAY_PAGE
    162  );
    163  await blockedIconShown();
    164 
    165  Assert.deepEqual(
    166    SitePermissions.getForPrincipal(
    167      principal,
    168      AUTOPLAY_PERM,
    169      tab.linkedBrowser
    170    ),
    171    {
    172      state: SitePermissions.BLOCK,
    173      scope: SitePermissions.SCOPE_PERSISTENT,
    174    }
    175  );
    176 
    177  let promiseWin = BrowserTestUtils.waitForNewWindow();
    178  gBrowser.replaceTabWithWindow(tab);
    179  let win = await promiseWin;
    180  tab = win.gBrowser.selectedTab;
    181 
    182  Assert.deepEqual(
    183    SitePermissions.getForPrincipal(
    184      principal,
    185      AUTOPLAY_PERM,
    186      tab.linkedBrowser
    187    ),
    188    {
    189      state: SitePermissions.BLOCK,
    190      scope: SitePermissions.SCOPE_PERSISTENT,
    191    }
    192  );
    193 
    194  SitePermissions.removeFromPrincipal(
    195    principal,
    196    AUTOPLAY_PERM,
    197    tab.linkedBrowser
    198  );
    199  await BrowserTestUtils.closeWindow(win);
    200 });
    201 
    202 add_task(async function testBFCache() {
    203  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
    204 
    205  await BrowserTestUtils.withNewTab("about:home", async function (browser) {
    206    BrowserTestUtils.startLoadingURIString(browser, AUTOPLAY_PAGE);
    207    await blockedIconShown();
    208 
    209    gBrowser.goBack();
    210    await blockedIconHidden();
    211 
    212    // Not sure why using `gBrowser.goForward()` doesn't trigger document's
    213    // visibility changes in some debug build on try server, which makes us not
    214    // to receive the blocked event.
    215    await SpecialPowers.spawn(browser, [], () => {
    216      content.history.forward();
    217    });
    218    await blockedIconShown();
    219  });
    220 
    221  Services.perms.removeAll();
    222 });
    223 
    224 add_task(async function testBlockedIconFromCORSIframe() {
    225  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
    226 
    227  await BrowserTestUtils.withNewTab(EMPTY_PAGE, async browser => {
    228    const blockedIconShownPromise = blockedIconShown();
    229    const CORS_AUTOPLAY_PAGE = AUTOPLAY_PAGE.replace(
    230      "example.com",
    231      "example.org"
    232    );
    233    info(`Load CORS autoplay on an iframe`);
    234    await SpecialPowers.spawn(browser, [CORS_AUTOPLAY_PAGE], async url => {
    235      const iframe = content.document.createElement("iframe");
    236      iframe.src = url;
    237      content.document.body.appendChild(iframe);
    238      info("Wait until iframe finishes loading");
    239      await new Promise(r => (iframe.onload = r));
    240    });
    241    await blockedIconShownPromise;
    242    ok(true, "Blocked icon shown for the CORS autoplay iframe");
    243  });
    244 
    245  Services.perms.removeAll();
    246 });
    247 
    248 add_task(async function testChangingBlockingSettingDuringNavigation() {
    249  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
    250 
    251  await BrowserTestUtils.withNewTab("about:home", async function (browser) {
    252    await blockedIconHidden();
    253    BrowserTestUtils.startLoadingURIString(browser, AUTOPLAY_PAGE);
    254    await blockedIconShown();
    255    Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.ALLOWED);
    256 
    257    gBrowser.goBack();
    258    await blockedIconHidden();
    259 
    260    gBrowser.goForward();
    261 
    262    // Sleep here to prevent false positives, the icon gets shown with an
    263    // async `GloballyAutoplayBlocked` event. The sleep gives it a little
    264    // time for it to show otherwise there is a chance it passes before it
    265    // would have shown.
    266    await sleep(100);
    267    ok(
    268      BrowserTestUtils.isHidden(autoplayBlockedIcon()),
    269      "Blocked icon is hidden"
    270    );
    271  });
    272 
    273  Services.perms.removeAll();
    274 });
    275 
    276 add_task(async function testSlowLoadingPage() {
    277  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
    278 
    279  let tab1 = await BrowserTestUtils.openNewForegroundTab(
    280    gBrowser,
    281    "about:home"
    282  );
    283  let tab2 = await BrowserTestUtils.openNewForegroundTab(
    284    gBrowser,
    285    SLOW_AUTOPLAY_PAGE
    286  );
    287  await blockedIconShown();
    288 
    289  await BrowserTestUtils.switchTab(gBrowser, tab1);
    290  // Wait until the blocked icon is hidden by switching tabs
    291  await blockedIconHidden();
    292  await BrowserTestUtils.switchTab(gBrowser, tab2);
    293  await blockedIconShown();
    294 
    295  BrowserTestUtils.removeTab(tab1);
    296  BrowserTestUtils.removeTab(tab2);
    297 
    298  Services.perms.removeAll();
    299 });
    300 
    301 add_task(async function testBlockedAll() {
    302  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED_ALL);
    303 
    304  await BrowserTestUtils.withNewTab("about:home", async function (browser) {
    305    await blockedIconHidden();
    306    BrowserTestUtils.startLoadingURIString(browser, MUTED_AUTOPLAY_PAGE);
    307    await blockedIconShown();
    308 
    309    await openPermissionPopup();
    310 
    311    Assert.equal(
    312      permissionListBlockedIcons().length,
    313      1,
    314      "Blocked icon is shown"
    315    );
    316 
    317    let menulist = document.getElementById("permission-popup-menulist");
    318    await EventUtils.synthesizeMouseAtCenter(menulist, { type: "mousedown" });
    319    await TestUtils.waitForCondition(() => {
    320      return (
    321        menulist.getElementsByTagName("menuitem")[1].label === "Block Audio"
    322      );
    323    });
    324 
    325    let menuitem = menulist.getElementsByTagName("menuitem")[0];
    326    menuitem.click();
    327    menulist.menupopup.hidePopup();
    328    await closePermissionPopup();
    329    gBrowser.reload();
    330    await blockedIconHidden();
    331  });
    332  Services.perms.removeAll();
    333 });
    334 
    335 add_task(async function testMultiplePlayNotificationsFromJS() {
    336  Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
    337 
    338  await BrowserTestUtils.withNewTab("about:home", async function (browser) {
    339    let count = 0;
    340    browser.addEventListener("GloballyAutoplayBlocked", function () {
    341      is(++count, 1, "Shouldn't get more than one autoplay blocked event");
    342    });
    343 
    344    await blockedIconHidden();
    345 
    346    BrowserTestUtils.startLoadingURIString(browser, AUTOPLAY_JS_PAGE);
    347 
    348    await blockedIconShown();
    349 
    350    // Sleep here a bit to ensure that multiple events don't arrive.
    351    await sleep(100);
    352 
    353    is(count, 1, "Shouldn't have got more events");
    354  });
    355 
    356  Services.perms.removeAll();
    357 });