playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[BUG] Throwing the error in page.on('console') callback breaks UI runner

Open rkhomi opened this issue 1 year ago • 2 comments

System info

  • Playwright Version: [v1.40.1]
  • Operating System: [ macOS 13.2]
  • Browser: [All, Chromium, Firefox, WebKit]
  • Other info:

Source code

export const test = base.extend<Fixtures & CustomConfigOptions>({
	page: async ({ page }, use) => {
	
		page.on('console', message => {
			if (
				message.type() === 'error'
			
			) {
				throw new Error(message.text());
			}
		});

		await use(page);
	},

});

Steps

  • Override page fixture to throw error when encounter console error from the application
  • Make the application so that it throws the error at the end of the test
  • Run test in UI runner

Expected

It should keep the test steps, console log, network and attachments, display in errors tab the actual fail, do not clear the app state and UI runner

Actual

Currently it clears all the test and all the data from all the tabs

https://github.com/microsoft/playwright/assets/85738556/6b88b879-3778-40ae-9c2f-7a6e75c42547

The place it fails in code image

rkhomi avatar Jan 28 '24 10:01 rkhomi

		page.on('console', message => {
			if (
				message.type() === 'error'
			
			) {
				throw new Error(message.text());
			}
		});

I suspect you've seen it in a tweet, but this in fact is a bad idea. What you are doing here is an asynchronous unhandled exception. It is handled after the test has already finished, so it can't be attributed to your test. You should instead collect the exceptions after log or assert them after the use(page) in the fixture.

pavelfeldman avatar Jan 29 '24 16:01 pavelfeldman

I tried reproducing your original issue with

import { test as baseTest, expect } from '@playwright/test';

export const test = baseTest.extend({
  page: async ({ page }, use) => {
    page.on('console', message => {
      if (message.type() === 'error')
        throw new Error(message.text());
    });
    await use(page);
  },
});

test('test', async ({ page }) => {
  await page.evaluate(() => console.error('error'));
});

and it did not fail, is there a minimal repro that you could share?

pavelfeldman avatar Jan 31 '24 22:01 pavelfeldman

Closing as non-actionable due to the lack of repro. Please open a new bug if you manage to create a repro we can use.

pavelfeldman avatar Feb 02 '24 20:02 pavelfeldman