playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature] Add a `force` option to `screenshot` methods

Open KotlinIsland opened this issue 2 years ago • 4 comments

So basically I want to be able to take a screenshot immediately without any stability checks.

try:
    if not page.locator("#foo").is_visible():
        raise Exception("failed to find element")
except Exception:
    page.screenshot()  # the element appears before it takes the screenshot because screenshot is doing stability checks
    raise

What I want:

    page.screenshot(force=True)

KotlinIsland avatar Jul 19 '22 05:07 KotlinIsland

@KotlinIsland There are no stability checks when calling page.screenshot(). The checks are performed when calling elementHandle.screenshot(). Generally speaking, it seems like you have a race condition, so making screenshot faster will not help as it will still fail on slow CI machines.

If you use expect(locator).to_be_visible() and enable tracing, it should produce a snapshot as fast as possible - that would be your best bet to see what was happening in the page.

dgozman avatar Jul 20 '22 17:07 dgozman

Closed related issue in Python repo and moving the example from the user here for triaging: https://github.com/microsoft/playwright-python/issues/1420#issuecomment-1191053014

rwoll avatar Jul 21 '22 20:07 rwoll

@aslushnikov Could this be caret hiding that waits for some evaluate?

dgozman avatar Jul 24 '22 20:07 dgozman

Note that passing caret: 'initial' option could make screenshot a little bit faster, as a workaround. However, there are no strict guarantees about how long does a screenshot take, because browsers are very asynchronous internally.

dgozman avatar Aug 09 '22 20:08 dgozman

Closing per above, since there is no API changes required.

dgozman avatar Aug 22 '22 16:08 dgozman

I've recently tested this, and even with caret: 'initial' I'm not seeing any change. @dgozman Do you think there could ever be any new approach that could improve the responsiveness/accuracy of screenshots?

KotlinIsland avatar Oct 18 '22 07:10 KotlinIsland

@KotlinIsland There's not much we can suggest here. Screenshots in the browser are asynchronous, complicated and time consuming, so there are no guarantees that it happens very fast, especially when your computer is under heavy load.

dgozman avatar Oct 18 '22 15:10 dgozman

here's a workaround to take a screenshot with no delay:

const base64 = (await (await page.context().newCDPSession(page)).send('Page.captureScreenshot')).data

it would be nice if playwright's screenshot method had an option to behave like this

DetachHead avatar Oct 26 '22 23:10 DetachHead

Wow, this is blazingly fast🔥! That's amazing 🚀.

KotlinIsland avatar Oct 27 '22 00:10 KotlinIsland

Great suggestion by @DetachHead . Complete code if someone else wanders here :)

    browser = playwright.chromium.launch(headless=True)
    context = browser.new_context()
    page = context.new_page()
    cdp = context.new_cdp_session(page)
    page.goto("https://www.google.com", wait_until="commit")
    b64_str = cdp.send("Page.captureScreenshot")["data"]
    b64_bytes = b64_str.encode("ascii")
    binary = base64.decodebytes(b64_bytes)
    with open("screenshot.png", "wb") as binary_file:
        binary_file.write(binary)

cyberw avatar Jan 15 '24 09:01 cyberw