tor-browser

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

browser_fullscreen_permissions_prompt.js (8345B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const { PromiseTestUtils } = ChromeUtils.importESModule(
      7  "resource://testing-common/PromiseTestUtils.sys.mjs"
      8 );
      9 PromiseTestUtils.allowMatchingRejectionsGlobally(/Not in fullscreen mode/);
     10 
     11 SimpleTest.requestCompleteLog();
     12 
     13 async function requestNotificationPermission(browser) {
     14  return SpecialPowers.spawn(browser, [], () => {
     15    return content.Notification.requestPermission();
     16  });
     17 }
     18 
     19 async function requestCameraPermission(browser) {
     20  return SpecialPowers.spawn(browser, [], () =>
     21    content.navigator.mediaDevices
     22      .getUserMedia({ video: true, fake: true })
     23      .then(
     24        () => true,
     25        () => false
     26      )
     27  );
     28 }
     29 
     30 add_task(async function test_fullscreen_closes_permissionui_prompt() {
     31  await SpecialPowers.pushPrefEnv({
     32    set: [
     33      ["dom.webnotifications.requireuserinteraction", false],
     34      ["permissions.fullscreen.allowed", false],
     35    ],
     36  });
     37 
     38  let tab = await BrowserTestUtils.openNewForegroundTab(
     39    gBrowser,
     40    "https://example.com"
     41  );
     42  let browser = tab.linkedBrowser;
     43 
     44  let popupShown, requestResult, popupHidden;
     45 
     46  popupShown = BrowserTestUtils.waitForEvent(
     47    window.PopupNotifications.panel,
     48    "popupshown"
     49  );
     50 
     51  info("Requesting notification permission");
     52  requestResult = requestNotificationPermission(browser);
     53  await popupShown;
     54 
     55  info("Entering DOM full-screen");
     56  popupHidden = BrowserTestUtils.waitForEvent(
     57    window.PopupNotifications.panel,
     58    "popuphidden"
     59  );
     60 
     61  await DOMFullscreenTestUtils.changeFullscreen(browser, true);
     62 
     63  await popupHidden;
     64 
     65  is(
     66    await requestResult,
     67    "default",
     68    "Expect permission request to be cancelled"
     69  );
     70 
     71  await DOMFullscreenTestUtils.changeFullscreen(browser, false);
     72 
     73  BrowserTestUtils.removeTab(tab);
     74  await SpecialPowers.popPrefEnv();
     75 });
     76 
     77 add_task(async function test_fullscreen_closes_webrtc_permission_prompt() {
     78  await SpecialPowers.pushPrefEnv({
     79    set: [
     80      ["media.navigator.permission.fake", true],
     81      ["media.navigator.permission.force", true],
     82      ["permissions.fullscreen.allowed", false],
     83    ],
     84  });
     85 
     86  let tab = await BrowserTestUtils.openNewForegroundTab(
     87    gBrowser,
     88    "https://example.com"
     89  );
     90  let browser = tab.linkedBrowser;
     91  let popupShown, requestResult, popupHidden;
     92 
     93  popupShown = BrowserTestUtils.waitForEvent(
     94    window.PopupNotifications.panel,
     95    "popupshown"
     96  );
     97 
     98  info("Requesting camera permission");
     99  requestResult = requestCameraPermission(browser);
    100 
    101  await popupShown;
    102 
    103  info("Entering DOM full-screen");
    104  popupHidden = BrowserTestUtils.waitForEvent(
    105    window.PopupNotifications.panel,
    106    "popuphidden"
    107  );
    108  await DOMFullscreenTestUtils.changeFullscreen(browser, true);
    109 
    110  await popupHidden;
    111 
    112  is(
    113    await requestResult,
    114    false,
    115    "Expect webrtc permission request to be cancelled"
    116  );
    117 
    118  await DOMFullscreenTestUtils.changeFullscreen(browser, false);
    119 
    120  BrowserTestUtils.removeTab(tab);
    121  await SpecialPowers.popPrefEnv();
    122 });
    123 
    124 add_task(async function test_permission_prompt_closes_fullscreen() {
    125  await SpecialPowers.pushPrefEnv({
    126    set: [
    127      ["dom.webnotifications.requireuserinteraction", false],
    128      ["permissions.fullscreen.allowed", false],
    129    ],
    130  });
    131 
    132  let tab = await BrowserTestUtils.openNewForegroundTab(
    133    gBrowser,
    134    "https://example.com"
    135  );
    136  let browser = tab.linkedBrowser;
    137  info("Entering DOM full-screen");
    138  await DOMFullscreenTestUtils.changeFullscreen(browser, true);
    139 
    140  let popupShown = BrowserTestUtils.waitForEvent(
    141    window.PopupNotifications.panel,
    142    "popupshown"
    143  );
    144  let fullScreenExit = DOMFullscreenTestUtils.waitForFullScreenState(
    145    browser,
    146    false
    147  );
    148 
    149  info("Requesting notification permission");
    150  requestNotificationPermission(browser).catch(() => {});
    151  await popupShown;
    152 
    153  info("Waiting for full-screen exit");
    154  await fullScreenExit;
    155 
    156  BrowserTestUtils.removeTab(tab);
    157  await SpecialPowers.popPrefEnv();
    158 });
    159 
    160 function triggerMainCommand(popup) {
    161  let notifications = popup.childNodes;
    162  ok(!!notifications.length, "at least one notification displayed");
    163  let notification = notifications[0];
    164  info("Triggering main command for notification " + notification.id);
    165  EventUtils.synthesizeMouseAtCenter(notification.button, {});
    166 }
    167 
    168 add_task(
    169  async function test_permission_prompt_closes_fullscreen_and_extends_security_delay() {
    170    const TEST_SECURITY_DELAY = 500;
    171    await SpecialPowers.pushPrefEnv({
    172      set: [
    173        ["dom.webnotifications.requireuserinteraction", false],
    174        ["permissions.fullscreen.allowed", false],
    175        ["security.notification_enable_delay", TEST_SECURITY_DELAY],
    176        // macOS is not affected by the sec delay bug because it uses the native
    177        // macOS full screen API. Revert back to legacy behavior so we can also
    178        // test on macOS. If this pref is removed in the future we can consider
    179        // skipping the testcase for macOS altogether.
    180        ["full-screen-api.macos-native-full-screen", false],
    181      ],
    182    });
    183 
    184    let tab = await BrowserTestUtils.openNewForegroundTab(
    185      gBrowser,
    186      "https://example.com"
    187    );
    188    let browser = tab.linkedBrowser;
    189    info("Entering DOM full-screen");
    190    await DOMFullscreenTestUtils.changeFullscreen(browser, true);
    191 
    192    let popupShown = BrowserTestUtils.waitForPopupEvent(
    193      window.PopupNotifications.panel,
    194      "shown"
    195    );
    196    let fullScreenExit = DOMFullscreenTestUtils.waitForFullScreenState(
    197      browser,
    198      false
    199    );
    200 
    201    info("Requesting notification permission");
    202    requestNotificationPermission(browser).catch(() => {});
    203    await popupShown;
    204 
    205    let notificationHiddenPromise = BrowserTestUtils.waitForPopupEvent(
    206      window.PopupNotifications.panel,
    207      "hidden"
    208    );
    209 
    210    info("Waiting for full-screen exit");
    211    await fullScreenExit;
    212 
    213    info("Wait for original security delay to expire.");
    214    SimpleTest.requestFlakyTimeout(
    215      "Wait for original security delay to expire."
    216    );
    217    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    218    await new Promise(resolve => setTimeout(resolve, TEST_SECURITY_DELAY));
    219 
    220    info(
    221      "Trigger main action via button click during the extended security delay"
    222    );
    223    triggerMainCommand(PopupNotifications.panel);
    224 
    225    let notification = PopupNotifications.getNotification(
    226      "web-notifications",
    227      gBrowser.selectedBrowser
    228    );
    229 
    230    // Linux in CI seems to skip the full screen animation, which means its not
    231    // affected by the bug and we can't test extension of the sec delay here.
    232    if (Services.appinfo.OS == "Linux") {
    233      // skip this, intermittent passing on Ubuntu 24.04
    234    } else {
    235      ok(
    236        notification &&
    237          !notification.dismissed &&
    238          BrowserTestUtils.isVisible(PopupNotifications.panel.firstChild),
    239        "Notification should still be open because we clicked during the security delay."
    240      );
    241    }
    242 
    243    // If the notification is no longer shown (test failure) skip the remaining
    244    // checks.
    245    if (!notification) {
    246      // Cleanup
    247      BrowserTestUtils.removeTab(tab);
    248      await SpecialPowers.popPrefEnv();
    249      // Remove the granted notification permission.
    250      Services.perms.removeAll();
    251      return;
    252    }
    253 
    254    Assert.greater(
    255      notification.timeShown,
    256      performance.now(),
    257      "Notification timeShown property should be in the future, because the security delay was extended."
    258    );
    259 
    260    // Ensure that once the security delay has passed the notification can be
    261    // closed again.
    262    let fakeTimeShown = TEST_SECURITY_DELAY + 500;
    263    info(`Manually set timeShown to ${fakeTimeShown}ms in the past.`);
    264    notification.timeShown = performance.now() - fakeTimeShown;
    265 
    266    info("Trigger main action via button click outside security delay");
    267    triggerMainCommand(PopupNotifications.panel);
    268 
    269    info("Wait for panel to be hidden.");
    270    await notificationHiddenPromise;
    271 
    272    ok(
    273      !PopupNotifications.getNotification(
    274        "web-notifications",
    275        gBrowser.selectedBrowser
    276      ),
    277      "Should not longer see the notification."
    278    );
    279 
    280    // Cleanup
    281    BrowserTestUtils.removeTab(tab);
    282    await SpecialPowers.popPrefEnv();
    283    // Remove the granted notification permission.
    284    Services.perms.removeAll();
    285  }
    286 );