tor-browser

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

browser_notification_silencing.js (6868B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const TEST_ROOT = getRootDirectory(gTestPath).replace(
      7  "chrome://mochitests/content/",
      8  "https://example.com/"
      9 );
     10 const TEST_PAGE = TEST_ROOT + "get_user_media.html";
     11 
     12 /**
     13 * Tests that the screen / window sharing permission popup offers the ability
     14 * for users to silence DOM notifications while sharing.
     15 */
     16 
     17 /**
     18 * Helper function that exercises a specific browser to test whether or not the
     19 * user can silence notifications via the display sharing permission panel.
     20 *
     21 * First, we ensure that notification silencing is disabled by default. Then, we
     22 * request screen sharing from the browser, and check the checkbox that
     23 * silences notifications. Once screen sharing is established, then we ensure
     24 * that notification silencing is enabled. Then we stop sharing, and ensure that
     25 * notification silencing is disabled again.
     26 *
     27 * @param {<xul:browser>} aBrowser - The window to run the test on. This browser
     28 *   should have TEST_PAGE loaded.
     29 * @returns {Promise<void>}
     30 *   Resolves when the test on the browser is complete.
     31 */
     32 async function testNotificationSilencing(aBrowser) {
     33  let hasIndicator = Services.wm
     34    .getEnumerator("Browser:WebRTCGlobalIndicator")
     35    .hasMoreElements();
     36 
     37  let window = aBrowser.ownerGlobal;
     38 
     39  let alertsService = Cc["@mozilla.org/alerts-service;1"]
     40    .getService(Ci.nsIAlertsService)
     41    .QueryInterface(Ci.nsIAlertsDoNotDisturb);
     42  Assert.ok(alertsService, "Alerts Service implements nsIAlertsDoNotDisturb");
     43  Assert.ok(
     44    !alertsService.suppressForScreenSharing,
     45    "Should not be silencing notifications to start."
     46  );
     47 
     48  let observerPromise = expectObserverCalled(
     49    "getUserMedia:request",
     50    1,
     51    aBrowser
     52  );
     53  let promise = promisePopupNotificationShown(
     54    "webRTC-shareDevices",
     55    null,
     56    window
     57  );
     58  let indicatorPromise = hasIndicator
     59    ? Promise.resolve()
     60    : promiseIndicatorWindow();
     61  await promiseRequestDevice(false, true, null, "screen", aBrowser);
     62  await promise;
     63  await observerPromise;
     64 
     65  checkDeviceSelectors(["screen"], window);
     66 
     67  let document = window.document;
     68 
     69  // Select one of the windows / screens. It doesn't really matter which.
     70  let menulist = document.getElementById("webRTC-selectWindow-menulist");
     71  menulist.getItemAtIndex(menulist.itemCount - 1).doCommand();
     72 
     73  let notification = window.PopupNotifications.panel.firstElementChild;
     74  Assert.ok(
     75    notification.hasAttribute("warninghidden"),
     76    "Notification silencing warning message is hidden by default"
     77  );
     78 
     79  let checkbox = notification.checkbox;
     80  Assert.ok(!!checkbox, "Notification silencing checkbox is present");
     81  Assert.ok(!checkbox.checked, "checkbox is not checked by default");
     82  checkbox.click();
     83  Assert.ok(checkbox.checked, "checkbox now checked");
     84  // The orginal behaviour of the checkbox disabled the Allow button. Let's
     85  // make sure we're not still doing that.
     86  Assert.ok(!notification.button.disabled, "Allow button is not disabled");
     87  Assert.ok(
     88    notification.hasAttribute("warninghidden"),
     89    "No warning message is shown"
     90  );
     91 
     92  let observerPromise1 = expectObserverCalled(
     93    "getUserMedia:response:allow",
     94    1,
     95    aBrowser
     96  );
     97  let observerPromise2 = expectObserverCalled(
     98    "recording-device-events",
     99    1,
    100    aBrowser
    101  );
    102  await promiseMessage(
    103    "ok",
    104    () => {
    105      notification.button.click();
    106    },
    107    1,
    108    aBrowser
    109  );
    110  await observerPromise1;
    111  await observerPromise2;
    112  let indicator = await indicatorPromise;
    113 
    114  Assert.ok(
    115    alertsService.suppressForScreenSharing,
    116    "Should now be silencing notifications"
    117  );
    118 
    119  let indicatorClosedPromise = hasIndicator
    120    ? Promise.resolve()
    121    : BrowserTestUtils.domWindowClosed(indicator);
    122 
    123  await stopSharing("screen", true, aBrowser, window);
    124  await indicatorClosedPromise;
    125 
    126  Assert.ok(
    127    !alertsService.suppressForScreenSharing,
    128    "Should no longer be silencing notifications"
    129  );
    130 }
    131 
    132 add_setup(async function () {
    133  // Set prefs so that permissions prompts are shown and loopback devices
    134  // are not used. To test the chrome we want prompts to be shown, and
    135  // these tests are flakey when using loopback devices (though it would
    136  // be desirable to make them work with loopback in future). See bug 1643711.
    137  let prefs = [
    138    [PREF_PERMISSION_FAKE, true],
    139    [PREF_AUDIO_LOOPBACK, ""],
    140    [PREF_VIDEO_LOOPBACK, ""],
    141    [PREF_FAKE_STREAMS, true],
    142    [PREF_FOCUS_SOURCE, false],
    143  ];
    144 
    145  await SpecialPowers.pushPrefEnv({ set: prefs });
    146 });
    147 
    148 /**
    149 * Tests notification silencing in a normal browser window.
    150 */
    151 add_task(async function testNormalWindow() {
    152  await BrowserTestUtils.withNewTab(
    153    {
    154      gBrowser,
    155      url: TEST_PAGE,
    156    },
    157    async browser => {
    158      await testNotificationSilencing(browser);
    159    }
    160  );
    161 });
    162 
    163 /**
    164 * Tests notification silencing in a private browser window.
    165 */
    166 add_task(async function testPrivateWindow() {
    167  let privateWindow = await BrowserTestUtils.openNewBrowserWindow({
    168    private: true,
    169  });
    170  await BrowserTestUtils.withNewTab(
    171    {
    172      gBrowser: privateWindow.gBrowser,
    173      url: TEST_PAGE,
    174    },
    175    async browser => {
    176      await testNotificationSilencing(browser);
    177    }
    178  );
    179 
    180  await BrowserTestUtils.closeWindow(privateWindow);
    181 });
    182 
    183 /**
    184 * Tests notification silencing when sharing a screen while already
    185 * sharing the microphone. Alone ensures that if we stop sharing the
    186 * screen, but continue sharing the microphone, that notification
    187 * silencing ends.
    188 */
    189 add_task(async function testWhileSharingMic() {
    190  await BrowserTestUtils.withNewTab(
    191    {
    192      gBrowser,
    193      url: TEST_PAGE,
    194    },
    195    async browser => {
    196      let promise = promisePopupNotificationShown("webRTC-shareDevices");
    197      let observerPromise = expectObserverCalled("getUserMedia:request");
    198      await promiseRequestDevice(true, true);
    199      await promise;
    200      await observerPromise;
    201 
    202      let indicatorPromise = promiseIndicatorWindow();
    203      let observerPromise1 = expectObserverCalled(
    204        "getUserMedia:response:allow"
    205      );
    206      let observerPromise2 = expectObserverCalled("recording-device-events");
    207 
    208      promise = promiseMessage("ok", () => {
    209        PopupNotifications.panel.firstElementChild.button.click();
    210      });
    211      await observerPromise1;
    212      await observerPromise2;
    213      await promise;
    214 
    215      Assert.deepEqual(
    216        await getMediaCaptureState(),
    217        { audio: true, video: true },
    218        "expected camera and microphone to be shared"
    219      );
    220 
    221      let indicator = await indicatorPromise;
    222      await checkSharingUI({ audio: true, video: true });
    223 
    224      await testNotificationSilencing(browser);
    225 
    226      let indicatorClosedPromise = BrowserTestUtils.domWindowClosed(indicator);
    227      await closeStream();
    228      await indicatorClosedPromise;
    229    }
    230  );
    231 });