microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
67.29k stars 3.71k forks source link

[Bug]: playwright hangs while waiting for pending navigations #33806

Open dgozman opened 2 days ago

dgozman commented 2 days ago

Version

1.49.0

Steps to reproduce

Reported by @chrisbottin in https://github.com/microsoft/playwright/pull/32899#issuecomment-2506437082.

The problem we are having is when we click on a link which triggers the beforeunload dialog, after we dismiss the dialog and try to interact with the page again, we get timeout errors.

Here is a simple test replicating the error ...

const {chromium} = require('playwright');
const {expect} = require('@playwright/test');

(async () => {
    const browser = await chromium.launch();
    const page = await browser.newPage();

    await page.mainFrame().goto('https://www.npmjs.com/');

    expect(await page.mainFrame().title()).toStrictEqual('npm | Home');

    await page.evaluate(() => {
        window.onbeforeunload = () => false;
    });

    page.on('dialog', async dialog => {
        await dialog.dismiss();
    });

    await page.getByRole('menuitem', {name: 'Teams'}).click({noWaitAfter: true});

    await page.evaluate(() => {
        window.onbeforeunload = null;
    });

    // Timeout error will occur here:
    await page.getByRole('menuitem', {name: 'Teams'}).click({timeout: 1000});

    expect(await page.mainFrame().title()).toStrictEqual('npm | Teams');

    await browser.close();
})();

Expected behavior

Test passes.

Actual behavior

The test fails on the line await page.getByRole('menuitem', {name: 'Teams'}).click({timeout: 1000}); with the error:

locator.click: Timeout 1000ms exceeded.
Call log:
  - waiting for getByRole('menuitem', { name: 'Teams' })
  - waiting for navigation to finish...

Additional context

During debugging, I noticed the pendingDocument() is set to {documentId: undefined, request: undefined}

If this line https://github.com/microsoft/playwright/blob/b5bd543cc6935f62732da3b6183bd319eb2bdc2a/packages/playwright-core/src/server/page.ts#L472 is changed to the following, our problem disappears:

if (!mainFrame || !mainFrame.pendingDocument() || !mainFrame.pendingDocument().documentId)
      return;

Environment

unknown
dgozman commented 2 days ago

As a workaround, try running with PLAYWRIGHT_SKIP_NAVIGATION_CHECK=1 npx playwright test and let me know whether that helps.

chrisbottin commented 2 days ago

@dgozman Yes using PLAYWRIGHT_SKIP_NAVIGATION_CHECK environment variable works. This is the route we were going to take to be able to use 1.49 but we don't think it's a long-term solution.

seahindeniz commented 2 days ago

I'm not sure if it is related, but it doesn't work for me. Tried it on @playwright/test@1.49.0

PLAYWRIGHT_SKIP_NAVIGATION_CHECK=1 playwright test test.spec.ts --debug

Image