diff --git a/src/browser-polyfill.js b/src/browser-polyfill.js index f9784fb..b7619fd 100644 --- a/src/browser-polyfill.js +++ b/src/browser-polyfill.js @@ -490,6 +490,24 @@ if (typeof browser === "undefined") { sendMessage: wrappedSendMessage.bind(null, "sendMessage", {minArgs: 2, maxArgs: 3}), }, }; + const settingMetadata = { + clear: {minArgs: 1, maxArgs: 1}, + get: {minArgs: 1, maxArgs: 1}, + set: {minArgs: 1, maxArgs: 1}, + }; + apiMetadata.privacy = { + network: { + networkPredictionEnabled: settingMetadata, + webRTCIPHandlingPolicy: settingMetadata, + }, + services: { + passwordSavingEnabled: settingMetadata, + }, + websites: { + hyperlinkAuditingEnabled: settingMetadata, + referrersEnabled: settingMetadata, + }, + }; return wrapObject(chrome, staticWrappers, apiMetadata); }; diff --git a/test/fixtures/privacy-setting-extension/background.js b/test/fixtures/privacy-setting-extension/background.js new file mode 100644 index 0000000..ef7bf14 --- /dev/null +++ b/test/fixtures/privacy-setting-extension/background.js @@ -0,0 +1,5 @@ +browser.runtime.onMessage.addListener(async (msg) => { + let {method, args} = msg; + let result = await browser.privacy.services.passwordSavingEnabled[method](...args); + return {result, type: typeof result}; +}); diff --git a/test/fixtures/privacy-setting-extension/content.js b/test/fixtures/privacy-setting-extension/content.js new file mode 100644 index 0000000..78cc4ef --- /dev/null +++ b/test/fixtures/privacy-setting-extension/content.js @@ -0,0 +1,48 @@ +test("privacy API should be unavailable in the content script", (t) => { + t.deepEqual(browser.privacy, undefined, "browser.privacy should not be available in a content script"); +}); + +test("privacy API should support promises", async (t) => { + async function callSettingAPI(method, ...args) { + // Invokes: browser.privacy.services.passwordSavingEnabled[method](...args); + let {type, result} = await browser.runtime.sendMessage({method, args}); + // In Chrome `undefined` values are serialized to `null`, so check the type + // as determined in the background page. + return type === "undefined" ? undefined : result; + } + + let res = await callSettingAPI("get", {}); + t.deepEqual(res, { + levelOfControl: "controllable_by_this_extension", + // Enabled by default in Chrome; disabled by default in Firefox. + value: !navigator.userAgent.includes("Firefox/"), + }, "passwordSavingEnabled.get() resolves to the initial value"); + + const defaultValue = res.value; + const newValue = !defaultValue; + res = await callSettingAPI("set", {value: newValue}); + if (navigator.userAgent.includes("Firefox/")) { + t.equal(res, true, "passwordSavingEnabled.set() resolves to true"); + } else { + t.equal(res, undefined, "passwordSavingEnabled.set() resolves to a void value"); + } + + res = await callSettingAPI("get", {}); + t.deepEqual(res, { + levelOfControl: "controlled_by_this_extension", + value: newValue, + }, "passwordSavingEnabled.get() resolves to the updated value"); + + res = await callSettingAPI("clear", {}); + if (navigator.userAgent.includes("Firefox/")) { + t.equal(res, true, "passwordSavingEnabled.clear() resolves to true"); + } else { + t.equal(res, undefined, "passwordSavingEnabled.clear() resolves to a void value"); + } + + res = await callSettingAPI("get", {}); + t.deepEqual(res, { + levelOfControl: "controllable_by_this_extension", + value: defaultValue, + }, "passwordSavingEnabled.get() resolves to the default value"); +}); diff --git a/test/fixtures/privacy-setting-extension/manifest.json b/test/fixtures/privacy-setting-extension/manifest.json new file mode 100644 index 0000000..28cdfdb --- /dev/null +++ b/test/fixtures/privacy-setting-extension/manifest.json @@ -0,0 +1,25 @@ +{ + "manifest_version": 2, + "name": "test-privacy", + "version": "0.1", + "description": "test-privacy", + "content_scripts": [ + { + "matches": [ + "http://localhost/*" + ], + "js": [ + "browser-polyfill.js", + "tape.js", + "content.js" + ] + } + ], + "permissions": ["privacy"], + "background": { + "scripts": [ + "browser-polyfill.js", + "background.js" + ] + } +} diff --git a/test/integration/test-extensions-in-browser.js b/test/integration/test-extensions-in-browser.js index 032f34f..be14a95 100644 --- a/test/integration/test-extensions-in-browser.js +++ b/test/integration/test-extensions-in-browser.js @@ -21,3 +21,8 @@ defineExtensionTests({ description: "polyfill should detect an existent browser API object in content scripts", extensions: ["detect-browser-api-object-in-content-script"], }); + +defineExtensionTests({ + description: "Instance of BrowserSetting API", + extensions: ["privacy-setting-extension"], +});