From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../test/browser/browser_ext_tabs_audio.js | 261 +++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 browser/components/extensions/test/browser/browser_ext_tabs_audio.js (limited to 'browser/components/extensions/test/browser/browser_ext_tabs_audio.js') 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); +}); -- cgit v1.2.3