mirror of
https://github.com/Feodor2/Mypal68.git
synced 2025-06-18 23:05:40 -04:00
550 lines
20 KiB
JavaScript
550 lines
20 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
const { ContentTaskUtils } = ChromeUtils.import(
|
|
"resource://testing-common/ContentTaskUtils.jsm"
|
|
);
|
|
const { TelemetryUtils } = ChromeUtils.import(
|
|
"resource://gre/modules/TelemetryUtils.jsm"
|
|
);
|
|
const { ObjectUtils } = ChromeUtils.import(
|
|
"resource://gre/modules/ObjectUtils.jsm"
|
|
);
|
|
const { PermissionTestUtils } = ChromeUtils.import(
|
|
"resource://testing-common/PermissionTestUtils.jsm"
|
|
);
|
|
|
|
const HC_PERMISSION = "hc_telemetry";
|
|
|
|
async function waitForProcessesEvents(
|
|
aProcesses,
|
|
aAdditionalCondition = data => true
|
|
) {
|
|
await ContentTaskUtils.waitForCondition(() => {
|
|
const events = Services.telemetry.snapshotEvents(
|
|
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS
|
|
);
|
|
return (
|
|
aProcesses.every(p => Object.keys(events).includes(p)) &&
|
|
aAdditionalCondition(events)
|
|
);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Wait for a specific event to appear in the given process data.
|
|
* @param {String} aProcess the name of the process we expect the event to appear.
|
|
* @param {Array} aEventData the event data to look for.
|
|
* @return {Promise} Resolved when the event is found or rejected if the search
|
|
* times out.
|
|
*/
|
|
async function waitForEvent(aProcess, aEventData) {
|
|
await waitForProcessesEvents([aProcess], events => {
|
|
let processEvents = events[aProcess].map(e => e.slice(1));
|
|
if (processEvents.length == 0) {
|
|
return false;
|
|
}
|
|
|
|
return processEvents.find(e => ObjectUtils.deepEqual(e, aEventData));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Remove the trailing null/undefined from an event definition.
|
|
* This is useful for comparing the sample events (that might
|
|
* contain null/undefined) to the data from the snapshot (which might
|
|
* filter them).
|
|
*/
|
|
function removeTrailingInvalidEntry(aEvent) {
|
|
while (
|
|
aEvent[aEvent.length - 1] === undefined ||
|
|
aEvent[aEvent.length - 1] === null
|
|
) {
|
|
aEvent.pop();
|
|
}
|
|
return aEvent;
|
|
}
|
|
|
|
add_task(async function test_setup() {
|
|
// Make sure the newly spawned content processes will have extended Telemetry and
|
|
// hybrid content telemetry enabled.
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
[TelemetryUtils.Preferences.OverridePreRelease, true],
|
|
[TelemetryUtils.Preferences.HybridContentEnabled, true],
|
|
[TelemetryUtils.Preferences.LogLevel, "Trace"],
|
|
],
|
|
});
|
|
// And take care of the already initialized one as well.
|
|
let canRecordExtended = Services.telemetry.canRecordExtended;
|
|
Services.telemetry.canRecordExtended = true;
|
|
registerCleanupFunction(
|
|
() => (Services.telemetry.canRecordExtended = canRecordExtended)
|
|
);
|
|
});
|
|
|
|
add_task(async function test_untrusted_http_origin() {
|
|
Services.telemetry.clearEvents();
|
|
|
|
// Install a custom handler that intercepts hybrid content telemetry messages
|
|
// and makes the test fail. We don't expect any message from non secure contexts.
|
|
const messageName = "HybridContentTelemetry:onTelemetryMessage";
|
|
let makeTestFail = () => ok(false, `Received an unexpected ${messageName}.`);
|
|
Services.mm.addMessageListener(messageName, makeTestFail);
|
|
|
|
// Try to use the API on a non-secure host.
|
|
const testHost = "http://example.org";
|
|
let testHttpUri = Services.io.newURI(testHost);
|
|
PermissionTestUtils.add(
|
|
testHttpUri,
|
|
HC_PERMISSION,
|
|
Services.perms.ALLOW_ACTION
|
|
);
|
|
let url = getRootDirectory(gTestPath) + "hybrid_content.html";
|
|
url = url.replace("chrome://mochitests/content", testHost);
|
|
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
|
|
|
// Try to use the API. Also record a content event from outside HCT: we'll
|
|
// use this event to know when we can stop waiting for the hybrid content data.
|
|
const TEST_CONTENT_EVENT = ["telemetry.test", "main_and_content", "object1"];
|
|
Services.telemetry.setEventRecordingEnabled("telemetry.test", true);
|
|
await ContentTask.spawn(
|
|
newTab.linkedBrowser,
|
|
[TEST_CONTENT_EVENT],
|
|
([testContentEvent]) => {
|
|
// Call the hybrid content telemetry API.
|
|
let contentWin = Cu.waiveXrays(content);
|
|
contentWin.testRegisterEvents(testContentEvent[0], JSON.stringify({}));
|
|
// Record from the usual telemetry API a "canary" event.
|
|
Services.telemetry.recordEvent(...testContentEvent);
|
|
}
|
|
);
|
|
|
|
// Let's support both e10s/non-e10s testing.
|
|
const processName = Services.appinfo.browserTabsRemoteAutostart
|
|
? "content"
|
|
: "parent";
|
|
await waitForEvent(processName, TEST_CONTENT_EVENT);
|
|
|
|
// This is needed otherwise the test will fail due to missing test passes.
|
|
ok(true, "The untrusted HTTP page was not able to use the API.");
|
|
|
|
// Finally clean up the listener.
|
|
BrowserTestUtils.removeTab(newTab);
|
|
PermissionTestUtils.remove(testHttpUri, HC_PERMISSION);
|
|
Services.mm.removeMessageListener(messageName, makeTestFail);
|
|
Services.telemetry.setEventRecordingEnabled("telemetry.test", false);
|
|
});
|
|
|
|
add_task(async function test_secure_non_whitelisted_origin() {
|
|
Services.telemetry.clearEvents();
|
|
|
|
// Install a custom handler that intercepts hybrid content telemetry messages
|
|
// and makes the test fail. We don't expect any message from non whitelisted pages.
|
|
const messageName = "HybridContentTelemetry:onTelemetryMessage";
|
|
let makeTestFail = () => ok(false, `Received an unexpected ${messageName}.`);
|
|
Services.mm.addMessageListener(messageName, makeTestFail);
|
|
|
|
// Try to use the API on a secure host but don't give the page enough privileges.
|
|
const testHost = "https://example.org";
|
|
let url = getRootDirectory(gTestPath) + "hybrid_content.html";
|
|
url = url.replace("chrome://mochitests/content", testHost);
|
|
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
|
|
|
// Try to use the API. Also record a content event from outside HCT: we'll
|
|
// use this event to know when we can stop waiting for the hybrid content data.
|
|
const TEST_CONTENT_EVENT = ["telemetry.test", "main_and_content", "object1"];
|
|
Services.telemetry.setEventRecordingEnabled("telemetry.test", true);
|
|
await ContentTask.spawn(
|
|
newTab.linkedBrowser,
|
|
[TEST_CONTENT_EVENT],
|
|
([testContentEvent]) => {
|
|
// Call the hybrid content telemetry API.
|
|
let contentWin = Cu.waiveXrays(content);
|
|
contentWin.testRegisterEvents(testContentEvent[0], JSON.stringify({}));
|
|
// Record from the usual telemetry API a "canary" event.
|
|
Services.telemetry.recordEvent(...testContentEvent);
|
|
}
|
|
);
|
|
|
|
// Let's support both e10s/non-e10s testing.
|
|
const processName = Services.appinfo.browserTabsRemoteAutostart
|
|
? "content"
|
|
: "parent";
|
|
await waitForEvent(processName, TEST_CONTENT_EVENT);
|
|
|
|
// This is needed otherwise the test will fail due to missing test passes.
|
|
ok(true, "The HTTPS page without permission was not able to use the API.");
|
|
|
|
// Finally clean up the listener.
|
|
BrowserTestUtils.removeTab(newTab);
|
|
Services.mm.removeMessageListener(messageName, makeTestFail);
|
|
Services.telemetry.setEventRecordingEnabled("telemetry.test", false);
|
|
});
|
|
|
|
add_task(async function test_trusted_disabled_hybrid_telemetry() {
|
|
Services.telemetry.clearEvents();
|
|
|
|
// This test requires hybrid content telemetry to be disabled.
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [[TelemetryUtils.Preferences.HybridContentEnabled, false]],
|
|
});
|
|
|
|
// Install a custom handler that intercepts hybrid content telemetry messages
|
|
// and makes the test fail. We don't expect any message when the API is disabled.
|
|
const messageName = "HybridContentTelemetry:onTelemetryMessage";
|
|
let makeTestFail = () => ok(false, `Received an unexpected ${messageName}.`);
|
|
Services.mm.addMessageListener(messageName, makeTestFail);
|
|
|
|
// Try to use the API on a secure host.
|
|
const testHost = "https://example.org";
|
|
let testHttpsUri = Services.io.newURI(testHost);
|
|
PermissionTestUtils.add(
|
|
testHttpsUri,
|
|
HC_PERMISSION,
|
|
Services.perms.ALLOW_ACTION
|
|
);
|
|
let url = getRootDirectory(gTestPath) + "hybrid_content.html";
|
|
url = url.replace("chrome://mochitests/content", testHost);
|
|
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
|
|
|
// Try to use the API. Also record a content event from outside HCT: we'll
|
|
// use this event to know when we can stop waiting for the hybrid content data.
|
|
const TEST_CONTENT_EVENT = ["telemetry.test", "main_and_content", "object1"];
|
|
Services.telemetry.setEventRecordingEnabled("telemetry.test", true);
|
|
await ContentTask.spawn(
|
|
newTab.linkedBrowser,
|
|
[TEST_CONTENT_EVENT],
|
|
([testContentEvent]) => {
|
|
// Call the hybrid content telemetry API.
|
|
let contentWin = Cu.waiveXrays(content);
|
|
contentWin.testRegisterEvents(testContentEvent[0], JSON.stringify({}));
|
|
// Record from the usual telemetry API a "canary" event.
|
|
Services.telemetry.recordEvent(...testContentEvent);
|
|
}
|
|
);
|
|
|
|
// Let's support both e10s/non-e10s testing.
|
|
const processName = Services.appinfo.browserTabsRemoteAutostart
|
|
? "content"
|
|
: "parent";
|
|
await waitForEvent(processName, TEST_CONTENT_EVENT);
|
|
|
|
// This is needed otherwise the test will fail due to missing test passes.
|
|
ok(true, "There were no unintended hybrid content API usages.");
|
|
|
|
// Finally clean up the listener.
|
|
await SpecialPowers.popPrefEnv();
|
|
BrowserTestUtils.removeTab(newTab);
|
|
PermissionTestUtils.remove(testHttpsUri, HC_PERMISSION);
|
|
Services.mm.removeMessageListener(messageName, makeTestFail);
|
|
Services.telemetry.setEventRecordingEnabled("telemetry.test", false);
|
|
});
|
|
|
|
add_task(async function test_hybrid_content_with_iframe() {
|
|
Services.telemetry.clearEvents();
|
|
|
|
// Open a trusted page that can use in the HCT in a new tab.
|
|
const testOuterPageHost = "https://example.com";
|
|
let testHttpsUri = Services.io.newURI(testOuterPageHost);
|
|
PermissionTestUtils.add(
|
|
testHttpsUri,
|
|
HC_PERMISSION,
|
|
Services.perms.ALLOW_ACTION
|
|
);
|
|
let url = getRootDirectory(gTestPath) + "hybrid_content.html";
|
|
let outerUrl = url.replace("chrome://mochitests/content", testOuterPageHost);
|
|
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, outerUrl);
|
|
|
|
// Install a custom handler that intercepts hybrid content telemetry messages
|
|
// and makes the test fail. This needs to be done after the tab is opened.
|
|
const messageName = "HybridContentTelemetry:onTelemetryMessage";
|
|
let makeTestFail = () => ok(false, `Received an unexpected ${messageName}.`);
|
|
Services.mm.addMessageListener(messageName, makeTestFail);
|
|
|
|
// Enable recording the canary event.
|
|
const TEST_CONTENT_EVENT = ["telemetry.test", "main_and_content", "object1"];
|
|
Services.telemetry.setEventRecordingEnabled("telemetry.test", true);
|
|
|
|
// Add an iframe to the test page. The URI in the iframe should not be able
|
|
// to use HCT to the the missing privileges.
|
|
const testHost = "https://example.org";
|
|
let iframeUrl = url.replace("chrome://mochitests/content", testHost);
|
|
await ContentTask.spawn(
|
|
newTab.linkedBrowser,
|
|
[iframeUrl, TEST_CONTENT_EVENT],
|
|
async function([iframeUrl, testContentEvent]) {
|
|
let doc = content.document;
|
|
let iframe = doc.createElement("iframe");
|
|
let promiseIframeLoaded = ContentTaskUtils.waitForEvent(
|
|
iframe,
|
|
"load",
|
|
false
|
|
);
|
|
iframe.src = iframeUrl;
|
|
doc.body.insertBefore(iframe, doc.body.firstChild);
|
|
await promiseIframeLoaded;
|
|
|
|
// Call the hybrid content telemetry API.
|
|
let contentWin = Cu.waiveXrays(iframe.contentWindow);
|
|
contentWin.testRegisterEvents(testContentEvent[0], JSON.stringify({}));
|
|
|
|
// Record from the usual telemetry API a "canary" event.
|
|
Services.telemetry.recordEvent(...testContentEvent);
|
|
}
|
|
);
|
|
|
|
// Let's support both e10s/non-e10s testing.
|
|
const processName = Services.appinfo.browserTabsRemoteAutostart
|
|
? "content"
|
|
: "parent";
|
|
await waitForEvent(processName, TEST_CONTENT_EVENT);
|
|
|
|
// This is needed otherwise the test will fail due to missing test passes.
|
|
ok(
|
|
true,
|
|
"There were no unintended hybrid content API usages from the iframe."
|
|
);
|
|
|
|
// Cleanup permissions and remove the tab.
|
|
BrowserTestUtils.removeTab(newTab);
|
|
Services.mm.removeMessageListener(messageName, makeTestFail);
|
|
PermissionTestUtils.remove(testHttpsUri, HC_PERMISSION);
|
|
Services.telemetry.setEventRecordingEnabled("telemetry.test", false);
|
|
});
|
|
|
|
add_task(async function test_hybrid_content_recording() {
|
|
const testHost = "https://example.org";
|
|
const TEST_EVENT_CATEGORY = "telemetry.test.hct";
|
|
const RECORDED_TEST_EVENTS = [
|
|
[TEST_EVENT_CATEGORY, "test1", "object1"],
|
|
[
|
|
TEST_EVENT_CATEGORY,
|
|
"test2",
|
|
"object1",
|
|
null,
|
|
{ key1: "foo", key2: "bar" },
|
|
],
|
|
[TEST_EVENT_CATEGORY, "test2", "object1", "some value"],
|
|
[TEST_EVENT_CATEGORY, "test1", "object1", null, null],
|
|
[TEST_EVENT_CATEGORY, "test1", "object1", "", null],
|
|
];
|
|
const NON_RECORDED_TEST_EVENTS = [
|
|
[TEST_EVENT_CATEGORY, "unknown", "unknown"],
|
|
];
|
|
|
|
Services.telemetry.clearEvents();
|
|
|
|
// Give the test host enough privileges to use the API and open the test page.
|
|
let testHttpsUri = Services.io.newURI(testHost);
|
|
PermissionTestUtils.add(
|
|
testHttpsUri,
|
|
HC_PERMISSION,
|
|
Services.perms.ALLOW_ACTION
|
|
);
|
|
let url = getRootDirectory(gTestPath) + "hybrid_content.html";
|
|
url = url.replace("chrome://mochitests/content", testHost);
|
|
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
|
|
|
// Register some events and record them in Telemetry.
|
|
await ContentTask.spawn(
|
|
newTab.linkedBrowser,
|
|
[TEST_EVENT_CATEGORY, RECORDED_TEST_EVENTS, NON_RECORDED_TEST_EVENTS],
|
|
([eventCategory, recordedTestEvents, nonRecordedTestEvents]) => {
|
|
let contentWin = Cu.waiveXrays(content);
|
|
|
|
// If we tried to call contentWin.Mozilla.ContentTelemetry.* functions
|
|
// and pass non-string parameters, |waiveXrays| would complain and not
|
|
// let us access them. To work around this, we generate test functions
|
|
// in the test HTML file and unwrap the passed JSON blob there.
|
|
contentWin.testRegisterEvents(
|
|
eventCategory,
|
|
JSON.stringify({
|
|
// Event with only required fields.
|
|
test1: {
|
|
methods: ["test1"],
|
|
objects: ["object1"],
|
|
},
|
|
// Event with extra_keys.
|
|
test2: {
|
|
methods: ["test2", "test2b"],
|
|
objects: ["object1"],
|
|
extra_keys: ["key1", "key2"],
|
|
},
|
|
})
|
|
);
|
|
|
|
// Record some valid events.
|
|
recordedTestEvents.forEach(e =>
|
|
contentWin.testRecordEvents(JSON.stringify(e))
|
|
);
|
|
|
|
// Test recording an unknown event. The Telemetry API itself is supposed to throw,
|
|
// but we catch that in hybrid content telemetry and log an error message.
|
|
nonRecordedTestEvents.forEach(e =>
|
|
contentWin.testRecordEvents(JSON.stringify(e))
|
|
);
|
|
}
|
|
);
|
|
|
|
// Wait for the data to be in the snapshot, then get the Telemetry data.
|
|
await waitForProcessesEvents(["dynamic"]);
|
|
let snapshot = Services.telemetry.snapshotEvents(
|
|
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS
|
|
);
|
|
|
|
// Check that the dynamically register events made it to the snapshot.
|
|
ok(
|
|
"dynamic" in snapshot,
|
|
"The snapshot must contain the 'dynamic' process section"
|
|
);
|
|
let dynamicEvents = snapshot.dynamic.map(e => e.slice(1));
|
|
is(
|
|
dynamicEvents.length,
|
|
RECORDED_TEST_EVENTS.length,
|
|
"Should match expected event count."
|
|
);
|
|
for (let i = 0; i < RECORDED_TEST_EVENTS.length; ++i) {
|
|
SimpleTest.isDeeply(
|
|
dynamicEvents[i],
|
|
removeTrailingInvalidEntry(RECORDED_TEST_EVENTS[i]),
|
|
"Should have recorded the expected event."
|
|
);
|
|
}
|
|
|
|
// Cleanup permissions and remove the tab.
|
|
BrowserTestUtils.removeTab(newTab);
|
|
PermissionTestUtils.remove(testHttpsUri, HC_PERMISSION);
|
|
});
|
|
|
|
add_task(async function test_can_upload() {
|
|
const testHost = "https://example.org";
|
|
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [[TelemetryUtils.Preferences.FhrUploadEnabled, true]],
|
|
});
|
|
|
|
// Give the test host enough privileges to use the API and open the test page.
|
|
let testHttpsUri = Services.io.newURI(testHost);
|
|
PermissionTestUtils.add(
|
|
testHttpsUri,
|
|
HC_PERMISSION,
|
|
Services.perms.ALLOW_ACTION
|
|
);
|
|
let url = getRootDirectory(gTestPath) + "hybrid_content.html";
|
|
url = url.replace("chrome://mochitests/content", testHost);
|
|
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
|
|
|
// Check that CanUpload reports the correct value.
|
|
await ContentTask.spawn(newTab.linkedBrowser, {}, async function() {
|
|
let contentWin = Cu.waiveXrays(content);
|
|
|
|
await contentWin.Mozilla.ContentTelemetry.initPromise();
|
|
|
|
// We don't need to pass any parameter, we can safely call Mozilla.ContentTelemetry.
|
|
let canUpload = contentWin.Mozilla.ContentTelemetry.canUpload();
|
|
ok(
|
|
canUpload,
|
|
"CanUpload must report 'true' if the preference has that value."
|
|
);
|
|
});
|
|
|
|
// Flip the pref and check again.
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [[TelemetryUtils.Preferences.FhrUploadEnabled, false]],
|
|
});
|
|
await ContentTask.spawn(newTab.linkedBrowser, {}, async function() {
|
|
let contentWin = Cu.waiveXrays(content);
|
|
await contentWin.Mozilla.ContentTelemetry.initPromise();
|
|
let canUpload = contentWin.Mozilla.ContentTelemetry.canUpload();
|
|
ok(
|
|
!canUpload,
|
|
"CanUpload must report 'false' if the preference has that value."
|
|
);
|
|
});
|
|
|
|
// Cleanup permissions and remove the tab.
|
|
BrowserTestUtils.removeTab(newTab);
|
|
PermissionTestUtils.remove(testHttpsUri, HC_PERMISSION);
|
|
});
|
|
|
|
add_task(async function test_init_rejects() {
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [[TelemetryUtils.Preferences.FhrUploadEnabled, true]],
|
|
});
|
|
|
|
// Give the test host no privilege: init() will throw.
|
|
const testHostNoPrivilege = "https://example.org";
|
|
let url = getRootDirectory(gTestPath) + "hybrid_content.html";
|
|
url = url.replace("chrome://mochitests/content", testHostNoPrivilege);
|
|
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
|
|
|
// Check that CanUpload reports false if we threw. We don't block on spawning
|
|
// the content task, as we want to spawn another tab that loads an URI with HCT
|
|
// privileges in order to make sure that init works ok there. We want both pages
|
|
// to load in parallel.
|
|
let page1Promise = ContentTask.spawn(
|
|
newTab.linkedBrowser,
|
|
{},
|
|
async function() {
|
|
let contentWin = Cu.waiveXrays(content);
|
|
|
|
await Assert.rejects(
|
|
contentWin.Mozilla.ContentTelemetry.initPromise(),
|
|
/Origin not trusted/,
|
|
"The init promise must reject if the page has no HCT permission."
|
|
);
|
|
|
|
// We don't need to pass any parameter, we can safely call Mozilla.ContentTelemetry.
|
|
let canUpload = contentWin.Mozilla.ContentTelemetry.canUpload();
|
|
ok(!canUpload, "CanUpload must report 'false' if init failed.");
|
|
}
|
|
);
|
|
|
|
// Give the test host HCT privileges and test that init doesn't throw.
|
|
const testHostPrivileges = "https://example.com";
|
|
let testUrlPrivileges = Services.io.newURI(testHostPrivileges);
|
|
PermissionTestUtils.add(
|
|
testUrlPrivileges,
|
|
HC_PERMISSION,
|
|
Services.perms.ALLOW_ACTION
|
|
);
|
|
let urlWithPrivs = getRootDirectory(gTestPath) + "hybrid_content.html";
|
|
urlWithPrivs = urlWithPrivs.replace(
|
|
"chrome://mochitests/content",
|
|
testHostPrivileges
|
|
);
|
|
let otherTab = await BrowserTestUtils.openNewForegroundTab(
|
|
gBrowser,
|
|
urlWithPrivs
|
|
);
|
|
|
|
// Check that CanUpload reports the correct value.
|
|
let page2Promise = ContentTask.spawn(
|
|
otherTab.linkedBrowser,
|
|
{},
|
|
async function() {
|
|
let contentWin = Cu.waiveXrays(content);
|
|
|
|
await contentWin.Mozilla.ContentTelemetry.initPromise();
|
|
|
|
// We don't need to pass any parameter, we can safely call Mozilla.ContentTelemetry.
|
|
let canUpload = contentWin.Mozilla.ContentTelemetry.canUpload();
|
|
ok(
|
|
canUpload,
|
|
"CanUpload must report the expected value if init succeeded."
|
|
);
|
|
}
|
|
);
|
|
|
|
await Promise.all([page1Promise, page2Promise]);
|
|
|
|
// Cleanup permissions and remove the tab.
|
|
BrowserTestUtils.removeTab(newTab);
|
|
BrowserTestUtils.removeTab(otherTab);
|
|
PermissionTestUtils.remove(testUrlPrivileges, HC_PERMISSION);
|
|
});
|