tor-browser

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

browser_active_mediasession_among_tabs.js (6730B)


      1 /* eslint-disable no-undef */
      2 "use strict";
      3 
      4 const PAGE =
      5  "https://example.com/browser/dom/media/mediasession/test/file_media_session.html";
      6 
      7 const ACTION = "previoustrack";
      8 
      9 add_task(async function setupTestingPref() {
     10  await SpecialPowers.pushPrefEnv({
     11    set: [["media.mediacontrol.testingevents.enabled", true]],
     12  });
     13 });
     14 
     15 /**
     16 * When multiple tabs are all having media session, the latest created one would
     17 * become an active session. When the active media session is destroyed via
     18 * closing the tab, the previous active session would become current active
     19 * session again.
     20 */
     21 add_task(async function testActiveSessionWhenClosingTab() {
     22  info(`open tab1 and load media session test page`);
     23  const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
     24  await startMediaPlaybackAndWaitMedisSessionBecomeActiveSession(tab1);
     25 
     26  info(`pressing '${ACTION}' key`);
     27  MediaControlService.generateMediaControlKey(ACTION);
     28 
     29  info(`session in tab1 should become active session`);
     30  await checkIfActionReceived(tab1, ACTION);
     31 
     32  info(`open tab2 and load media session test page`);
     33  const tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
     34  await startMediaPlaybackAndWaitMedisSessionBecomeActiveSession(tab2);
     35 
     36  info(`pressing '${ACTION}' key`);
     37  MediaControlService.generateMediaControlKey(ACTION);
     38 
     39  info(`session in tab2 should become active session`);
     40  await checkIfActionReceived(tab2, ACTION);
     41  await checkIfActionNotReceived(tab1, ACTION);
     42 
     43  info(`remove tab2`);
     44  const controllerChanged = waitUntilMainMediaControllerChanged();
     45  BrowserTestUtils.removeTab(tab2);
     46  await controllerChanged;
     47 
     48  info(`pressing '${ACTION}' key`);
     49  MediaControlService.generateMediaControlKey(ACTION);
     50 
     51  info(`session in tab1 should become active session again`);
     52  await checkIfActionReceived(tab1, ACTION);
     53 
     54  info(`remove tab1`);
     55  BrowserTestUtils.removeTab(tab1);
     56 });
     57 
     58 /**
     59 * This test is similar with `testActiveSessionWhenClosingTab`, the difference
     60 * is that the way we use to destroy active session is via naviagation, not
     61 * closing tab.
     62 */
     63 add_task(async function testActiveSessionWhenNavigatingTab() {
     64  info(`open tab1 and load media session test page`);
     65  const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
     66  await startMediaPlaybackAndWaitMedisSessionBecomeActiveSession(tab1);
     67 
     68  info(`pressing '${ACTION}' key`);
     69  MediaControlService.generateMediaControlKey(ACTION);
     70 
     71  info(`session in tab1 should become active session`);
     72  await checkIfActionReceived(tab1, ACTION);
     73 
     74  info(`open tab2 and load media session test page`);
     75  const tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
     76  await startMediaPlaybackAndWaitMedisSessionBecomeActiveSession(tab2);
     77 
     78  info(`pressing '${ACTION}' key`);
     79  MediaControlService.generateMediaControlKey(ACTION);
     80 
     81  info(`session in tab2 should become active session`);
     82  await checkIfActionReceived(tab2, ACTION);
     83  await checkIfActionNotReceived(tab1, ACTION);
     84 
     85  info(`navigate tab2 to blank page`);
     86  const controllerChanged = waitUntilMainMediaControllerChanged();
     87  BrowserTestUtils.startLoadingURIString(tab2.linkedBrowser, "about:blank");
     88  await controllerChanged;
     89 
     90  info(`pressing '${ACTION}' key`);
     91  MediaControlService.generateMediaControlKey(ACTION);
     92 
     93  info(`session in tab1 should become active session`);
     94  await checkIfActionReceived(tab1, ACTION);
     95 
     96  info(`remove tabs`);
     97  BrowserTestUtils.removeTab(tab1);
     98  BrowserTestUtils.removeTab(tab2);
     99 });
    100 
    101 /**
    102 * If we create a media session in a tab where no any playing media exists, then
    103 * that session would not involve in global active media session selection. The
    104 * current active media session would remain unchanged.
    105 */
    106 add_task(async function testCreatingSessionWithoutPlayingMedia() {
    107  info(`open tab1 and load media session test page`);
    108  const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
    109  await startMediaPlaybackAndWaitMedisSessionBecomeActiveSession(tab1);
    110 
    111  info(`pressing '${ACTION}' key`);
    112  MediaControlService.generateMediaControlKey(ACTION);
    113 
    114  info(`session in tab1 should become active session`);
    115  await checkIfActionReceived(tab1, ACTION);
    116 
    117  info(`open tab2 and load media session test page`);
    118  const tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
    119 
    120  info(`pressing '${ACTION}' key`);
    121  MediaControlService.generateMediaControlKey(ACTION);
    122 
    123  info(
    124    `session in tab1 is still an active session because there is no media playing in tab2`
    125  );
    126  await checkIfActionReceived(tab1, ACTION);
    127  await checkIfActionNotReceived(tab2, ACTION);
    128 
    129  info(`remove tabs`);
    130  BrowserTestUtils.removeTab(tab1);
    131  BrowserTestUtils.removeTab(tab2);
    132 });
    133 
    134 /**
    135 * The following are helper functions
    136 */
    137 async function startMediaPlaybackAndWaitMedisSessionBecomeActiveSession(tab) {
    138  await Promise.all([
    139    BrowserUtils.promiseObserved("active-media-session-changed"),
    140    SpecialPowers.spawn(tab.linkedBrowser, [], () => {
    141      const video = content.document.getElementById("testVideo");
    142      if (!video) {
    143        ok(false, `can't get the media element!`);
    144      }
    145      video.play();
    146    }),
    147  ]);
    148 }
    149 
    150 async function checkIfActionReceived(tab, action) {
    151  await SpecialPowers.spawn(tab.linkedBrowser, [action], expectedAction => {
    152    return new Promise(resolve => {
    153      const result = content.document.getElementById("result");
    154      if (!result) {
    155        ok(false, `can't get the element for showing result!`);
    156      }
    157 
    158      function checkAction() {
    159        is(
    160          result.innerHTML,
    161          expectedAction,
    162          `received '${expectedAction}' correctly`
    163        );
    164        // Reset the result after finishing checking result, then we can dispatch
    165        // same action again without worrying about previous result.
    166        result.innerHTML = "";
    167        resolve();
    168      }
    169 
    170      if (result.innerHTML == "") {
    171        info(`wait until receiving action`);
    172        result.addEventListener("actionChanged", () => checkAction(), {
    173          once: true,
    174        });
    175      } else {
    176        checkAction();
    177      }
    178    });
    179  });
    180 }
    181 
    182 async function checkIfActionNotReceived(tab, action) {
    183  await SpecialPowers.spawn(tab.linkedBrowser, [action], expectedAction => {
    184    return new Promise(resolve => {
    185      const result = content.document.getElementById("result");
    186      if (!result) {
    187        ok(false, `can't get the element for showing result!`);
    188      }
    189      is(result.innerHTML, "", `should not receive any action`);
    190      ok(result.innerHTML != expectedAction, `not receive '${expectedAction}'`);
    191      resolve();
    192    });
    193  });
    194 }
    195 
    196 function waitUntilMainMediaControllerChanged() {
    197  return BrowserUtils.promiseObserved("main-media-controller-changed");
    198 }