playwright: [BUG] "NS_BINDING_ABORTED" error in Firefox

Context:

  • Playwright Version: 1.30.0
  • Operating System: Mac/Ubuntu
  • Node.js version: 18.12.1
  • Browser: Firefox

Code Snippet

See repository with minimal reproducible example: https://github.com/wentwrong/pw-firefox-ns-binding-aborted

Describe the bug

When you navigate to page A and then immediately navigate to page B (using page.goto), if page A asynchronously navigates itself to another URL then navigation to page B will fail in Firefox with the following error:

1) [firefox] › bug.spec.js:3:1 › goto should not fail with the "NS_BINDING_ABORTED" error ========

  page.goto: NS_BINDING_ABORTED; maybe frame was detached?
  =========================== logs ===========================
  navigating to "http://localhost:3000/b", waiting until "load"
  ============================================================

    3 | test('goto should not fail with the "NS_BINDING_ABORTED" error', async ({ page }) => {
    4 |     await page.goto('http://localhost:3000/a');
  > 5 |     await page.goto('http://localhost:3000/b');
      |                ^
    6 | });
    7 |

See detailed logs here: https://github.com/wentwrong/pw-firefox-ns-binding-aborted/actions/runs/4124609214/jobs/7124068636

Currently there are no ways to workaround it except adding explicit page.waitForTimeout() after first navigation which is a little hacky and unreliable.

I expect that the page.goto API will work uniformly across all browsers and page-initiated navigation can’t affect subsequent navigations done by page.goto. At least it shouldn’t crash.

Related issues:

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 8
  • Comments: 18 (4 by maintainers)

Commits related to this issue

Most upvoted comments

confirmed this is still an issue in firefox

This behavior is consistent with what happens in Firefox when you type the url into the address bar while there is a concurrent navigation triggered by the page.

I understand that, but the problem is that there is no way to supress this error, and seeing it doesn’t provide any useful information for the user.

For now we are experimenting with the following approach:

const test = base.extend({
    page: async ({ page, browserName }, use) => {
        const originalGoto = page.goto.bind(page);

        page.goto = async function(url, options) {
            if (!['firefox', 'webkit'].includes(browserName)) return originalGoto(url, options);

            const response = await originalGoto(url, options);
            const waitForURL = options?.waitForURL;

            if (waitForURL) await page.waitForURL(waitForURL);

            return response;
        };

        await use(page);
    }
});

test('prevents NS_BINDING_ABORTED error', async ({ page }) => {
    await page.goto('http://localhost:3000/a', { waitForURL: 'http://localhost:3000/b' });
    await page.goto('http://localhost:3000/b');
});

It’s certainly better than adding explicit page.waitForTimeout()-s in every test, but it still doesn’t feel like a proper way of handling this issue. First of all, we need to know in advance on which page the redirect chain will end up on, so that we can wait until this page is open to be sure that the navigation requests will not be canceled by the subsequent page.goto() invocations. And secondly, it slows down tests in Firefox and Webkit browsers.

With the help of the page.on('requestfailed') event handler we can catch this error, but unfortunately there is no way to tell Playwright to suppress it, although most users who encountered this error would like to be able to.

I’be really glad to hear on how this error is supposed to be solved or worked around, because as I stated in the issue message, as a user of Playwright framework I expect that the page.goto() API will work uniformly across all browsers. And even if opening a new page in a browser leads to cancellation of previous navigations, it should not fail the test whatsoever because it’s not a sensible default behaviour.

Still occurs for me on Firefox browser.

I’be really glad to hear on how this error is supposed to be solved or worked around, because as I stated in the issue message, as a user of Playwright framework I expect that the page.goto() API will work uniformly across all browsers.

The behavior varies between browsers in this scenario and playwright reflects that. You can wait for the redirect to finish before starting next navigation:

test('prevents NS_BINDING_ABORTED error', async ({ page, browserName }) => {
    await page.goto('http://localhost:3000/a');
    if (browserName !== 'chromium')
      await page.waitForURL('http://localhost:3000/b');
    await page.goto('http://localhost:3000/b');
});

alternatively you can start the new navigation in a new page object.

I still see that ERROR. Can you please reopen the ticket?

fwiw, i’m using Playwright Test and was able to workaround with the expect + timeout

await expect( page ).toHaveURL( 'url', { timeout: 30000 } )

an example of the code that throws the error

await page.goto( 'url1' )
await page.getByRole( 'button', { name: 'Login' } ).click()
await page.waitForURL( 'url2' )

There are multiple redirects before getting to the URL in the page.waitForURL

This only happens in firefox. Chromium/WebKit work

Hope this helps someone else and/or the issue is reopened

Cheers! 🍻

It’s happening while opening google drive not my own server so i don’t know if it’s a bug or it this something from google to promote google chrome like they do with youtube and google image search i am not sure , i don’t mind providing you with any logs or troubleshooting steps required to do from my end

This seems to be different than calling page.goto() when the page is doing js redirect. Please file a separate issue with detailed reproduction steps.