summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands/resource/tests/browser_resources_websocket.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/commands/resource/tests/browser_resources_websocket.js')
-rw-r--r--devtools/shared/commands/resource/tests/browser_resources_websocket.js245
1 files changed, 245 insertions, 0 deletions
diff --git a/devtools/shared/commands/resource/tests/browser_resources_websocket.js b/devtools/shared/commands/resource/tests/browser_resources_websocket.js
new file mode 100644
index 0000000000..601620bc59
--- /dev/null
+++ b/devtools/shared/commands/resource/tests/browser_resources_websocket.js
@@ -0,0 +1,245 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test the ResourceCommand API around WEBSOCKET.
+
+const ResourceCommand = require("resource://devtools/shared/commands/resource/resource-command.js");
+
+const IS_NUMBER = "IS_NUMBER";
+const SHOULD_EXIST = "SHOULD_EXIST";
+
+const targets = {
+ TOP_LEVEL_DOCUMENT: "top-level-document",
+ IN_PROCESS_IFRAME: "in-process-frame",
+ OUT_PROCESS_IFRAME: "out-process-frame",
+};
+
+add_task(async function () {
+ info("Testing the top-level document");
+ await testWebsocketResources(targets.TOP_LEVEL_DOCUMENT);
+ info("Testing the in-process iframe");
+ await testWebsocketResources(targets.IN_PROCESS_IFRAME);
+ info("Testing the out-of-process iframe");
+ await testWebsocketResources(targets.OUT_PROCESS_IFRAME);
+});
+
+async function testWebsocketResources(target) {
+ const tab = await addTab(URL_ROOT_SSL + "websocket_frontend.html");
+ const { client, resourceCommand, targetCommand } = await initResourceCommand(
+ tab
+ );
+
+ const availableResources = [];
+ function onResourceAvailable(resources) {
+ availableResources.push(...resources);
+ }
+
+ await resourceCommand.watchResources([resourceCommand.TYPES.WEBSOCKET], {
+ onAvailable: onResourceAvailable,
+ });
+
+ info("Check available resources at initial");
+ is(
+ availableResources.length,
+ 0,
+ "Length of existing resources is correct at initial"
+ );
+
+ info("Check resource of opening websocket");
+ await executeFunctionInContext(tab, target, "openConnection");
+
+ await waitUntil(() => availableResources.length === 1);
+
+ const httpChannelId = availableResources[0].httpChannelId;
+
+ ok(httpChannelId, "httpChannelId is present in the resource");
+
+ assertResource(availableResources[0], {
+ wsMessageType: "webSocketOpened",
+ effectiveURI:
+ "wss://example.com/browser/devtools/shared/commands/resource/tests/websocket_backend",
+ extensions: "permessage-deflate",
+ protocols: "",
+ });
+
+ info("Check resource of sending/receiving the data via websocket");
+ await executeFunctionInContext(tab, target, "sendData", "test");
+
+ await waitUntil(() => availableResources.length === 3);
+
+ assertResource(availableResources[1], {
+ wsMessageType: "frameSent",
+ httpChannelId,
+ data: {
+ type: "sent",
+ payload: "test",
+ timeStamp: SHOULD_EXIST,
+ finBit: SHOULD_EXIST,
+ rsvBit1: SHOULD_EXIST,
+ rsvBit2: SHOULD_EXIST,
+ rsvBit3: SHOULD_EXIST,
+ opCode: SHOULD_EXIST,
+ mask: SHOULD_EXIST,
+ maskBit: SHOULD_EXIST,
+ },
+ });
+ assertResource(availableResources[2], {
+ wsMessageType: "frameReceived",
+ httpChannelId,
+ data: {
+ type: "received",
+ payload: "test",
+ timeStamp: SHOULD_EXIST,
+ finBit: SHOULD_EXIST,
+ rsvBit1: SHOULD_EXIST,
+ rsvBit2: SHOULD_EXIST,
+ rsvBit3: SHOULD_EXIST,
+ opCode: SHOULD_EXIST,
+ mask: SHOULD_EXIST,
+ maskBit: SHOULD_EXIST,
+ },
+ });
+
+ info("Check resource of closing websocket");
+ await executeFunctionInContext(tab, target, "closeConnection");
+
+ await waitUntil(() => availableResources.length === 6);
+ assertResource(availableResources[3], {
+ wsMessageType: "frameSent",
+ httpChannelId,
+ data: {
+ type: "sent",
+ payload: "",
+ timeStamp: SHOULD_EXIST,
+ finBit: SHOULD_EXIST,
+ rsvBit1: SHOULD_EXIST,
+ rsvBit2: SHOULD_EXIST,
+ rsvBit3: SHOULD_EXIST,
+ opCode: SHOULD_EXIST,
+ mask: SHOULD_EXIST,
+ maskBit: SHOULD_EXIST,
+ },
+ });
+ assertResource(availableResources[4], {
+ wsMessageType: "frameReceived",
+ httpChannelId,
+ data: {
+ type: "received",
+ payload: "",
+ timeStamp: SHOULD_EXIST,
+ finBit: SHOULD_EXIST,
+ rsvBit1: SHOULD_EXIST,
+ rsvBit2: SHOULD_EXIST,
+ rsvBit3: SHOULD_EXIST,
+ opCode: SHOULD_EXIST,
+ mask: SHOULD_EXIST,
+ maskBit: SHOULD_EXIST,
+ },
+ });
+ assertResource(availableResources[5], {
+ wsMessageType: "webSocketClosed",
+ httpChannelId,
+ code: IS_NUMBER,
+ reason: "",
+ wasClean: true,
+ });
+
+ info("Check existing resources");
+ const existingResources = [];
+
+ function onExsistingResourceAvailable(resources) {
+ existingResources.push(...resources);
+ }
+
+ await resourceCommand.watchResources([resourceCommand.TYPES.WEBSOCKET], {
+ onAvailable: onExsistingResourceAvailable,
+ });
+
+ is(
+ availableResources.length,
+ existingResources.length,
+ "Length of existing resources is correct"
+ );
+
+ for (let i = 0; i < availableResources.length; i++) {
+ Assert.strictEqual(
+ availableResources[i],
+ existingResources[i],
+ `The ${i}th resource is correct`
+ );
+ }
+
+ await resourceCommand.unwatchResources([resourceCommand.TYPES.WEBSOCKET], {
+ onAvailable: onResourceAvailable,
+ });
+
+ await resourceCommand.unwatchResources([resourceCommand.TYPES.WEBSOCKET], {
+ onAvailable: onExsistingResourceAvailable,
+ });
+
+ targetCommand.destroy();
+ await client.close();
+ BrowserTestUtils.removeTab(tab);
+}
+
+/**
+ * Execute global functions defined in the correct
+ * target (top-level-window or frames) contexts.
+ *
+ * @param {object} tab The current window tab
+ * @param {string} target A string identify if we want to test the top level document or iframes
+ * @param {string} funcName The name of the global function which needs to be called.
+ * @param {*} funcArgs The arguments to pass to the global function
+ */
+async function executeFunctionInContext(tab, target, funcName, ...funcArgs) {
+ let browsingContext = tab.linkedBrowser.browsingContext;
+ // If the target is an iframe get its window global
+ if (target !== targets.TOP_LEVEL_DOCUMENT) {
+ browsingContext = await SpecialPowers.spawn(
+ tab.linkedBrowser,
+ [target],
+ async _target => {
+ const iframe = content.document.getElementById(_target);
+ return iframe.browsingContext;
+ }
+ );
+ }
+
+ return SpecialPowers.spawn(
+ browsingContext,
+ [funcName, funcArgs],
+ async (_funcName, _funcArgs) => {
+ await content.wrappedJSObject[_funcName](..._funcArgs);
+ }
+ );
+}
+
+function assertResource(resource, expected) {
+ is(
+ resource.resourceType,
+ ResourceCommand.TYPES.WEBSOCKET,
+ "Resource type is correct"
+ );
+
+ assertObject(resource, expected);
+}
+
+function assertObject(object, expected) {
+ for (const field in expected) {
+ if (typeof expected[field] === "object") {
+ assertObject(object[field], expected[field]);
+ } else if (expected[field] === SHOULD_EXIST) {
+ Assert.notStrictEqual(
+ object[field],
+ undefined,
+ `The value of ${field} exists`
+ );
+ } else if (expected[field] === IS_NUMBER) {
+ ok(!isNaN(object[field]), `The value of ${field} is number`);
+ } else {
+ is(object[field], expected[field], `The value of ${field} is correct`);
+ }
+ }
+}