Skip to content

Failing New Page closes the page before run_on_failure, so the failure screenshot is missing or shows a different page #5261

Description

@aaltat

Describe the bug

When New Page fails to navigate, the page it created is closed before anything can look at it:

    try {
        ...
        await page.p.goto(url, goToOptions);
        ...
    } catch (e) {
        void browserState.browser.popPage()?.p.close();
        throw e;
    }

node/playwright-wrapper/playwright-state.ts:813-833

The error then travels back to Python, and only after that does run_on_failure fire (Browser/browser.py:1162-1196). By then the page that failed is gone, so the failure screenshot is taken of whatever is left. There are two outcomes and both are bad:

1. There is no other page — the screenshot is skipped.

Keyword 'Take Screenshot  fail-screenshot-{index}' could not be run on failure:
Error: Tried to take screenshot, but no page was open.

This case is already known and deliberately demoted to INFO in keyword_error (Browser/browser.py:1188-1195), so it passes silently.

2. There is another page — the screenshot is of the wrong page, and nothing says so.

This is the damaging one. From run 33839012661, test Run Rfbrowser To Combine Coverage Reports With Different Reports:

[PASS] New Page      elapsed=0.061956   -> about:blank
...
[FAIL] New Page      elapsed=5.141698
       Screenshot successfully captured to: ...\browser\screenshot\fail-screenshot-1.png
       </td></tr><tr><td colspan="3"><a href="browser/screenshot/...-fail-screenshot-1.png" ...><img src="..."/></a>
       TimeoutError: page.goto: Timeout 5000ms exceeded.
         - navigating to "file:///.../combined_coverage_reports_2/index.html", waiting until "load"

The screenshot is reported as successful and embedded in the RF log directly under the failure message. Opening it from the artifact: it is a blank white page — the earlier about:blank, not the page that failed. A user reading that log sees a picture that looks like evidence of the failure and is not.

Expected behaviour

The failure screenshot for a failing New Page shows the page that failed, or the log says plainly that the page could not be photographed. It never silently shows a different page.

Suggested fix, and the constraint on it

The page must still be removed — atest/test/01_Browser_Management/new_page_should_not_timeout.robot:13-25 asserts exactly that the catalog is unchanged after a New Page timeout, so "stop closing the page" is not the fix. The capture has to happen before the close, inside the catch in newPage.

While that catch is open, it is also the only place that can still see the failed page's own state. Collecting it there answers the question these timeouts always raise — did the document finish loading and we missed the event, or did it never finish:

  • page.url()
  • document.readyState
  • performance.getEntriesByType('navigation')[0]domContentLoadedEventEnd, loadEventEnd
  • performance.getEntriesByType('resource') entries with no responseEnd — names any subresource still outstanding

Each needs its own short timeout and try/catch; the page is in an unknown state and none of this may hang or mask the original error, which must still be what is thrown.

Environment

Browser 20.5.0, Playwright 1.63.0, Robot Framework 7.1.1, Python 3.10.11 and 3.14.7, Windows, chromium. Observed against main at b986d01. The screenshot behaviour is not platform specific; the runs it was observed in happen to be Windows.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions