Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
// Test the cache mechanism of the ResourceCommand.
const TEST_URI = "data:text/html;charset=utf-8,<!DOCTYPE html>Cache Test";
add_task(async function () {
info("Test whether multiple listener can get same cached resources");
const tab = await addTab(TEST_URI);
const { client, resourceCommand, targetCommand } = await initResourceCommand(
tab
);
info("Add messages as existing resources");
const messages = ["a", "b", "c"];
await logMessages(tab.linkedBrowser, messages);
info("Register first listener");
const cachedResources1 = [];
await resourceCommand.watchResources(
[resourceCommand.TYPES.CONSOLE_MESSAGE],
{
onAvailable(resources, { areExistingResources }) {
ok(areExistingResources, "All resources are already existing ones");
cachedResources1.push(...resources);
},
}
);
info("Register second listener");
const cachedResources2 = [];
await resourceCommand.watchResources(
[resourceCommand.TYPES.CONSOLE_MESSAGE],
{
onAvailable(resources, { areExistingResources }) {
ok(areExistingResources, "All resources are already existing ones");
cachedResources2.push(...resources);
},
}
);
assertContents(cachedResources1, messages);
assertResources(cachedResources2, cachedResources1);
targetCommand.destroy();
await client.close();
});
add_task(async function () {
info(
"Test whether the cache is reflecting existing resources and additional resources"
);
const tab = await addTab(TEST_URI);
const { client, resourceCommand, targetCommand } = await initResourceCommand(
tab
);
info("Add messages as existing resources");
const existingMessages = ["a", "b", "c"];
await logMessages(tab.linkedBrowser, existingMessages);
info("Register first listener to get all available resources");
const availableResources = [];
// We first get notified about existing resources
let shouldBeExistingResources = true;
await resourceCommand.watchResources(
[resourceCommand.TYPES.CONSOLE_MESSAGE],
{
onAvailable(resources, { areExistingResources }) {
is(
areExistingResources,
shouldBeExistingResources,
"areExistingResources flag is correct"
);
availableResources.push(...resources);
},
}
);
// Then, we are notified about, new, live ones
shouldBeExistingResources = false;
info("Add messages as additional resources");
const additionalMessages = ["d", "e"];
await logMessages(tab.linkedBrowser, additionalMessages);
info("Wait until onAvailable is called expected times");
const allMessages = [...existingMessages, ...additionalMessages];
await waitUntil(() => availableResources.length === allMessages.length);
info("Register second listener to get the cached resources");
const cachedResources = [];
await resourceCommand.watchResources(
[resourceCommand.TYPES.CONSOLE_MESSAGE],
{
onAvailable(resources, { areExistingResources }) {
ok(areExistingResources, "All resources are already existing ones");
cachedResources.push(...resources);
},
}
);
assertContents(availableResources, allMessages);
assertResources(cachedResources, availableResources);
targetCommand.destroy();
await client.close();
});
add_task(async function () {
info("Test whether the cache is cleared when navigation");
const tab = await addTab(TEST_URI);
const { client, resourceCommand, targetCommand } = await initResourceCommand(
tab
);
info("Add messages as existing resources");
const existingMessages = ["a", "b", "c"];
await logMessages(tab.linkedBrowser, existingMessages);
info("Register first listener");
await resourceCommand.watchResources(
[resourceCommand.TYPES.CONSOLE_MESSAGE],
{
onAvailable: () => {},
}
);
info("Reload the page");
await BrowserTestUtils.reloadTab(tab);
info("Register second listener");
const cachedResources = [];
await resourceCommand.watchResources(
[resourceCommand.TYPES.CONSOLE_MESSAGE],
{
onAvailable: resources => cachedResources.push(...resources),
}
);
is(cachedResources.length, 0, "The cache in ResourceCommand is cleared");
targetCommand.destroy();
await client.close();
});
add_task(async function () {
info("Test with multiple resource types");
const tab = await addTab(TEST_URI);
const { client, resourceCommand, targetCommand } = await initResourceCommand(
tab
);
info("Register first listener to get all available resources");
const availableResources = [];
await resourceCommand.watchResources(
[
resourceCommand.TYPES.CONSOLE_MESSAGE,
resourceCommand.TYPES.ERROR_MESSAGE,
],
{
onAvailable: resources => availableResources.push(...resources),
}
);
info("Add messages as console message");
const consoleMessages1 = ["a", "b", "c"];
await logMessages(tab.linkedBrowser, consoleMessages1);
info("Add message as error message");
const errorMessages = ["document.doTheImpossible();"];
await triggerErrors(tab.linkedBrowser, errorMessages);
info("Add messages as console message again");
const consoleMessages2 = ["d", "e"];
await logMessages(tab.linkedBrowser, consoleMessages2);
info("Wait until the getting all available resources");
const totalResourceCount =
consoleMessages1.length + errorMessages.length + consoleMessages2.length;
await waitUntil(() => {
return availableResources.length === totalResourceCount;
});
info("Register listener to get the cached resources");
const cachedResources = [];
await resourceCommand.watchResources(
[
resourceCommand.TYPES.CONSOLE_MESSAGE,
resourceCommand.TYPES.ERROR_MESSAGE,
],
{
onAvailable: resources => cachedResources.push(...resources),
}
);
assertResources(cachedResources, availableResources);
targetCommand.destroy();
await client.close();
});
add_task(async function () {
info("Test multiple listeners with/without ignoreExistingResources");
await testIgnoreExistingResources(true);
await testIgnoreExistingResources(false);
});
async function testIgnoreExistingResources(isFirstListenerIgnoreExisting) {
const tab = await addTab(TEST_URI);
const { client, resourceCommand, targetCommand } = await initResourceCommand(
tab
);
info("Add messages as existing resources");
const existingMessages = ["a", "b", "c"];
await logMessages(tab.linkedBrowser, existingMessages);
info("Register first listener");
const cachedResources1 = [];
await resourceCommand.watchResources(
[resourceCommand.TYPES.CONSOLE_MESSAGE],
{
onAvailable: resources => cachedResources1.push(...resources),
ignoreExistingResources: isFirstListenerIgnoreExisting,
}
);
info("Register second listener");
const cachedResources2 = [];
await resourceCommand.watchResources(
[resourceCommand.TYPES.CONSOLE_MESSAGE],
{
onAvailable: resources => cachedResources2.push(...resources),
ignoreExistingResources: !isFirstListenerIgnoreExisting,
}
);
const cachedResourcesWithFlag = isFirstListenerIgnoreExisting
? cachedResources1
: cachedResources2;
const cachedResourcesWithoutFlag = isFirstListenerIgnoreExisting
? cachedResources2
: cachedResources1;
info("Check the existing resources both listeners got");
assertContents(cachedResourcesWithFlag, []);
assertContents(cachedResourcesWithoutFlag, existingMessages);
info("Add messages as additional resources");
const additionalMessages = ["d", "e"];
await logMessages(tab.linkedBrowser, additionalMessages);
info("Wait until onAvailable is called expected times");
await waitUntil(
() => cachedResourcesWithFlag.length === additionalMessages.length
);
const allMessages = [...existingMessages, ...additionalMessages];
await waitUntil(
() => cachedResourcesWithoutFlag.length === allMessages.length
);
info("Check the resources after adding messages");
assertContents(cachedResourcesWithFlag, additionalMessages);
assertContents(cachedResourcesWithoutFlag, allMessages);
targetCommand.destroy();
await client.close();
}
add_task(async function () {
info("Test that onAvailable is not called with an empty resources array");
const tab = await addTab(TEST_URI);
const { client, resourceCommand, targetCommand } = await initResourceCommand(
tab
);
info("Register first listener to get all available resources");
const availableResources = [];
let onAvailableCallCount = 0;
const onAvailable = resources => {
ok(
!!resources.length,
"onAvailable is called with a non empty resources array"
);
availableResources.push(...resources);
onAvailableCallCount++;
};
await resourceCommand.watchResources(
[resourceCommand.TYPES.CONSOLE_MESSAGE],
{ onAvailable }
);
is(availableResources.length, 0, "availableResources array is empty");
is(onAvailableCallCount, 0, "onAvailable was never called");
info("Add messages as console message");
await logMessages(tab.linkedBrowser, ["expected message"]);
await waitUntil(() => availableResources.length === 1);
is(availableResources.length, 1, "availableResources array has one item");
is(onAvailableCallCount, 1, "onAvailable was called only once");
is(
availableResources[0].message.arguments[0],
"expected message",
"onAvailable was called with the expected resource"
);
resourceCommand.unwatchResources([resourceCommand.TYPES.CONSOLE_MESSAGE], {
onAvailable,
});
targetCommand.destroy();
await client.close();
});
function assertContents(resources, expectedMessages) {
is(
resources.length,
expectedMessages.length,
"Number of the resources is correct"
);
for (let i = 0; i < expectedMessages.length; i++) {
const resource = resources[i];
const message = resource.message.arguments[0];
const expectedMessage = expectedMessages[i];
is(message, expectedMessage, `The ${i}th content is correct`);
}
}
function assertResources(resources, expectedResources) {
is(
resources.length,
expectedResources.length,
"Number of the resources is correct"
);
for (let i = 0; i < resources.length; i++) {
const resource = resources[i];
const expectedResource = expectedResources[i];
Assert.strictEqual(
resource,
expectedResource,
`The ${i}th resource is correct`
);
}
}
function logMessages(browser, messages) {
return ContentTask.spawn(browser, { messages }, args => {
for (const message of args.messages) {
content.console.log(message);
}
});
}
async function triggerErrors(browser, errorScripts) {
for (const errorScript of errorScripts) {
await ContentTask.spawn(browser, errorScript, expr => {
const document = content.document;
const container = document.createElement("script");
document.body.appendChild(container);
container.textContent = expr;
container.remove();
});
}
}