What is the best way to retrieve all WebSockets present on the current page utilizing Puppeteer in a TypeScript environment?

Is there a way to efficiently gather all WebSockets on the current page in order to easily send messages through them? I've been attempting the following:

const prototype = await page.evaluateHandle("WebSocket.prototype");
    var socketInstances = await page.queryObjects(prototype);
    await page.evaluate((instances:Array<WebSocket>) => {
            instances[0].send("message");
        }, socketInstances);

const cdp = await page.createCDPSession();
    await cdp.send('Network.enable');
    await cdp.send('Page.enable');

cdp.on("Network.webSocketFrameReceived", response => console.log(response));
    cdp.on('Network.webSocketFrameSent', response => console.log(response));

While this allows me to monitor received WebSocket messages, I'm struggling to find a more efficient way to send messages through these sockets without having to call page.evaluate each time. I attempted to reference the WebSockets like so:

await cdp.send('Runtime.enable');
const { exceptionDetails, result: remoteObject } = await cdp.send('Runtime.evaluate', {
        expression: 'WebSocket'
      });
await cdp.send("Runtime.queryObjects", {prototypeObjectId: remoteObject.objectId});

However, this approach doesn't seem to work as desired. Does anyone have any thoughts on a simpler or alternate method to achieve this?

Answer №1

Encountering a similar issue, I wasn't completely satisfied with the solution I came across. However, it does get the job done. I opted for playwright over puppeteer, although CDP shouldn't rely on the specific chromium wrapper being used.

const dtClient = await page.context().newCDPSession(page);
await dtClient.send('Network.enable');

dtClient.on('Network.webSocketCreated', async ({requestId, url}) => {
    const { result } = await dtClient.send('Runtime.evaluate', {expression: 'WebSocket.prototype'});

    const { objects } = await dtClient.send("Runtime.queryObjects", {prototypeObjectId: result.objectId!});

    await dtClient.send('Runtime.callFunctionOn', {
        objectId: objects.objectId,
        functionDeclaration: `function () {
            const ws = this[0];
            setTimeout(() => {
            ws.send('[1, "Testing"]');
            }, 500)
        }`
    });
});

this in the context of the function provided to Runtime.callFunctionOn refers to the object specified by the objectId. Specifically, an Array object that holds references to WebSockets. It's important to note that the WebSocket may still be in the CONNECTING state when callFunctionOn is triggered.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unexpected unhandled_exception_processor in Google Chrome

I keep encountering a strange uncaught exception handler in Google Chrome. After updating all follow buttons to download JavaScript asynchronously, I noticed an error in the content.js file mentioned in the exception message which advises against polluting ...

Closing Modals in ReactJS Hooks with Parent and Child Components

I have a scenario where I am successfully opening a Model (child Component) on Button Click from the Parent Component. However, the issue arises when trying to close the modal as it displays an error message: Uncaught TypeError: setOpen is not a functio ...

Issue with Bootstrap 4.6 Collapse Feature Failing to Toggle (Opening or Closing)

Take a look at the code snippet below. I'm facing an issue with my Bootstrap 4.6 collapse feature not opening when I click the button. Interestingly, running $("#30-50hp").collapse('show') in the JavaScript console does make it op ...

Tips for setting background colors as a prop for Material UI cards in React JS

Currently utilizing the Material UI next framework to construct a wrapper for the card component. This customized wrapper allows for personalization of the component. I have successfully extended the component so that the title and image within the card ca ...

Using a variety of objects in TypeScript arrays

How to effectively implement a superior class in TypeScript for an array containing diverse objects that inherit from the same class, without triggering errors? This is my attempt: interface IVehicle{ modelName: string } interface ICar extends IVehi ...

Determining Visibility in Three.js: A Guide to Checking if an Object is in View of the Camera

Struggling to determine the best method for checking if an Object3d is visible to the camera. Imagine a sphere in the center of the screen with cubes randomly placed on its surface. I need a way to identify which cubes are visible (on the front half of th ...

Guide to specifying a type as optional based on specific criteria

In coding, there exists a certain type that is defined as follows: type PropsType = { dellSelectedOption: (id: string, idOptions: string[]) => void; ownFilterData: Array<ActiveFilterAndPredFilterDataType>; watchOverflow: boolean; childre ...

Leverage the power of ExpressJS by seamlessly sharing route middleware between routes

Looking for a way to share multiple route middleware across various routes and controllers? Check out this setup: In app.js, we require ./routes/index.js: // load fs module var fs = require('fs'); // import routing files module.exports = func ...

Leveraging AJAX for managing multiple selection options without the need for a submit button

Currently, I have a page featuring two select buttons. Whenever both are selected, the page should update automatically. Furthermore, each time a new option is chosen, the page needs to keep updating on its own. Below is my HTML code: <form action="" m ...

Enhance your UI experience with a beautifully styled button using Material-

I was using a Material UI button with a purple background. <Button component={Link} to={link} style={{ background: '#6c74cc', borderRadius: 3, border: 0, color: 'white', heig ...

Facing the issue once more - Angular displaying "Http failure response for... 0 Unknown Error"

I have been researching extensively on this issue, particularly on Stack Overflow. Many of the responses point to it being a CORS problem, but I am uncertain if that is the case in my situation. Therefore, I am reaching out for help once again and would gr ...

Utilize JQuery to implement fading effects for clicked elements in a webpage

I've been using a rollover JavaScript plugin to create smooth transitional effects when users hover over clickable page elements. Everything was going well until I decided to switch to making ajax calls instead of page loads for dynamic content. The p ...

How can I use the .filter() method in JavaScript to retrieve the last X elements/indices from an array?

I am searching for a method to sift through an array and retrieve the last x number (or most recently added) of elements/indices from that array. While I understand that .pop() may be a possibility, I am uncertain about how to integrate ...

I keep encountering an error in the where clause when trying to update MySQL. What could be

I encountered an issue stating Unknown column 'CR0001' in 'where clause' while executing my code. Strangely, the error seems to be related to the id_scooter column rather than CR0001. Below is the snippet of my code: var update = "UPDA ...

Create a library with CSS files added, excluding any test files

As I develop a React library, I've encountered an issue where the CSS files are being ignored during the build process. In an attempt to resolve this, I included the --copy-files flag in the build script, which successful copied the CSS files but also ...

Vue3 with Typescript may either display an error message or remain empty when handling props

I've been attempting to utilize the default Quasar card component in order to display data received from props. Unfortunately, I haven't had any success as my component remains empty and I keep encountering various errors with each attempt. Rece ...

Encountering a problem: "The '$acknowledged' field name is invalid as an operator in the aggregation query."

I'm attempting to retrieve the most recent messages between User A and any other user. Unfortunately, I am encountering an error message that states: The field name '$acknowledged' cannot be an operator name I am unsure of what mistake I ...

Adding a new row to a Bootstrap table while maintaining the consistent style

Is there a way to dynamically add a new table row with different styling using jQuery? I'm facing this particular issue and need help in solving it. Below, I have included some screenshots of my code and the view for better understanding. Here is the ...

Navigating through props provided within a setup function in Vuejs using the Composition API

I am facing an issue when trying to pass an object into a child component using props in the Composition API setup function of Vue. Instead of utilizing 'Abe', I want to run a query from firebase based on the displayName property of the user. As ...

Is the "mocha" command line tool requires quotation marks for specifying test files?

Here are some examples of npm scripts: "scripts": { "test": "mocha tools/testSetup.js src/**/*.spec.js" } "scripts": { "test": "mocha tools/testSetup.js 'src/**/*.spec.js'" } "scripts": { "test": "mocha tools/testSetup.js \"src/**/* ...