October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
browser automation

How to Click a Button with Playwright for Python

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a locator that identifies the button by its role and accessible name, then call click(). In synchronous Python, write page.get_by_role("button", name="Continue").click(); in asynchronous Python, write await page.get_by_role("button", name="Continue").click(). Replace Continue with the button’s accessible name. After the click, assert the expected result: a successful click does not by itself prove the application reached the state you intended.

Use a button role and accessible name

For most buttons, start with get_by_role("button", name="..."). The role identifies the kind of control; the name identifies which button you mean. This describes the control in user-facing terms and is usually more robust than a selector tied to the page’s internal structure.

page.get_by_role("button", name="Sign in").click()

The name is generally the text a user can perceive as the button’s label, though accessible names can also come from accessibility-related attributes. Match the name you expect the control to expose, not merely a nearby heading or text elsewhere on the page. If the name is not what you expected, inspect the rendered page and accessibility information before switching to a less descriptive selector.

Use an exact name when the full label should match and the page has similar labels. For example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
page.get_by_role("button", name="Save changes", exact=True).click()

Without exact matching, a name can match more broadly than intended. Whichever form you choose, make the locator identify the intended control, not just something that happens to contain similar words.

Choose the right Python style

Playwright for Python provides synchronous and asynchronous APIs. The locator is the same in both; synchronous code calls the method directly, while asynchronous code awaits it. Choose the style that fits the rest of your program rather than mixing them in the same flow.

Synchronous example

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("https://example.com")

    page.get_by_role("button", name="Continue").click()
    page.get_by_text("Welcome").wait_for(state="visible")

    browser.close()

Asynchronous example

import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        await page.goto("https://example.com")

        await page.get_by_role("button", name="Continue").click()
        await page.get_by_text("Welcome").wait_for(state="visible")

        await browser.close()

asyncio.run(main())

These examples assume the page actually contains the named button and that clicking it makes the “Welcome” text visible. Replace the URL, label, and expected result with the ones for the page under test. In a test suite, use the assertion facilities already used by that suite to check the result.

Make repeated button names unambiguous

Pages often contain more than one button called “Add to cart,” “Edit,” or “Continue.” Playwright requires a locator used for an action like click() to resolve to exactly one element. If two or more elements match, it raises a strictness violation rather than guessing which one you meant. That is a useful signal that the locator is underspecified.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Scope the button to a meaningful region, such as the particular product’s list item, dialog, or form. The outer locator should itself identify the intended region uniquely:

product = page.get_by_role("listitem").filter(has_text="Blue jacket")
product.get_by_role("button", name="Add to cart").click()

The example assumes each product is represented by a list item and that “Blue jacket” identifies the right one. Adapt the container to the page’s actual structure. A dialog can be scoped similarly:

dialog = page.get_by_role("dialog", name="Delete project")
dialog.get_by_role("button", name="Delete", exact=True).click()

Avoid reaching for .first, .last, or .nth() just to silence an ambiguity error. Those methods can be appropriate when position is itself part of the intended behavior, but position-based targeting may click the wrong control after the page changes or the item order shifts. Prefer a locator that explains which region or item is the target.

What Playwright waits for before clicking

click() is not just an immediate event dispatch. Before performing a normal click, Playwright waits for a unique target and checks that it is visible, stable, enabled, and able to receive pointer events. If those conditions are not satisfied before the applicable timeout, the action fails with a TimeoutError.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Pointer actions scroll the target into view when needed. Playwright also waits for the action point to receive pointer events and retries if the element detaches while the checks are taking place. This automatic waiting handles many ordinary timing variations, but it cannot make an incorrect locator correct or make an obstructed, disabled control clickable.

The Locator API reference sets a default action timeout of 30,000 milliseconds; page or browser-context timeout settings can change it. A timeout is the limit for waiting on the action, not a guarantee that the page will become ready in that time. Set a different timeout only when the page’s expected behavior calls for one; extending it can make a genuinely broken interaction take longer to report.

Check the result instead of adding a fixed sleep

A click call establishes that Playwright performed the action. It does not establish that the application accepted it, saved data, displayed a confirmation, or navigated to the right place. Follow the interaction with a check tied to the intended outcome.

from playwright.async_api import expect

await page.get_by_role("button", name="Sign in").click()
await expect(page.get_by_text("Welcome")).to_be_visible()

Playwright’s assertions retry while waiting for the condition to become true, which is usually a better fit for an interface response than a guessed delay. For navigation, wait for or assert the expected destination or resulting page state. Do not add an arbitrary sleep as a substitute for knowing what success looks like: a fixed pause can be too short on a slow run and waste time on a fast one.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose an outcome that distinguishes success from merely remaining on the original page. Depending on the application, that may be a confirmation message, a changed heading, a new URL, or a dialog closing. If the click completes but the assertion fails, investigate the application response and the assertion’s target separately.

Diagnose click failures

A strictness violation says multiple controls match

Make the locator unique. Add an exact accessible name if a partial match is too broad, or scope it to a uniquely identified container. Do not assume Playwright should pick one of several matching buttons.

A timeout may indicate the button is not actionable

Check whether the locator matches the intended element and whether it is visible and enabled. A button may still be disabled while a form is incomplete, or the page may not yet have reached the state that renders it. If the target is moving, wait for the page’s real readiness condition rather than relying on a timing guess.

An overlay may be receiving the click

A modal layer, banner, or other overlay can sit over the button and intercept pointer events. Determine what is covering the action point and handle that interface state intentionally—for example, dismiss the overlay if that is part of the user flow. Forcing the click can hide the fact that an ordinary user could not reach the button.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The element may detach during the interaction

Applications sometimes replace or rerender controls during updates. Playwright retries when a target detaches during its actionability checks, but a locator that identifies a transient or outdated part of the page may still fail. Locate the current control based on a stable user-facing name or its current container, and wait for the page state that produces it.

The click succeeds but the test still fails

Check the expected outcome, not just the action. The button may have been clicked while validation prevented submission, the application may show a different confirmation, or navigation may not have happened. Assert the actual success condition for the task and investigate why that condition was not reached.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When force and dispatched clicks are appropriate

click(force=True) bypasses non-essential actionability checks, including the normal check that the target receives events. It is a special-purpose option for a test that intentionally needs to bypass those checks—not a general remedy for a timeout or overlay. If a real user would be blocked from interacting with the control, a forced click can make the test pass while concealing a user-visible defect.

page.get_by_role("button", name="Continue").click(force=True)

dispatch_event("click") triggers the element’s programmatic click behavior rather than performing the ordinary pointer interaction. Use it when the behavior under test specifically requires a programmatically dispatched event. It is not equivalent to clicking with a pointer, and it should not be used to work around a control that is obscured or otherwise inaccessible in the normal interaction.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your goal is a screenshot rather than clicking a control in an automated interaction, ScreenshotNeo offers a website screenshot API. It captures pages; it does not replace Playwright’s button-click action. A basic Python request is:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

See the ScreenshotNeo documentation for API details. Cookie banners and consent notices, newsletter popups, and chat widgets are removed before capture; each of those cleanup steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers say the page verdict and whether the request was billed. An MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

The free plan includes 1,000 screenshots per month with no card required. Paid plans start at $5 for 3,000 screenshots; yearly billing gives two months free. Sign up for 1,000 free screenshots a month, with no card required.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.