summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_tabs_zoom.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_tabs_zoom.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_zoom.js346
1 files changed, 346 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_zoom.js b/browser/components/extensions/test/browser/browser_ext_tabs_zoom.js
new file mode 100644
index 0000000000..ad10324573
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_zoom.js
@@ -0,0 +1,346 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+const SITE_SPECIFIC_PREF = "browser.zoom.siteSpecific";
+const FULL_ZOOM_PREF = "browser.content.full-zoom";
+
+let gContentPrefs = Cc["@mozilla.org/content-pref/service;1"].getService(
+ Ci.nsIContentPrefService2
+);
+
+// A single monitor for the tests. If it receives any
+// incognito data in event listeners it will fail.
+let monitor;
+add_task(async function startup() {
+ monitor = await startIncognitoMonitorExtension();
+});
+registerCleanupFunction(async function finish() {
+ await monitor.unload();
+});
+
+add_task(async function test_zoom_api() {
+ 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, msg, result) => {
+ if (message == "msg-done" && deferred[msg]) {
+ deferred[msg].resolve(result);
+ }
+ });
+
+ let _id = 0;
+ function msg(...args) {
+ return new Promise((resolve, reject) => {
+ let id = ++_id;
+ deferred[id] = { resolve, reject };
+ browser.test.sendMessage("msg", id, ...args);
+ });
+ }
+
+ let lastZoomEvent = {};
+ let promiseZoomEvents = {};
+ browser.tabs.onZoomChange.addListener(info => {
+ lastZoomEvent[info.tabId] = info;
+ if (promiseZoomEvents[info.tabId]) {
+ promiseZoomEvents[info.tabId]();
+ promiseZoomEvents[info.tabId] = null;
+ }
+ });
+
+ let awaitZoom = async (tabId, newValue) => {
+ let listener;
+
+ // eslint-disable-next-line no-async-promise-executor
+ await new Promise(async resolve => {
+ listener = info => {
+ if (info.tabId == tabId && info.newZoomFactor == newValue) {
+ resolve();
+ }
+ };
+ browser.tabs.onZoomChange.addListener(listener);
+
+ let zoomFactor = await browser.tabs.getZoom(tabId);
+ if (zoomFactor == newValue) {
+ resolve();
+ }
+ });
+
+ browser.tabs.onZoomChange.removeListener(listener);
+ };
+
+ let checkZoom = async (tabId, newValue, oldValue = null) => {
+ let awaitEvent;
+ if (oldValue != null && !lastZoomEvent[tabId]) {
+ awaitEvent = new Promise(resolve => {
+ promiseZoomEvents[tabId] = resolve;
+ });
+ }
+
+ let [apiZoom, realZoom] = await Promise.all([
+ browser.tabs.getZoom(tabId),
+ msg("get-zoom", tabId),
+ awaitEvent,
+ ]);
+
+ browser.test.assertEq(
+ newValue,
+ apiZoom,
+ `Got expected zoom value from API`
+ );
+ browser.test.assertEq(
+ newValue,
+ realZoom,
+ `Got expected zoom value from parent`
+ );
+
+ if (oldValue != null) {
+ let event = lastZoomEvent[tabId];
+ lastZoomEvent[tabId] = null;
+ browser.test.assertEq(
+ tabId,
+ event.tabId,
+ `Got expected zoom event tab ID`
+ );
+ browser.test.assertEq(
+ newValue,
+ event.newZoomFactor,
+ `Got expected zoom event zoom factor`
+ );
+ browser.test.assertEq(
+ oldValue,
+ event.oldZoomFactor,
+ `Got expected zoom event old zoom factor`
+ );
+
+ browser.test.assertEq(
+ 3,
+ Object.keys(event.zoomSettings).length,
+ `Zoom settings should have 3 keys`
+ );
+ browser.test.assertEq(
+ "automatic",
+ event.zoomSettings.mode,
+ `Mode should be "automatic"`
+ );
+ browser.test.assertEq(
+ "per-origin",
+ event.zoomSettings.scope,
+ `Scope should be "per-origin"`
+ );
+ browser.test.assertEq(
+ 1,
+ event.zoomSettings.defaultZoomFactor,
+ `Default zoom should be 1`
+ );
+ }
+ };
+
+ try {
+ let tabs = await browser.tabs.query({});
+ browser.test.assertEq(tabs.length, 4, "We have 4 tabs");
+
+ let tabIds = tabs.splice(1).map(tab => tab.id);
+ await checkZoom(tabIds[0], 1);
+
+ await browser.tabs.setZoom(tabIds[0], 2);
+ await checkZoom(tabIds[0], 2, 1);
+
+ let zoomSettings = await browser.tabs.getZoomSettings(tabIds[0]);
+ browser.test.assertEq(
+ 3,
+ Object.keys(zoomSettings).length,
+ `Zoom settings should have 3 keys`
+ );
+ browser.test.assertEq(
+ "automatic",
+ zoomSettings.mode,
+ `Mode should be "automatic"`
+ );
+ browser.test.assertEq(
+ "per-origin",
+ zoomSettings.scope,
+ `Scope should be "per-origin"`
+ );
+ browser.test.assertEq(
+ 1,
+ zoomSettings.defaultZoomFactor,
+ `Default zoom should be 1`
+ );
+
+ browser.test.log(`Switch to tab 2`);
+ await browser.tabs.update(tabIds[1], { active: true });
+ await checkZoom(tabIds[1], 1);
+
+ browser.test.log(`Navigate tab 2 to origin of tab 1`);
+ browser.tabs.update(tabIds[1], { url: "http://example.com" });
+ await promiseUpdated(tabIds[1], "url");
+ await checkZoom(tabIds[1], 2, 1);
+
+ browser.test.log(`Update zoom in tab 2, expect changes in both tabs`);
+ await browser.tabs.setZoom(tabIds[1], 1.5);
+ await checkZoom(tabIds[1], 1.5, 2);
+
+ browser.test.log(`Switch to tab 3, expect zoom to affect private window`);
+ await browser.tabs.setZoom(tabIds[2], 3);
+ await checkZoom(tabIds[2], 3, 1);
+
+ browser.test.log(
+ `Switch to tab 1, expect asynchronous zoom change just after the switch`
+ );
+ await Promise.all([
+ awaitZoom(tabIds[0], 1.5),
+ browser.tabs.update(tabIds[0], { active: true }),
+ ]);
+ await checkZoom(tabIds[0], 1.5, 2);
+
+ browser.test.log("Set zoom to 0, expect it set to 1");
+ await browser.tabs.setZoom(tabIds[0], 0);
+ await checkZoom(tabIds[0], 1, 1.5);
+
+ browser.test.log("Change zoom externally, expect changes reflected");
+ await msg("enlarge");
+ await checkZoom(tabIds[0], 1.1, 1);
+
+ await Promise.all([
+ browser.tabs.setZoom(tabIds[0], 0),
+ browser.tabs.setZoom(tabIds[1], 0),
+ browser.tabs.setZoom(tabIds[2], 0),
+ ]);
+ await Promise.all([
+ checkZoom(tabIds[0], 1, 1.1),
+ checkZoom(tabIds[1], 1, 1.5),
+ checkZoom(tabIds[2], 1, 3),
+ ]);
+
+ browser.test.log("Check that invalid zoom values throw an error");
+ await browser.test.assertRejects(
+ browser.tabs.setZoom(tabIds[0], 42),
+ /Zoom value 42 out of range/,
+ "Expected an out of range error"
+ );
+
+ browser.test.log("Disable site-specific zoom, expect correct scope");
+ await msg("site-specific", false);
+ zoomSettings = await browser.tabs.getZoomSettings(tabIds[0]);
+
+ browser.test.assertEq(
+ "per-tab",
+ zoomSettings.scope,
+ `Scope should be "per-tab"`
+ );
+
+ await msg("site-specific", null);
+
+ browser.test.onMessage.addListener(async msg => {
+ if (msg === "set-global-zoom-done") {
+ zoomSettings = await browser.tabs.getZoomSettings(tabIds[0]);
+
+ browser.test.assertEq(
+ 5,
+ zoomSettings.defaultZoomFactor,
+ `Default zoom should be 5 after being changed`
+ );
+
+ browser.test.notifyPass("tab-zoom");
+ }
+ });
+ await msg("set-global-zoom");
+ } catch (e) {
+ browser.test.fail(`Error: ${e} :: ${e.stack}`);
+ browser.test.notifyFail("tab-zoom");
+ }
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["tabs"],
+ },
+ incognitoOverride: "spanning",
+ background,
+ });
+
+ extension.onMessage("msg", (id, msg, ...args) => {
+ const {
+ Management: {
+ global: { tabTracker },
+ },
+ } = ChromeUtils.importESModule("resource://gre/modules/Extension.sys.mjs");
+
+ let resp;
+ if (msg == "get-zoom") {
+ let tab = tabTracker.getTab(args[0]);
+ resp = ZoomManager.getZoomForBrowser(tab.linkedBrowser);
+ } else if (msg == "set-zoom") {
+ let tab = tabTracker.getTab(args[0]);
+ ZoomManager.setZoomForBrowser(tab.linkedBrowser);
+ } else if (msg == "set-global-zoom") {
+ resp = gContentPrefs.setGlobal(
+ FULL_ZOOM_PREF,
+ 5,
+ Cu.createLoadContext(),
+ {
+ handleCompletion() {
+ extension.sendMessage("set-global-zoom-done", id, resp);
+ },
+ }
+ );
+ } else if (msg == "enlarge") {
+ FullZoom.enlarge();
+ } else if (msg == "site-specific") {
+ if (args[0] == null) {
+ SpecialPowers.clearUserPref(SITE_SPECIFIC_PREF);
+ } else {
+ SpecialPowers.setBoolPref(SITE_SPECIFIC_PREF, args[0]);
+ }
+ }
+
+ extension.sendMessage("msg-done", id, resp);
+ });
+
+ let url = "https://example.com/";
+ let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+ let tab2 = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "http://example.org/"
+ );
+
+ let privateWindow = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+ let selectedBrowser = privateWindow.gBrowser.selectedBrowser;
+ BrowserTestUtils.loadURIString(selectedBrowser, url);
+ await BrowserTestUtils.browserLoaded(selectedBrowser, false, url);
+
+ gBrowser.selectedTab = tab1;
+
+ await extension.startup();
+
+ await extension.awaitFinish("tab-zoom");
+
+ await extension.unload();
+
+ await new Promise(resolve => {
+ gContentPrefs.setGlobal(FULL_ZOOM_PREF, null, Cu.createLoadContext(), {
+ handleCompletion() {
+ resolve();
+ },
+ });
+ });
+
+ privateWindow.close();
+ BrowserTestUtils.removeTab(tab1);
+ BrowserTestUtils.removeTab(tab2);
+});