Tips for updating the front end with the status of a lengthy playwright test

In the node backend, I have defined a route for test progress using SSE (https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events).

The URL initialization is happening on the frontend.

Below is the code snippet from the server route file:

let clients: Array<any> = [];

router.get('/progress', (req, res) => {
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      Connection: 'keep-alive',
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Headers': '*',
    });

    const data = `data: ${JSON.stringify('Starting the test')}\n\n`;

    res.write(data);

    const clientId = Date.now();

    const newClient = {
      id: clientId,
      res,
    };
    clients.push(newClient);
    req.on('close', () => {
      console.log(`${clientId} Connection closed`);
      clients = clients.filter((client) => client.id !== clientId);
    });
  });

On the frontend side, there is a button that when clicked triggers a playwright test in the node backend.

Considering this test can be long-running (looping through a csv and checking), I want to send the progress updates to the frontend periodically.

I attempted to import and use the sendEventsToAll function (defined in the server route file) as shown below within the test script, but it seems to not work:

export function sendEventsToAll(data: any) {
  console.log('SSE ' + data);
  clients.forEach((client) => client.res.write(`data: ${JSON.stringify(data)}\n\n`));
}

Could you suggest the best approach to address this issue or if there's a better alternative solution? Your insights are appreciated.

Thank you.

Answer №1

It appears that your route /progress is configured to send Server-Sent Events (SSE) to clients. Instead of directly using the sendEventsToAll function, you can create a separate function specifically for sending progress updates:

    let clientsList: Array<any> = [];

router.get('/progress', (req, res) => {
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      Connection: 'keep-alive',
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Headers': '*',
    });

    const eventData = `data: ${JSON.stringify('Starting the test')}\n\n`;

    res.write(eventData);

    const clientID = Date.now();

    const newClient = {
      id: clientID,
      res,
    };
    clientsList.push(newClient);
    req.on('close', () => {
      console.log(`${clientID} Connection closed`);
      clientsList = clientsList.filter((client) => client.id !== clientID);
    });

    // Define a function for sending progress updates
    res.sendEventsToAll = (data: any) => {
        console.log('SSE Data: ' + data);
        clientsList.forEach((client) => client.res.write(`data: ${JSON.stringify(data)}\n\n`));
    };
});

// Function for sending progress updates
export function sendProgressUpdate(data: any) {
    // Trigger the function attached to the response object
    res.sendEventsToAll(data);
}

Now in your playwright test script, import the sendProgressUpdate function and use it to send progress updates:

import { sendProgressUpdate } from './yourRouteFile'; // Replace 'yourRouteFile' with the actual path

// Inside your Playwright test loop or wherever needed
// Assuming you have a variable 'progressData' holding progress details
sendProgressUpdate(progressData);

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

Angular - Creating validations for numeric input fields within reactive forms to ensure values fall within a designated range

One issue I am facing in my Angular form is with a numeric input field. The requirement is to set the minimum value as 3 and the maximum value as 10. However, upon loading the form, the default value should be 0. Users are expected to enter values ranging ...

Encountering SUID Sandbox Helper Issue When Running "npm start" on WSL with Electron and Typescript

Can anyone help me with this issue? I have Node v8.10.0 and I'm attempting to follow a beginner tutorial on Electron + Typescript which can be found at the following link: https://github.com/electron/electron-quick-start-typescript Here is the full e ...

Type validation in TypeScript through cross-referencing variables

Can TypeScript be used to define a variable that determines the type of other variables? I want to simplify the process by only needing to check one variable, stateIndicator, which is dependent on other variables to infer their types. type A = {prop1: st ...

Another return payload failing to retrieve the return value

I'm currently facing an issue where a function that should return a value is not being passed on to another function. Below is the code snippet in question: public _getProfileToUpdate() { return { corporateId: this.storeService.setStoreData().p ...

Tips for incorporating classes as a prop in material ui components

When working with material ui, I often find myself creating generic components where the styling is actually defined in a parent or grandparent component. For example: const GenericDescendant = (props: DescendantProps) => { const { classesFromAncestor ...

Having trouble changing file names in a Next.js 13 project

I've been facing an issue ever since Next.Js 13 updated the `pages` folder to a new `app` folder. Whenever I try to rename the default "Pages.tsx" file to something like "Home.tsx" or "Information.tsx", it breaks and shows a 404 Page error. The first ...

Leveraging AWS CDK to seamlessly integrate an established data pipeline into your infrastructure

I currently have a data pipeline set up manually, but now I want to transition to using CDK code for management. How can I achieve this using the AWS CDK TypeScript library to locate and manage this data pipeline? For example, with AWS SNS, we can utilize ...

Transforming res.json() into an Array of Objects

I am dealing with a Java webservice that outputs a list of Json objects with specific properties: public class Oferta { private int id; private String categoria; private String descricao_oferta; private String anunciante; private double valor; private boo ...

Disabling the submission button in the absence of any input or data

I am currently experiencing an issue where the submit button is active and displays an error message when clicked without any data. I would like to rectify this situation by disabling the submit button until there is valid data input. < ...

Is it possible to conceal dom elements within an ng-template?

Utilizing ng-bootstrap, I am creating a Popover with HTML and bindings. However, the ng-template keeps getting recreated every time I click the button, causing a delay in the initialization of my component. Is there a way to hide the ng-template instead? ...

Creating reusable TypeScript function argument types

There is a function that I have defined in the following way: function getRangeBounds(start: number, stop?: number, step?: number) { if (step === undefined) step = 1; const actualStart = start !== undefined && stop !== undefined ? start : 0; ...

Cannot send response headers once they have already been sent to the client [NEXTJS]

Currently, I am engrossed in a personal project focused on creating a dashboard using NextJS. This project serves as an opportunity for me to delve into learning NextJS and the fundamental concepts of TypeScript. My primary challenge at the moment revolves ...

Using TypeScript and webpack, include the access_token in the http header when making requests with axios

I need to include an access_token in the header of axios, following this example: https://github.com/axios/axios#global-axios-defaults Currently, I am fetching the access_token using razor syntax, which is only accessible in CSHTML files. https://github ...

The property 'owlDateTimeTrigger' cannot be bound to 'span' as it is not recognized

I have integrated the OwlDateTimeModule into my smart-table-datepicker component. Although I imported it in my smart-table-datepicker.module file, I am still encountering errors. What could be causing this issue? smart-table-datepicker.module.ts import { ...

Can a TypeScript-typed wrapper for localStorage be created to handle mapped return values effectively?

Is it feasible to create a TypeScript wrapper for localStorage with a schema that outlines all the possible values stored in localStorage? Specifically, I am struggling to define the return type so that it corresponds to the appropriate type specified in t ...

Tips for retrieving data sent through Nextjs Api routing

Here is the API file I have created : import type { NextApiRequest, NextApiResponse } from 'next/types' import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient() export default async function handler(req: NextApi ...

Dividing a TypeScript NPM package into separate files while keeping internal components secure

I have developed an NPM package using TypeScript specifically for Node.js applications. The challenge I am facing is that my classes contain internal methods that should not be accessible outside of the package, yet I can't mark them as private since ...

Steps for mandating the specification of a type parameter for a generic React component

When setting up a new instance of a generic React component, I noticed that the TypeScript type checker automatically defaults to unknown without requiring me to specify the type argument: https://i.sstatic.net/1hT6H.png Ideally, I would prefer if TypeSc ...

In TypeScript, both 'module' and 'define' are nowhere to be found

When I transpile my TypeScript using "-m umd" for a project that includes server, client, and shared code, I encounter an issue where the client-side code does not work in the browser. Strangely, no errors are displayed in the browser console, and breakpoi ...

What is the best method for choosing visible elements within a scrollable container?

Is there a way to retrieve the list of visible elements within a scrollable container? The number of elements that are visible on the screen changes as one scrolls, making it challenging to add a specific class to only the last two visible elements. Any s ...