summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands/resource/tests/browser_resources_client_caching.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/commands/resource/tests/browser_resources_client_caching.js')
-rw-r--r--devtools/shared/commands/resource/tests/browser_resources_client_caching.js376
1 files changed, 376 insertions, 0 deletions
diff --git a/devtools/shared/commands/resource/tests/browser_resources_client_caching.js b/devtools/shared/commands/resource/tests/browser_resources_client_caching.js
new file mode 100644
index 0000000000..a10c74e298
--- /dev/null
+++ b/devtools/shared/commands/resource/tests/browser_resources_client_caching.js
@@ -0,0 +1,376 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"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];
+ ok(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();
+ });
+ }
+}