tor-browser

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

browser_popupNotification.js (12344B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // These are shared between test #4 to #5
      6 var wrongBrowserNotificationObject = new BasicNotification("wrongBrowser");
      7 var wrongBrowserNotification;
      8 
      9 function test() {
     10  waitForExplicitFinish();
     11 
     12  ok(PopupNotifications, "PopupNotifications object exists");
     13  ok(PopupNotifications.panel, "PopupNotifications panel exists");
     14 
     15  setup();
     16 }
     17 
     18 var tests = [
     19  {
     20    id: "Test#1",
     21    run() {
     22      this.notifyObj = new BasicNotification(this.id);
     23      showNotification(this.notifyObj);
     24    },
     25    onShown(popup) {
     26      checkPopup(popup, this.notifyObj);
     27      triggerMainCommand(popup);
     28    },
     29    onHidden() {
     30      ok(this.notifyObj.mainActionClicked, "mainAction was clicked");
     31      ok(
     32        !this.notifyObj.dismissalCallbackTriggered,
     33        "dismissal callback wasn't triggered"
     34      );
     35      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
     36      is(
     37        this.notifyObj.mainActionSource,
     38        "button",
     39        "main action should have been triggered by button."
     40      );
     41      is(
     42        this.notifyObj.secondaryActionSource,
     43        undefined,
     44        "shouldn't have a secondary action source."
     45      );
     46    },
     47  },
     48  {
     49    id: "Test#2",
     50    run() {
     51      this.notifyObj = new BasicNotification(this.id);
     52      showNotification(this.notifyObj);
     53    },
     54    onShown(popup) {
     55      checkPopup(popup, this.notifyObj);
     56      triggerSecondaryCommand(popup, 0);
     57    },
     58    onHidden() {
     59      ok(this.notifyObj.secondaryActionClicked, "secondaryAction was clicked");
     60      ok(
     61        !this.notifyObj.dismissalCallbackTriggered,
     62        "dismissal callback wasn't triggered"
     63      );
     64      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
     65      is(
     66        this.notifyObj.mainActionSource,
     67        undefined,
     68        "shouldn't have a main action source."
     69      );
     70      is(
     71        this.notifyObj.secondaryActionSource,
     72        "button",
     73        "secondary action should have been triggered by button."
     74      );
     75    },
     76  },
     77  {
     78    id: "Test#2b",
     79    run() {
     80      this.notifyObj = new BasicNotification(this.id);
     81      this.notifyObj.secondaryActions.push({
     82        label: "Extra Secondary Action",
     83        accessKey: "E",
     84        callback: () => (this.extraSecondaryActionClicked = true),
     85      });
     86      showNotification(this.notifyObj);
     87    },
     88    onShown(popup) {
     89      checkPopup(popup, this.notifyObj);
     90      triggerSecondaryCommand(popup, 1);
     91    },
     92    onHidden() {
     93      ok(
     94        this.extraSecondaryActionClicked,
     95        "extra secondary action was clicked"
     96      );
     97      ok(
     98        !this.notifyObj.dismissalCallbackTriggered,
     99        "dismissal callback wasn't triggered"
    100      );
    101      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
    102    },
    103  },
    104  {
    105    id: "Test#2c",
    106    run() {
    107      this.notifyObj = new BasicNotification(this.id);
    108      this.notifyObj.secondaryActions.push(
    109        {
    110          label: "Extra Secondary Action",
    111          accessKey: "E",
    112          callback: () => ok(false, "unexpected callback invocation"),
    113        },
    114        {
    115          label: "Other Extra Secondary Action",
    116          accessKey: "O",
    117          callback: () => (this.extraSecondaryActionClicked = true),
    118        }
    119      );
    120      showNotification(this.notifyObj);
    121    },
    122    onShown(popup) {
    123      checkPopup(popup, this.notifyObj);
    124      triggerSecondaryCommand(popup, 2);
    125    },
    126    onHidden() {
    127      ok(
    128        this.extraSecondaryActionClicked,
    129        "extra secondary action was clicked"
    130      );
    131      ok(
    132        !this.notifyObj.dismissalCallbackTriggered,
    133        "dismissal callback wasn't triggered"
    134      );
    135      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
    136    },
    137  },
    138  {
    139    id: "Test#3",
    140    run() {
    141      this.notifyObj = new BasicNotification(this.id);
    142      this.notification = showNotification(this.notifyObj);
    143    },
    144    onShown(popup) {
    145      checkPopup(popup, this.notifyObj);
    146      dismissNotification(popup);
    147    },
    148    onHidden() {
    149      ok(
    150        this.notifyObj.dismissalCallbackTriggered,
    151        "dismissal callback triggered"
    152      );
    153      this.notification.remove();
    154      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
    155    },
    156  },
    157  // test opening a notification for a background browser
    158  // Note: test 4 to 6 share a tab.
    159  {
    160    id: "Test#4",
    161    async run() {
    162      // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    163      let tab = BrowserTestUtils.addTab(gBrowser, "http://example.com/");
    164      await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
    165      isnot(gBrowser.selectedTab, tab, "new tab isn't selected");
    166      wrongBrowserNotificationObject.browser = gBrowser.getBrowserForTab(tab);
    167      let promiseTopic = TestUtils.topicObserved(
    168        "PopupNotifications-backgroundShow"
    169      );
    170      wrongBrowserNotification = showNotification(
    171        wrongBrowserNotificationObject
    172      );
    173      await promiseTopic;
    174      is(PopupNotifications.isPanelOpen, false, "panel isn't open");
    175      ok(
    176        !wrongBrowserNotificationObject.mainActionClicked,
    177        "main action wasn't clicked"
    178      );
    179      ok(
    180        !wrongBrowserNotificationObject.secondaryActionClicked,
    181        "secondary action wasn't clicked"
    182      );
    183      ok(
    184        !wrongBrowserNotificationObject.dismissalCallbackTriggered,
    185        "dismissal callback wasn't called"
    186      );
    187      goNext();
    188    },
    189  },
    190  // now select that browser and test to see that the notification appeared
    191  {
    192    id: "Test#5",
    193    run() {
    194      this.oldSelectedTab = gBrowser.selectedTab;
    195      gBrowser.selectedTab = gBrowser.tabs[gBrowser.tabs.length - 1];
    196    },
    197    onShown(popup) {
    198      checkPopup(popup, wrongBrowserNotificationObject);
    199      is(
    200        PopupNotifications.isPanelOpen,
    201        true,
    202        "isPanelOpen getter doesn't lie"
    203      );
    204 
    205      // switch back to the old browser
    206      gBrowser.selectedTab = this.oldSelectedTab;
    207    },
    208    onHidden() {
    209      // actually remove the notification to prevent it from reappearing
    210      ok(
    211        wrongBrowserNotificationObject.dismissalCallbackTriggered,
    212        "dismissal callback triggered due to tab switch"
    213      );
    214      wrongBrowserNotification.remove();
    215      ok(
    216        wrongBrowserNotificationObject.removedCallbackTriggered,
    217        "removed callback triggered"
    218      );
    219      wrongBrowserNotification = null;
    220    },
    221  },
    222  // test that the removed notification isn't shown on browser re-select
    223  {
    224    id: "Test#6",
    225    async run() {
    226      let promiseTopic = TestUtils.topicObserved(
    227        "PopupNotifications-updateNotShowing"
    228      );
    229      gBrowser.selectedTab = gBrowser.tabs[gBrowser.tabs.length - 1];
    230      await promiseTopic;
    231      is(PopupNotifications.isPanelOpen, false, "panel isn't open");
    232      gBrowser.removeTab(gBrowser.selectedTab);
    233      goNext();
    234    },
    235  },
    236  // Test that two notifications with the same ID result in a single displayed
    237  // notification.
    238  {
    239    id: "Test#7",
    240    run() {
    241      this.notifyObj = new BasicNotification(this.id);
    242      // Show the same notification twice
    243      this.notification1 = showNotification(this.notifyObj);
    244      this.notification2 = showNotification(this.notifyObj);
    245    },
    246    onShown(popup) {
    247      checkPopup(popup, this.notifyObj);
    248      this.notification2.remove();
    249    },
    250    onHidden() {
    251      ok(
    252        !this.notifyObj.dismissalCallbackTriggered,
    253        "dismissal callback wasn't triggered"
    254      );
    255      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
    256    },
    257  },
    258  // Test that two notifications with different IDs are displayed
    259  {
    260    id: "Test#8",
    261    run() {
    262      this.testNotif1 = new BasicNotification(this.id);
    263      this.testNotif1.message += " 1";
    264      showNotification(this.testNotif1);
    265      this.testNotif2 = new BasicNotification(this.id);
    266      this.testNotif2.message += " 2";
    267      this.testNotif2.id += "-2";
    268      showNotification(this.testNotif2);
    269    },
    270    onShown(popup) {
    271      is(popup.children.length, 2, "two notifications are shown");
    272      // Trigger the main command for the first notification, and the secondary
    273      // for the second. Need to do mainCommand first since the secondaryCommand
    274      // triggering is async.
    275      triggerMainCommand(popup);
    276      is(popup.children.length, 1, "only one notification left");
    277      triggerSecondaryCommand(popup, 0);
    278    },
    279    onHidden() {
    280      ok(this.testNotif1.mainActionClicked, "main action #1 was clicked");
    281      ok(
    282        !this.testNotif1.secondaryActionClicked,
    283        "secondary action #1 wasn't clicked"
    284      );
    285      ok(
    286        !this.testNotif1.dismissalCallbackTriggered,
    287        "dismissal callback #1 wasn't called"
    288      );
    289 
    290      ok(!this.testNotif2.mainActionClicked, "main action #2 wasn't clicked");
    291      ok(
    292        this.testNotif2.secondaryActionClicked,
    293        "secondary action #2 was clicked"
    294      );
    295      ok(
    296        !this.testNotif2.dismissalCallbackTriggered,
    297        "dismissal callback #2 wasn't called"
    298      );
    299    },
    300  },
    301  // Test notification without mainAction or secondaryActions, it should fall back
    302  // to a default button that dismisses the notification in place of the main action.
    303  {
    304    id: "Test#9",
    305    run() {
    306      this.notifyObj = new BasicNotification(this.id);
    307      this.notifyObj.mainAction = null;
    308      this.notifyObj.secondaryActions = null;
    309      this.notification = showNotification(this.notifyObj);
    310    },
    311    onShown(popup) {
    312      let notification = popup.children[0];
    313      ok(
    314        notification.hasAttribute("buttonhighlight"),
    315        "default action is highlighted"
    316      );
    317      triggerMainCommand(popup);
    318    },
    319    onHidden() {
    320      ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked");
    321      ok(
    322        !this.notifyObj.dismissalCallbackTriggered,
    323        "dismissal callback wasn't triggered"
    324      );
    325      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
    326    },
    327  },
    328  // Test notification without mainAction but with secondaryActions, it should fall back
    329  // to a default button that dismisses the notification in place of the main action
    330  // and ignore the passed secondaryActions.
    331  {
    332    id: "Test#10",
    333    run() {
    334      this.notifyObj = new BasicNotification(this.id);
    335      this.notifyObj.mainAction = null;
    336      this.notification = showNotification(this.notifyObj);
    337    },
    338    onShown(popup) {
    339      let notification = popup.children[0];
    340      ok(
    341        notification.hasAttribute("secondarybuttonhidden"),
    342        "secondary button is hidden"
    343      );
    344      ok(
    345        notification.hasAttribute("buttonhighlight"),
    346        "default action is highlighted"
    347      );
    348      triggerMainCommand(popup);
    349    },
    350    onHidden() {
    351      ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked");
    352      ok(
    353        !this.notifyObj.dismissalCallbackTriggered,
    354        "dismissal callback wasn't triggered"
    355      );
    356      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
    357    },
    358  },
    359  // Test two notifications with different anchors
    360  {
    361    id: "Test#11",
    362    run() {
    363      this.notifyObj = new BasicNotification(this.id);
    364      this.firstNotification = showNotification(this.notifyObj);
    365      this.notifyObj2 = new BasicNotification(this.id);
    366      this.notifyObj2.id += "-2";
    367      this.notifyObj2.anchorID = "addons-notification-icon";
    368      // Second showNotification() overrides the first
    369      this.secondNotification = showNotification(this.notifyObj2);
    370    },
    371    onShown(popup) {
    372      // This also checks that only one element is shown.
    373      checkPopup(popup, this.notifyObj2);
    374      is(
    375        document.getElementById("geo-notification-icon").getBoundingClientRect()
    376          .width,
    377        0,
    378        "geo anchor shouldn't be visible"
    379      );
    380      dismissNotification(popup);
    381    },
    382    onHidden() {
    383      // Remove the notifications
    384      this.firstNotification.remove();
    385      this.secondNotification.remove();
    386      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
    387      ok(
    388        this.notifyObj2.removedCallbackTriggered,
    389        "removed callback triggered"
    390      );
    391    },
    392  },
    393 ];