249 lines
7.8 KiB
JavaScript
249 lines
7.8 KiB
JavaScript
"use strict";
|
|
|
|
AddonTestUtils.createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1");
|
|
|
|
createHttpServer({ hosts: ["example.com"] });
|
|
|
|
add_setup(() => {
|
|
// Need a profile to init Glean.
|
|
do_get_profile();
|
|
Services.fog.initializeFOG();
|
|
});
|
|
|
|
async function test_mozExtensionGlobalMatch({ expectAllowed }) {
|
|
const testMatchesWindowGlobal = async ({ allowed, extId, subframeURL }) => {
|
|
const { MatchPatternSet, WebExtensionContentScript, WebExtensionPolicy } =
|
|
Cu.getGlobalForObject(Services);
|
|
|
|
const policy = WebExtensionPolicy.getByID(extId);
|
|
const script = new WebExtensionContentScript(policy, {
|
|
// This content script matches would be matching any extension document,
|
|
// but we will be call matchesWindowGlobal only for a specific document
|
|
// and so we expect the warning log to only be emitted for that
|
|
// specific document (and not emitted for the other extension page).
|
|
matches: new MatchPatternSet([policy.getURL("*")]),
|
|
// The content script instance should be configured to match all
|
|
// frames if we are testing a moz-extension subframe.
|
|
allFrames: !!subframeURL,
|
|
matchAboutBlank: false,
|
|
});
|
|
|
|
let targetWin = this.content;
|
|
|
|
if (subframeURL) {
|
|
info("Creating moz-extension subframe");
|
|
const iframe = this.content.document.createElement("iframe");
|
|
iframe.src = subframeURL;
|
|
const promiseFrameLoaded = new Promise(resolve => {
|
|
iframe.addEventListener("load", resolve, { once: true });
|
|
});
|
|
this.content.document.body.append(iframe);
|
|
info("Waiting for subframe to be fully loaded");
|
|
await promiseFrameLoaded;
|
|
info("Subframe load is completed: " + iframe.contentDocument.documentURI);
|
|
targetWin = iframe.contentWindow;
|
|
}
|
|
|
|
info(
|
|
"Call WebExtensionContentScript.matchesWindowGlobal and wait for the console message"
|
|
);
|
|
const results = await new Promise(resolve => {
|
|
let matchResult;
|
|
let listener = {
|
|
QueryInterface: ChromeUtils.generateQI(["nsIConsoleListener"]),
|
|
observe(msg) {
|
|
info(`Got console message: ${msg.message}`);
|
|
const msgFound = msg.message.match(
|
|
/Content Script execution in moz-extension document has been deprecated/
|
|
);
|
|
if (msgFound) {
|
|
Services.console.unregisterListener(this);
|
|
resolve({ matchResult, consoleMsg: msg });
|
|
}
|
|
},
|
|
};
|
|
Services.console.registerListener(listener);
|
|
info(`Testing WebExtensionContentScript matchesWindowGlobal`);
|
|
matchResult = script.matchesWindowGlobal(targetWin.windowGlobalChild);
|
|
});
|
|
|
|
info("Assert matchesWindowGlobal result and logged warning messages");
|
|
|
|
Assert.equal(
|
|
results.matchResult,
|
|
allowed,
|
|
`Got the expect matchesWindowGlobal result`
|
|
);
|
|
const expectWarningOutcomeMsg = allowed
|
|
? "and will be removed in"
|
|
: "and it has been blocked";
|
|
ok(results.consoleMsg, "Expect deprecation warning message to be logged");
|
|
ok(
|
|
results.consoleMsg?.message.includes(expectWarningOutcomeMsg),
|
|
`Expect the warning message to include "${expectWarningOutcomeMsg}"`
|
|
);
|
|
const { documentURI } = targetWin.document;
|
|
ok(
|
|
results.consoleMsg.message.includes(`{file: "${documentURI}"`),
|
|
`Expect the warning message to be associated to the extension page url: ${documentURI}`
|
|
);
|
|
Assert.equal(
|
|
results.consoleMsg?.logLevel,
|
|
Ci.nsIConsoleMessage.warn,
|
|
"Extpect log level to be 'warn'."
|
|
);
|
|
Assert.ok(
|
|
results.consoleMsg instanceof Ci.nsIScriptError,
|
|
"Expect console message to be an instance of nsIScriptError"
|
|
);
|
|
Assert.equal(
|
|
results.consoleMsg.innerWindowID,
|
|
targetWin.windowGlobalChild.innerWindowId,
|
|
"Expect the warning to be associated to the right innerWindowID"
|
|
);
|
|
};
|
|
|
|
const extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
web_accessible_resources: ["extdoc.html"],
|
|
},
|
|
files: {
|
|
"extdoc.html": `<h1>Extension Context</h1>`,
|
|
"another-extdoc.html": `<h1>Another Extension Context</h1>`,
|
|
},
|
|
});
|
|
|
|
await extension.startup();
|
|
|
|
const page = await ExtensionTestUtils.loadContentPage(
|
|
`moz-extension://${extension.uuid}/extdoc.html`
|
|
);
|
|
const anotherPage = await ExtensionTestUtils.loadContentPage(
|
|
`moz-extension://${extension.uuid}/another-extdoc.html`
|
|
);
|
|
const webPage = await ExtensionTestUtils.loadContentPage(
|
|
"http://example.com/"
|
|
);
|
|
|
|
// Flush and clear all child processes Glean data.
|
|
await Services.fog.testFlushAllChildren();
|
|
Services.fog.testResetFOG();
|
|
|
|
const extId = extension.id;
|
|
|
|
// Test warning logged in top level frame.
|
|
await page.spawn(
|
|
[{ allowed: expectAllowed, extId }],
|
|
testMatchesWindowGlobal
|
|
);
|
|
// Verify telemetry event for top-level page matching.
|
|
await Services.fog.testFlushAllChildren();
|
|
Assert.deepEqual(
|
|
Glean.extensions.matchMozExtensionDocument.testGetValue()?.map(event => {
|
|
delete event.timestamp;
|
|
return event;
|
|
}),
|
|
[
|
|
{
|
|
category: "extensions",
|
|
name: "match_moz_extension_document",
|
|
extra: {
|
|
restricted: `${!expectAllowed}`,
|
|
addon_id: extension.id,
|
|
is_top_level_frame: "true",
|
|
},
|
|
},
|
|
],
|
|
"Got the expected telemetry matchMozExtensionDocument Glean events for top-level frame"
|
|
);
|
|
Services.fog.testResetFOG();
|
|
await page.close();
|
|
|
|
// Test warning logged in subframe.
|
|
const subframeURL = `moz-extension://${extension.uuid}/extdoc.html`;
|
|
await webPage.spawn(
|
|
[{ allowed: expectAllowed, extId, subframeURL }],
|
|
testMatchesWindowGlobal
|
|
);
|
|
// Verify telemetry event for subframe matching.
|
|
await Services.fog.testFlushAllChildren();
|
|
Assert.deepEqual(
|
|
Glean.extensions.matchMozExtensionDocument.testGetValue()?.map(event => {
|
|
delete event.timestamp;
|
|
return event;
|
|
}),
|
|
[
|
|
{
|
|
category: "extensions",
|
|
name: "match_moz_extension_document",
|
|
extra: {
|
|
restricted: `${!expectAllowed}`,
|
|
addon_id: extId,
|
|
is_top_level_frame: "false",
|
|
},
|
|
},
|
|
],
|
|
"Got the expected telemetry matchMozExtensionDocument Glean events for subframe"
|
|
);
|
|
Services.fog.testResetFOG();
|
|
await webPage.close();
|
|
|
|
await anotherPage.close();
|
|
await extension.unload();
|
|
}
|
|
|
|
add_task(
|
|
{
|
|
pref_set: [
|
|
["extensions.webextensions.allow_executeScript_in_moz_extension", true],
|
|
],
|
|
},
|
|
async function test_mozExtensionGlobalMatchAllowed() {
|
|
await test_mozExtensionGlobalMatch({ expectAllowed: true });
|
|
}
|
|
);
|
|
|
|
add_task(
|
|
{
|
|
pref_set: [
|
|
["extensions.webextensions.allow_executeScript_in_moz_extension", false],
|
|
],
|
|
},
|
|
async function test_mozExtensionGlobalMatchDisallowed() {
|
|
await test_mozExtensionGlobalMatch({ expectAllowed: false });
|
|
}
|
|
);
|
|
|
|
add_task(
|
|
{
|
|
pref_set: [
|
|
["extensions.webextensions.allow_executeScript_in_moz_extension", true],
|
|
],
|
|
},
|
|
async function test_rollbackPrefTelemetry() {
|
|
await AddonTestUtils.promiseShutdownManager();
|
|
Services.fog.testResetFOG();
|
|
// Sanity check.
|
|
Assert.equal(
|
|
Glean.extensions.allowExecuteScriptInMozExtension.testGetValue(),
|
|
null,
|
|
"Expect allowExecuteScriptInMozExtension metric to be initially unset"
|
|
);
|
|
await AddonTestUtils.promiseStartupManager();
|
|
Assert.equal(
|
|
Glean.extensions.allowExecuteScriptInMozExtension.testGetValue(),
|
|
true,
|
|
"Expect allowExecuteScriptInMozExtension metric to be set to true after AOM startup"
|
|
);
|
|
Services.prefs.setBoolPref(
|
|
"extensions.webextensions.allow_executeScript_in_moz_extension",
|
|
false
|
|
);
|
|
Assert.equal(
|
|
Glean.extensions.allowExecuteScriptInMozExtension.testGetValue(),
|
|
false,
|
|
"Expect allowExecuteScriptInMozExtension metric to be set to false after the pref value has been changed"
|
|
);
|
|
}
|
|
);
|