What is the best way to launch the Playwright browser in Jest using the setupFilesAfterEnv hook, to ensure accessibility within the test file while incorporating TypeScript?

When using Jest and Playwright, I encountered an issue where I wanted to launch the browser from setupFilesAfterEnv in order to avoid repeating the process in every test file. Despite successfully launching the browser and having global variables accessible for testing purposes, I kept receiving an error message: 'TypeError: global.browser.newContext is not a function'. My setup involves using Babel to incorporate TypeScript into Jest.

My Configuration

jest.config.cjs

const config = {
    testTimeout: 20000,
    setupFilesAfterEnv: ["<rootDir>/setup.ts"]
};

module.exports = config;

setup.ts

import {chromium} from "playwright-chromium";

global.browser = chromium.launch({headless: false});
global.my_val = "10";

test.test.ts

describe("Test", () => {
    let context;
    let page;

    beforeEach(async () => {
        console.log("Global 10")
        console.log(global.my_val)
        context = await global.browser.newContext();
        page = await context.newPage();
    })

    test(...)

The browser launches properly, as confirmed by its presence in the list of processes (although it runs in headless mode despite being set to false).

console.log(global.my_val) correctly displays 10, indicating that global variables from the setup are visible within this context.

However, the following error is hindering my progress:

TypeError: Cannot read properties of undefined (reading 'newContext')

      28 |
      29 |     beforeEach(async () => {
    > 30 |         context = await global.browser.newContext();
         |                                        ^
      31 |         page = await context.newPage();
      32 |     })
      33 |

Answer №1

Alright, it appears that achieving this can be done using the testEnvironment in JavaScript. It's also possible with TypeScript if you utilize TS-node.

Here is a potential solution:

const { chromium } = require('playwright-chromium');
const NodeEnvironment = require('jest-environment-node').TestEnvironment;

class CustomEnvironment extends NodeEnvironment {
    constructor(config, context) {
        super(config, context);
    }

    async setup() {
        await super.setup();
        this.global.browser = await chromium.launch({headless: false});
    }

    async teardown() {
        await super.teardown();
        await this.global.browser.close();
    }
}

module.exports = CustomEnvironment;

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

Showing the outcome of the request from the backend on an HTML page using the MEAN stack

I am currently in the process of developing an angular application with a node.js + express backend. After successfully retrieving the necessary data from MongoDB and being able to view it through terminal, I encountered a challenge when trying to display ...

Transferring Information Between Components

After logging into my login component, I want to pass data to my navbar component but unfortunately, my navbar content does not update. The navbar component is located in the app-module while the login component is in a separate module. I attempted to us ...

What is the best way to retrieve the name of a static method within a class?

In my code, I am logging multiple messages in a static method and I want to use the method name as context. However, I do not want to create a separate variable called `context` and assign the function/method name to it. I would like to be able to access ...

Using the TypeScript NextPage function along with the getInitialProps static method and @typescript-eslint/unbound-method

After enabling typescript-eslint with its recommended settings, I encountered an issue in my code. I came across this helpful post on Stack Overflow: Using getInitialProps in Next.js with TypeScript const X: NextPage = props => {/*...*/} X.getInitialP ...

Is there a way to create a stub for the given function using sinon?

Here is my test function: const customTestLibrary = require("./test"); describe("Initial Test", function() { it("should run the test function successfully", function(done) { customTestLibrary.execute(); done(); }); }); The te ...

What is the best method to condense an array or extract only the valid values?

Looking to find the total count of properties that are true from an array of objects? Here's an example: let data = [ { comment: true, attachment: true, actionPlan: true }, { whenValue: '', ...

Tips for boosting ViteJs development mode performance

One issue I am facing is the slow server performance during development mode. After starting the server and opening the page in my browser, I have to wait 3–6 minutes for it to load! Initially, ViteJs downloads a small amount of resources, but then the ...

Error encountered during Jest snapshot testing: Attempting to destructure a non-iterable object which is invalid

I am currently facing an issue with my React codebase where I am attempting to create snapshot tests for a component. However, Jest is showing an error indicating that I am trying to destructure a non-iterable instance. Despite thoroughly reviewing the cod ...

Error encountered with TypeScript template literals strings type

There's a new feature in the latest version of Typescript that allows the use of template literal strings as types, like this: type Hey = 'Hey'; type HeyThere = `${Hey} There`; It works perfectly in the Typescript playground with version 4 ...

What is the reason behind the ability to assign any single parameter function to the type `(val: never) => void` in TypeScript?

Take a look at the code snippet below interface Fn { (val: never): void } const fn1: Fn = () => {} const fn2: Fn = (val: number) => {} const fn3: Fn = (val: { canBeAnyThing: string }) => {} Despite the lack of errors, I find it puzzling. For ...

Issues with Angular's router outlet link functionality not performing as expected

I am encountering difficulties trying to create a link to a named router outlet in Angular. Let's focus on the most crucial part of the code: app-routing-module.ts: import { NgModule } from '@angular/core'; import { RouterModule, Routes } ...

Is there a way to denote a specific part of a generic type without explicitly specifying the parts as generics themselves?

My dilemma involves an object defined by a type from a 3rd party library: // Unable to modify this - it belongs to the 3rd party library; interface TypedEvent< TArgsArray extends Array<any> = any, TArgsObject = any > extends Event { args ...

Design a data structure that encompasses the combined output of multiple functions

I have a set of functions and I want to combine the return types of these functions into a union type. Example Input function types: type InputType1 = () => {type: "INCREASE"} type InputType2 = () => {type: "ADD", by: number} Ou ...

The Quasar test fails to locate elements with a name tag>null<

I've encountered a strange issue while trying to conduct unit tests on my Quasar application. The problem seems to be that the test is unable to locate elements with the name tag, except for the q-route-tab components. I've experimented with diff ...

Utilizing the <HTMLSelectElement> in a Typescript project

What exactly does the <HTMLSelectElement> do in relation to a TypeScript task? let element = <HTMLSelectElement> document.querySelector('#id_name'); The HTMLSelectElement interface, similar to the one mentioned in TypeScript, is exp ...

What is the role of the "prepare" function in AWS CDK constructs?

TL;DR: What is the role and purpose of the prepare(): void method in AWS CDK's Construct class? When and how should it be utilized or avoided? The information provided about prepare() states: prepare() function is called after child constructs have ...

Dynamic table row that expands to show additional rows sourced from various data sets

Is there a way to expand the table row in an angular-material table when it is clicked, showing multiple sets of rows in the same column as the table? The new rows should share the same column header but not necessarily come from the same data source. Whe ...

Exploring the world of Typescript TSX with the power of generic

Introducing JSX syntax support in Typescript opens up new possibilities. I have an expression that functions smoothly with traditional *.ts files, but encounters issues with *.tsx files: const f = <T1>(arg1: T1) => <T2>(arg2: T2) => { ...

Using TypeScript with React and Material-UI: Issue with undefined theme in createStyles()

Currently, I am delving into React with TypeScript and utilizing the Material UI framework for the frontend. In my quest to activate media queries, an error has crossed my path: Uncaught TypeError: Cannot read property 'up' of undefined ...

Exploring the capabilities of renderOption within Material-UI's AutoComplete functionality

Hey there, I've been pondering a question lately and could really use some help. I've been trying to set up my autocomplete feature to display a label in the options while having a different value. After doing some research, I learned about usin ...