I’m working on a Playwright test script in TypeScript and encountering the following error:
Type 'void' is not assignable to type 'Response | undefined'.ts(2322)
Here is the relevant portion of my code:
import { test, expect, Page, Browser, BrowserContext, Response } from '@playwright/test';
import { chromium } from 'playwright-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
// Use playwright-extra and apply stealth plugin
chromium.use(StealthPlugin());
// Configuration object
const config = {
loginUrl: 'YOUR_LOGIN_URL',
email: 'YOUR_EMAIL',
password: 'YOUR_PASSWORD',
pageTimeout: 60000, // 1 minute timeout for page actions
};
test('Admin Login', async () => {
let browser: Browser | undefined;
let context: BrowserContext | undefined;
let page: Page | undefined;
let loginResponse: Response | undefined;
browser = await chromium.launch({ headless: false }) as unknown as Browser;
context = await browser.newContext();
page = await context.newPage();
// Set up request interception to capture the login request and response
await page.route('YOUR_LOGIN_API_URL', async (route) => {
const response = await route.continue(); // Continue the request
loginResponse = response; // Store the response
});
await page.goto(config.loginUrl);
await page.evaluate(() => window.scrollBy(0, 400));
await page.click('#cookiescript_accept'); // Handle cookie popup
await page.fill('#admin-login-email', config.email);
await page.fill('#admin-login-password', config.password);
await page.click('button[type="submit"]');
// Wait for the login response to be captured
await page.waitForResponse('YOUR_LOGIN_API_URL', { timeout: config.pageTimeout });
// Check if login was successful
await expect(page).toHaveURL(/.*dashboard/);
console.log('Successfully logged in and reached dashboard.');
// Log the login response
if (loginResponse) {
const responseBody = await loginResponse.body();
const responseText = await responseBody.text();
const responseJSON = JSON.parse(responseText);
console.log('Login response:', responseJSON);
} else {
console.log('Login response not found.');
}
await page.close();
await context.close();
await browser.close();
});
The error seems to be related to the line where I am assigning the response to loginResponse
:
loginResponse = response; // Store the response
The error message indicates that TypeScript is expecting a Response or undefined, but void is being assigned.
I’ve verified that the route.continue() function returns a void, which is likely causing the issue. How can I modify the code to properly handle this and avoid the TypeScript error?
1
The original code doesn’t make a lot of sense, and fixing the type error doesn’t resolve the underlying problems. loginResponse
can never be assigned to a response, so your if
will never run.
Also, let Playwright manage the browser. Putting a ton of setup/teardown code in every test isn’t maintainable.
Try something like:
test("Admin Login", async ({page}) => {
await page.goto(config.loginUrl);
await page.evaluate(() => window.scrollBy(0, 400));
await page.click("#cookiescript_accept");
await page.fill("#admin-login-email", config.email);
await page.fill("#admin-login-password", config.password);
const loginResponseP = page.waitForResponse(
"YOUR_LOGIN_API_URL",
{timeout: config.pageTimeout}
);
await page.click('button[type="submit"]');
const loginResponse = await loginResponseP;
await expect(page).toHaveURL(/dashboard/);
const responseData = await loginResponse.json();
// make this an assertion and remove the log
console.log("Login response:", responseData);
});
In other words, loginResponse
is the resolved value of page.waitForResponse
, not route.continue()
. You almost never need to use this fishy-looking pattern in JS:
let result;
addListener((_result) => {
result = _result;
});
// ...
console.log(result);
Note that the response listener needs to be set before the click, otherwise there’s a race condition if the response arrives too quickly.
Responses have a .json()
method so you don’t need to use JSON.parse()
.
/.*dashboard/
has pointless regex syntax: /dashboard/
is functionally identical, although you might want something more precise like //dashboard/
.
Once you have this test working and you want to add more, consider breaking out a POM.