summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_tabs_audio.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_tabs_audio.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_audio.js261
1 files changed, 261 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_audio.js b/browser/components/extensions/test/browser/browser_ext_tabs_audio.js
new file mode 100644
index 0000000000..978c3697c8
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_audio.js
@@ -0,0 +1,261 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+add_task(async function () {
+ let tab1 = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "about:blank?1"
+ );
+ let tab2 = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "about:blank?2"
+ );
+
+ gBrowser.selectedTab = tab1;
+
+ async function background() {
+ function promiseUpdated(tabId, attr) {
+ return new Promise(resolve => {
+ let onUpdated = (tabId_, changeInfo, tab) => {
+ if (tabId == tabId_ && attr in changeInfo) {
+ browser.tabs.onUpdated.removeListener(onUpdated);
+
+ resolve({ changeInfo, tab });
+ }
+ };
+ browser.tabs.onUpdated.addListener(onUpdated);
+ });
+ }
+
+ let deferred = {};
+ browser.test.onMessage.addListener((message, tabId, result) => {
+ if (message == "change-tab-done" && deferred[tabId]) {
+ deferred[tabId].resolve(result);
+ }
+ });
+
+ function changeTab(tabId, attr, on) {
+ return new Promise((resolve, reject) => {
+ deferred[tabId] = { resolve, reject };
+ browser.test.sendMessage("change-tab", tabId, attr, on);
+ });
+ }
+
+ try {
+ let tabs = await browser.tabs.query({ lastFocusedWindow: true });
+ browser.test.assertEq(tabs.length, 3, "We have three tabs");
+
+ for (let tab of tabs) {
+ // Note: We want to check that these are actual boolean values, not
+ // just that they evaluate as false.
+ browser.test.assertEq(false, tab.mutedInfo.muted, "Tab is not muted");
+ browser.test.assertEq(
+ undefined,
+ tab.mutedInfo.reason,
+ "Tab has no muted info reason"
+ );
+ browser.test.assertEq(false, tab.audible, "Tab is not audible");
+ }
+
+ let windowId = tabs[0].windowId;
+ let tabIds = [tabs[1].id, tabs[2].id];
+
+ browser.test.log(
+ "Test initial queries for muted and audible return no tabs"
+ );
+ let silent = await browser.tabs.query({ windowId, audible: false });
+ let audible = await browser.tabs.query({ windowId, audible: true });
+ let muted = await browser.tabs.query({ windowId, muted: true });
+ let nonMuted = await browser.tabs.query({ windowId, muted: false });
+
+ browser.test.assertEq(3, silent.length, "Three silent tabs");
+ browser.test.assertEq(0, audible.length, "No audible tabs");
+
+ browser.test.assertEq(0, muted.length, "No muted tabs");
+ browser.test.assertEq(3, nonMuted.length, "Three non-muted tabs");
+
+ browser.test.log(
+ "Toggle muted and audible externally on one tab each, and check results"
+ );
+ [muted, audible] = await Promise.all([
+ promiseUpdated(tabIds[0], "mutedInfo"),
+ promiseUpdated(tabIds[1], "audible"),
+ changeTab(tabIds[0], "muted", true),
+ changeTab(tabIds[1], "audible", true),
+ ]);
+
+ for (let obj of [muted.changeInfo, muted.tab]) {
+ browser.test.assertEq(true, obj.mutedInfo.muted, "Tab is muted");
+ browser.test.assertEq(
+ "user",
+ obj.mutedInfo.reason,
+ "Tab was muted by the user"
+ );
+ }
+
+ browser.test.assertEq(
+ true,
+ audible.changeInfo.audible,
+ "Tab audible state changed"
+ );
+ browser.test.assertEq(true, audible.tab.audible, "Tab is audible");
+
+ browser.test.log(
+ "Re-check queries. Expect one audible and one muted tab"
+ );
+ silent = await browser.tabs.query({ windowId, audible: false });
+ audible = await browser.tabs.query({ windowId, audible: true });
+ muted = await browser.tabs.query({ windowId, muted: true });
+ nonMuted = await browser.tabs.query({ windowId, muted: false });
+
+ browser.test.assertEq(2, silent.length, "Two silent tabs");
+ browser.test.assertEq(1, audible.length, "One audible tab");
+
+ browser.test.assertEq(1, muted.length, "One muted tab");
+ browser.test.assertEq(2, nonMuted.length, "Two non-muted tabs");
+
+ browser.test.assertEq(true, muted[0].mutedInfo.muted, "Tab is muted");
+ browser.test.assertEq(
+ "user",
+ muted[0].mutedInfo.reason,
+ "Tab was muted by the user"
+ );
+
+ browser.test.assertEq(true, audible[0].audible, "Tab is audible");
+
+ browser.test.log(
+ "Toggle muted internally on two tabs, and check results"
+ );
+ [nonMuted, muted] = await Promise.all([
+ promiseUpdated(tabIds[0], "mutedInfo"),
+ promiseUpdated(tabIds[1], "mutedInfo"),
+ browser.tabs.update(tabIds[0], { muted: false }),
+ browser.tabs.update(tabIds[1], { muted: true }),
+ ]);
+
+ for (let obj of [nonMuted.changeInfo, nonMuted.tab]) {
+ browser.test.assertEq(false, obj.mutedInfo.muted, "Tab is not muted");
+ }
+ for (let obj of [muted.changeInfo, muted.tab]) {
+ browser.test.assertEq(true, obj.mutedInfo.muted, "Tab is muted");
+ }
+
+ for (let obj of [
+ nonMuted.changeInfo,
+ nonMuted.tab,
+ muted.changeInfo,
+ muted.tab,
+ ]) {
+ browser.test.assertEq(
+ "extension",
+ obj.mutedInfo.reason,
+ "Mute state changed by extension"
+ );
+
+ browser.test.assertEq(
+ browser.runtime.id,
+ obj.mutedInfo.extensionId,
+ "Mute state changed by extension"
+ );
+ }
+
+ browser.test.log("Test that mutedInfo is preserved by sessionstore");
+ let tab = await changeTab(tabIds[1], "duplicate").then(browser.tabs.get);
+
+ browser.test.assertEq(true, tab.mutedInfo.muted, "Tab is muted");
+
+ browser.test.assertEq(
+ "extension",
+ tab.mutedInfo.reason,
+ "Mute state changed by extension"
+ );
+
+ browser.test.assertEq(
+ browser.runtime.id,
+ tab.mutedInfo.extensionId,
+ "Mute state changed by extension"
+ );
+
+ browser.test.log("Unmute externally, and check results");
+ [nonMuted] = await Promise.all([
+ promiseUpdated(tabIds[1], "mutedInfo"),
+ changeTab(tabIds[1], "muted", false),
+ browser.tabs.remove(tab.id),
+ ]);
+
+ for (let obj of [nonMuted.changeInfo, nonMuted.tab]) {
+ browser.test.assertEq(false, obj.mutedInfo.muted, "Tab is not muted");
+ browser.test.assertEq(
+ "user",
+ obj.mutedInfo.reason,
+ "Mute state changed by user"
+ );
+ }
+
+ browser.test.notifyPass("tab-audio");
+ } catch (e) {
+ browser.test.fail(`${e} :: ${e.stack}`);
+ browser.test.notifyFail("tab-audio");
+ }
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["tabs"],
+ },
+
+ background,
+ });
+
+ extension.onMessage("change-tab", (tabId, attr, on) => {
+ const {
+ Management: {
+ global: { tabTracker },
+ },
+ } = ChromeUtils.importESModule("resource://gre/modules/Extension.sys.mjs");
+
+ let tab = tabTracker.getTab(tabId);
+
+ if (attr == "muted") {
+ // Ideally we'd simulate a click on the tab audio icon for this, but the
+ // handler relies on CSS :hover states, which are complicated and fragile
+ // to simulate.
+ if (tab.muted != on) {
+ tab.toggleMuteAudio();
+ }
+ } else if (attr == "audible") {
+ let browser = tab.linkedBrowser;
+ if (on) {
+ browser.audioPlaybackStarted();
+ } else {
+ browser.audioPlaybackStopped();
+ }
+ } else if (attr == "duplicate") {
+ // This is a bit of a hack. It won't be necessary once we have
+ // `tabs.duplicate`.
+ let newTab = gBrowser.duplicateTab(tab);
+ BrowserTestUtils.waitForEvent(newTab, "SSTabRestored", () => true).then(
+ () => {
+ extension.sendMessage(
+ "change-tab-done",
+ tabId,
+ tabTracker.getId(newTab)
+ );
+ }
+ );
+ return;
+ }
+
+ extension.sendMessage("change-tab-done", tabId);
+ });
+
+ await extension.startup();
+
+ await extension.awaitFinish("tab-audio");
+
+ await extension.unload();
+
+ BrowserTestUtils.removeTab(tab1);
+ BrowserTestUtils.removeTab(tab2);
+});