diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /devtools/shared/commands/resource/tests/browser_resources_websocket.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/shared/commands/resource/tests/browser_resources_websocket.js')
-rw-r--r-- | devtools/shared/commands/resource/tests/browser_resources_websocket.js | 240 |
1 files changed, 240 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..6e73fa7b2e --- /dev/null +++ b/devtools/shared/commands/resource/tests/browser_resources_websocket.js @@ -0,0 +1,240 @@ +/* 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++) { + ok( + 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) { + ok(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`); + } + } +} |