tor-browser

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

browser_panelUINotifications.js (16593B)


      1 "use strict";
      2 
      3 const { AppMenuNotifications } = ChromeUtils.importESModule(
      4  "resource://gre/modules/AppMenuNotifications.sys.mjs"
      5 );
      6 
      7 /**
      8 * Tests that when we click on the main call-to-action of the doorhanger, the provided
      9 * action is called, and the doorhanger removed.
     10 */
     11 add_task(async function testMainActionCalled() {
     12  let options = {
     13    gBrowser: window.gBrowser,
     14    url: "about:blank",
     15  };
     16 
     17  await BrowserTestUtils.withNewTab(options, function () {
     18    is(
     19      PanelUI.notificationPanel.state,
     20      "closed",
     21      "update-manual doorhanger is closed."
     22    );
     23    let mainActionCalled = false;
     24    let mainAction = {
     25      callback: () => {
     26        mainActionCalled = true;
     27      },
     28    };
     29    AppMenuNotifications.showNotification("update-manual", mainAction);
     30 
     31    isnot(
     32      PanelUI.notificationPanel.state,
     33      "closed",
     34      "update-manual doorhanger is showing."
     35    );
     36    let notifications = [...PanelUI.notificationPanel.children].filter(
     37      n => !n.hidden
     38    );
     39    is(
     40      notifications.length,
     41      1,
     42      "PanelUI doorhanger is only displaying one notification."
     43    );
     44    let doorhanger = notifications[0];
     45    is(
     46      doorhanger.id,
     47      "appMenu-update-manual-notification",
     48      "PanelUI is displaying the update-manual notification."
     49    );
     50 
     51    let button = doorhanger.button;
     52    button.click();
     53 
     54    ok(mainActionCalled, "Main action callback was called");
     55    is(
     56      PanelUI.notificationPanel.state,
     57      "closed",
     58      "update-manual doorhanger is closed."
     59    );
     60    is(
     61      PanelUI.menuButton.hasAttribute("badge-status"),
     62      false,
     63      "Should not have a badge status"
     64    );
     65  });
     66 });
     67 
     68 /**
     69 * This tests that when we click the secondary action for a notification,
     70 * it will display the badge for that notification on the PanelUI menu button.
     71 * Once we click on this button, we should see an item in the menu which will
     72 * call our main action.
     73 */
     74 add_task(async function testSecondaryActionWorkflow() {
     75  let options = {
     76    gBrowser: window.gBrowser,
     77    url: "about:blank",
     78  };
     79 
     80  await BrowserTestUtils.withNewTab(options, async function () {
     81    is(
     82      PanelUI.notificationPanel.state,
     83      "closed",
     84      "update-manual doorhanger is closed."
     85    );
     86 
     87    let mainActionCalled = false;
     88    let mainAction = {
     89      callback: () => {
     90        mainActionCalled = true;
     91      },
     92    };
     93    AppMenuNotifications.showNotification("update-manual", mainAction);
     94 
     95    isnot(
     96      PanelUI.notificationPanel.state,
     97      "closed",
     98      "update-manual doorhanger is showing."
     99    );
    100    let notifications = [...PanelUI.notificationPanel.children].filter(
    101      n => !n.hidden
    102    );
    103    is(
    104      notifications.length,
    105      1,
    106      "PanelUI doorhanger is only displaying one notification."
    107    );
    108    let doorhanger = notifications[0];
    109    is(
    110      doorhanger.id,
    111      "appMenu-update-manual-notification",
    112      "PanelUI is displaying the update-manual notification."
    113    );
    114 
    115    let secondaryActionButton = doorhanger.secondaryButton;
    116    secondaryActionButton.click();
    117 
    118    is(
    119      PanelUI.notificationPanel.state,
    120      "closed",
    121      "update-manual doorhanger is closed."
    122    );
    123 
    124    is(
    125      PanelUI.menuButton.getAttribute("badge-status"),
    126      "update-manual",
    127      "Badge is displaying on PanelUI button."
    128    );
    129 
    130    await gCUITestUtils.openMainMenu();
    131    is(
    132      PanelUI.menuButton.getAttribute("badge-status"),
    133      "update-manual",
    134      "Badge is displaying on PanelUI button."
    135    );
    136    let menuItem = PanelUI.mainView.querySelector(".panel-banner-item");
    137    is(
    138      menuItem.getAttribute("data-l10n-id"),
    139      "appmenuitem-banner-update-manual",
    140      "Showing correct label"
    141    );
    142    is(menuItem.hidden, false, "update-manual menu item is showing.");
    143 
    144    await gCUITestUtils.hideMainMenu();
    145    is(
    146      PanelUI.menuButton.getAttribute("badge-status"),
    147      "update-manual",
    148      "Badge is shown on PanelUI button."
    149    );
    150 
    151    await gCUITestUtils.openMainMenu();
    152    menuItem.click();
    153    ok(mainActionCalled, "Main action callback was called");
    154 
    155    AppMenuNotifications.removeNotification(/.*/);
    156  });
    157 });
    158 
    159 /**
    160 * This tests that the PanelUI update downloading badge and banner
    161 * notification are correctly displayed and that clicking the banner
    162 * item calls the main action.
    163 */
    164 add_task(async function testDownloadingBadge() {
    165  let options = {
    166    gBrowser: window.gBrowser,
    167    url: "about:blank",
    168  };
    169 
    170  await BrowserTestUtils.withNewTab(options, async function () {
    171    let mainActionCalled = false;
    172    let mainAction = {
    173      callback: () => {
    174        mainActionCalled = true;
    175      },
    176    };
    177    // The downloading notification is always displayed in a dismissed state.
    178    AppMenuNotifications.showNotification(
    179      "update-downloading",
    180      mainAction,
    181      undefined,
    182      { dismissed: true }
    183    );
    184    is(PanelUI.notificationPanel.state, "closed", "doorhanger is closed.");
    185 
    186    is(
    187      PanelUI.menuButton.getAttribute("badge-status"),
    188      "update-downloading",
    189      "Downloading badge is displaying on PanelUI button."
    190    );
    191 
    192    await gCUITestUtils.openMainMenu();
    193    is(
    194      PanelUI.menuButton.getAttribute("badge-status"),
    195      "update-downloading",
    196      "Downloading badge is displaying on PanelUI button."
    197    );
    198    let menuItem = PanelUI.mainView.querySelector(".panel-banner-item");
    199    is(
    200      menuItem.getAttribute("data-l10n-id"),
    201      "appmenuitem-banner-update-downloading",
    202      "Showing correct label (downloading)"
    203    );
    204    is(menuItem.hidden, false, "update-downloading menu item is showing.");
    205 
    206    await gCUITestUtils.hideMainMenu();
    207    is(
    208      PanelUI.menuButton.getAttribute("badge-status"),
    209      "update-downloading",
    210      "Downloading badge is shown on PanelUI button."
    211    );
    212 
    213    await gCUITestUtils.openMainMenu();
    214    menuItem.click();
    215    ok(mainActionCalled, "Main action callback was called");
    216 
    217    AppMenuNotifications.removeNotification(/.*/);
    218  });
    219 });
    220 
    221 /**
    222 * We want to ensure a few things with this:
    223 * - Adding a doorhanger will make a badge disappear
    224 * - once the notification for the doorhanger is resolved (removed, not just dismissed),
    225 *   then we display any other badges that are remaining.
    226 */
    227 add_task(async function testInteractionWithBadges() {
    228  await BrowserTestUtils.withNewTab("about:blank", async function () {
    229    // Remove the fxa toolbar button from the navbar to ensure the notification
    230    // is displayed on the app menu button.
    231    let { CustomizableUI } = ChromeUtils.importESModule(
    232      "moz-src:///browser/components/customizableui/CustomizableUI.sys.mjs"
    233    );
    234    CustomizableUI.removeWidgetFromArea("fxa-toolbar-menu-button");
    235 
    236    AppMenuNotifications.showBadgeOnlyNotification("fxa-needs-authentication");
    237    is(
    238      PanelUI.menuButton.getAttribute("badge-status"),
    239      "fxa-needs-authentication",
    240      "Fxa badge is shown on PanelUI button."
    241    );
    242    is(
    243      PanelUI.notificationPanel.state,
    244      "closed",
    245      "update-manual doorhanger is closed."
    246    );
    247 
    248    let mainActionCalled = false;
    249    let mainAction = {
    250      callback: () => {
    251        mainActionCalled = true;
    252      },
    253    };
    254    AppMenuNotifications.showNotification("update-manual", mainAction);
    255 
    256    isnot(
    257      PanelUI.menuButton.getAttribute("badge-status"),
    258      "fxa-needs-authentication",
    259      "Fxa badge is hidden on PanelUI button."
    260    );
    261    isnot(
    262      PanelUI.notificationPanel.state,
    263      "closed",
    264      "update-manual doorhanger is showing."
    265    );
    266    let notifications = [...PanelUI.notificationPanel.children].filter(
    267      n => !n.hidden
    268    );
    269    is(
    270      notifications.length,
    271      1,
    272      "PanelUI doorhanger is only displaying one notification."
    273    );
    274    let doorhanger = notifications[0];
    275    is(
    276      doorhanger.id,
    277      "appMenu-update-manual-notification",
    278      "PanelUI is displaying the update-manual notification."
    279    );
    280 
    281    let secondaryActionButton = doorhanger.secondaryButton;
    282    secondaryActionButton.click();
    283 
    284    is(
    285      PanelUI.notificationPanel.state,
    286      "closed",
    287      "update-manual doorhanger is closed."
    288    );
    289 
    290    is(
    291      PanelUI.menuButton.getAttribute("badge-status"),
    292      "update-manual",
    293      "Badge is displaying on PanelUI button."
    294    );
    295 
    296    await gCUITestUtils.openMainMenu();
    297    is(
    298      PanelUI.menuButton.getAttribute("badge-status"),
    299      "update-manual",
    300      "Badge is displaying on PanelUI button."
    301    );
    302    let menuItem = PanelUI.mainView.querySelector(".panel-banner-item");
    303    is(
    304      menuItem.getAttribute("data-l10n-id"),
    305      "appmenuitem-banner-update-manual",
    306      "Showing correct label"
    307    );
    308    is(menuItem.hidden, false, "update-manual menu item is showing.");
    309 
    310    menuItem.click();
    311    ok(mainActionCalled, "Main action callback was called");
    312 
    313    is(
    314      PanelUI.menuButton.getAttribute("badge-status"),
    315      "fxa-needs-authentication",
    316      "Fxa badge is shown on PanelUI button."
    317    );
    318    AppMenuNotifications.removeNotification(/.*/);
    319    is(
    320      PanelUI.menuButton.hasAttribute("badge-status"),
    321      false,
    322      "Should not have a badge status"
    323    );
    324  });
    325 });
    326 
    327 /**
    328 * This tests that adding a badge will not dismiss any existing doorhangers.
    329 */
    330 add_task(async function testAddingBadgeWhileDoorhangerIsShowing() {
    331  await BrowserTestUtils.withNewTab("about:blank", function () {
    332    is(
    333      PanelUI.notificationPanel.state,
    334      "closed",
    335      "update-manual doorhanger is closed."
    336    );
    337    let mainActionCalled = false;
    338    let mainAction = {
    339      callback: () => {
    340        mainActionCalled = true;
    341      },
    342    };
    343    AppMenuNotifications.showNotification("update-manual", mainAction);
    344    AppMenuNotifications.showBadgeOnlyNotification("fxa-needs-authentication");
    345 
    346    isnot(
    347      PanelUI.menuButton.getAttribute("badge-status"),
    348      "fxa-needs-authentication",
    349      "Fxa badge is hidden on PanelUI button."
    350    );
    351    isnot(
    352      PanelUI.notificationPanel.state,
    353      "closed",
    354      "update-manual doorhanger is showing."
    355    );
    356    let notifications = [...PanelUI.notificationPanel.children].filter(
    357      n => !n.hidden
    358    );
    359    is(
    360      notifications.length,
    361      1,
    362      "PanelUI doorhanger is only displaying one notification."
    363    );
    364    let doorhanger = notifications[0];
    365    is(
    366      doorhanger.id,
    367      "appMenu-update-manual-notification",
    368      "PanelUI is displaying the update-manual notification."
    369    );
    370 
    371    let mainActionButton = doorhanger.button;
    372    mainActionButton.click();
    373 
    374    ok(mainActionCalled, "Main action callback was called");
    375    is(
    376      PanelUI.notificationPanel.state,
    377      "closed",
    378      "update-manual doorhanger is closed."
    379    );
    380    is(
    381      PanelUI.menuButton.getAttribute("badge-status"),
    382      "fxa-needs-authentication",
    383      "Fxa badge is shown on PanelUI button."
    384    );
    385    AppMenuNotifications.removeNotification(/.*/);
    386    is(
    387      PanelUI.menuButton.hasAttribute("badge-status"),
    388      false,
    389      "Should not have a badge status"
    390    );
    391  });
    392 });
    393 
    394 /**
    395 * Tests that badges operate like a stack.
    396 */
    397 add_task(async function testMultipleBadges() {
    398  await BrowserTestUtils.withNewTab("about:blank", async function (browser) {
    399    let doc = browser.ownerDocument;
    400    let menuButton = doc.getElementById("PanelUI-menu-button");
    401 
    402    is(
    403      menuButton.hasAttribute("badge-status"),
    404      false,
    405      "Should not have a badge status"
    406    );
    407    is(
    408      menuButton.hasAttribute("badge"),
    409      false,
    410      "Should not have the badge attribute set"
    411    );
    412 
    413    AppMenuNotifications.showBadgeOnlyNotification("fxa-needs-authentication");
    414    is(
    415      menuButton.getAttribute("badge-status"),
    416      "fxa-needs-authentication",
    417      "Should have fxa-needs-authentication badge status"
    418    );
    419 
    420    AppMenuNotifications.showBadgeOnlyNotification("update-succeeded");
    421    is(
    422      menuButton.getAttribute("badge-status"),
    423      "update-succeeded",
    424      "Should have update-succeeded badge status (update > fxa)"
    425    );
    426 
    427    AppMenuNotifications.showBadgeOnlyNotification("update-failed");
    428    is(
    429      menuButton.getAttribute("badge-status"),
    430      "update-failed",
    431      "Should have update-failed badge status"
    432    );
    433 
    434    AppMenuNotifications.removeNotification(/^update-/);
    435    is(
    436      menuButton.getAttribute("badge-status"),
    437      "fxa-needs-authentication",
    438      "Should have fxa-needs-authentication badge status"
    439    );
    440 
    441    AppMenuNotifications.removeNotification(/^fxa-/);
    442    is(
    443      menuButton.hasAttribute("badge-status"),
    444      false,
    445      "Should not have a badge status"
    446    );
    447 
    448    await gCUITestUtils.openMainMenu();
    449    is(
    450      menuButton.hasAttribute("badge-status"),
    451      false,
    452      "Should not have a badge status (Hamburger menu opened)"
    453    );
    454    await gCUITestUtils.hideMainMenu();
    455 
    456    AppMenuNotifications.showBadgeOnlyNotification("fxa-needs-authentication");
    457    AppMenuNotifications.showBadgeOnlyNotification("update-succeeded");
    458    AppMenuNotifications.removeNotification(/.*/);
    459    is(
    460      menuButton.hasAttribute("badge-status"),
    461      false,
    462      "Should not have a badge status"
    463    );
    464  });
    465 });
    466 
    467 /**
    468 * Tests that non-badges also operate like a stack.
    469 */
    470 add_task(async function testMultipleNonBadges() {
    471  await BrowserTestUtils.withNewTab("about:blank", async function () {
    472    is(
    473      PanelUI.notificationPanel.state,
    474      "closed",
    475      "update-manual doorhanger is closed."
    476    );
    477 
    478    let updateManualAction = {
    479      called: false,
    480      callback: () => {
    481        updateManualAction.called = true;
    482      },
    483    };
    484    let updateRestartAction = {
    485      called: false,
    486      callback: () => {
    487        updateRestartAction.called = true;
    488      },
    489    };
    490 
    491    AppMenuNotifications.showNotification("update-manual", updateManualAction);
    492 
    493    let notifications;
    494    let doorhanger;
    495 
    496    isnot(PanelUI.notificationPanel.state, "closed", "Doorhanger is showing.");
    497    notifications = [...PanelUI.notificationPanel.children].filter(
    498      n => !n.hidden
    499    );
    500    is(
    501      notifications.length,
    502      1,
    503      "PanelUI doorhanger is only displaying one notification."
    504    );
    505    doorhanger = notifications[0];
    506    is(
    507      doorhanger.id,
    508      "appMenu-update-manual-notification",
    509      "PanelUI is displaying the update-manual notification."
    510    );
    511 
    512    AppMenuNotifications.showNotification(
    513      "update-restart",
    514      updateRestartAction
    515    );
    516 
    517    isnot(PanelUI.notificationPanel.state, "closed", "Doorhanger is showing.");
    518    notifications = [...PanelUI.notificationPanel.children].filter(
    519      n => !n.hidden
    520    );
    521    is(
    522      notifications.length,
    523      1,
    524      "PanelUI doorhanger is only displaying one notification."
    525    );
    526    doorhanger = notifications[0];
    527    is(
    528      doorhanger.id,
    529      "appMenu-update-restart-notification",
    530      "PanelUI is displaying the update-restart notification."
    531    );
    532 
    533    let secondaryActionButton = doorhanger.secondaryButton;
    534    secondaryActionButton.click();
    535 
    536    is(
    537      PanelUI.notificationPanel.state,
    538      "closed",
    539      "update-manual doorhanger is closed."
    540    );
    541    is(
    542      PanelUI.menuButton.getAttribute("badge-status"),
    543      "update-restart",
    544      "update-restart badge is displaying on PanelUI button."
    545    );
    546 
    547    await gCUITestUtils.openMainMenu();
    548    is(
    549      PanelUI.menuButton.getAttribute("badge-status"),
    550      "update-restart",
    551      "update-restart badge is displaying on PanelUI button."
    552    );
    553    let menuItem = PanelUI.mainView.querySelector(".panel-banner-item");
    554    is(
    555      menuItem.getAttribute("data-l10n-id"),
    556      "appmenuitem-banner-update-restart",
    557      "Showing correct label"
    558    );
    559    is(menuItem.hidden, false, "update-restart menu item is showing.");
    560 
    561    menuItem.click();
    562    ok(
    563      updateRestartAction.called,
    564      "update-restart main action callback was called"
    565    );
    566 
    567    is(
    568      PanelUI.notificationPanel.state,
    569      "closed",
    570      "update-manual doorhanger is closed."
    571    );
    572    is(
    573      PanelUI.menuButton.getAttribute("badge-status"),
    574      "update-manual",
    575      "update-manual badge is displaying on PanelUI button."
    576    );
    577 
    578    await gCUITestUtils.openMainMenu();
    579    is(
    580      PanelUI.menuButton.getAttribute("badge-status"),
    581      "update-manual",
    582      "update-manual badge is displaying on PanelUI button."
    583    );
    584    is(
    585      menuItem.getAttribute("data-l10n-id"),
    586      "appmenuitem-banner-update-manual",
    587      "Showing correct label"
    588    );
    589    is(menuItem.hidden, false, "update-manual menu item is showing.");
    590 
    591    menuItem.click();
    592    ok(
    593      updateManualAction.called,
    594      "update-manual main action callback was called"
    595    );
    596  });
    597 });