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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Set headless=False when you launch Playwright. That single option changes the default invisible run into a browser window you can watch and inspect:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://example.com")
    input("Press Enter to close the browser...")
    browser.close()

Playwright runs headless by default, so the launch setting is the important change. The pause keeps the process alive; without it, this short script can finish and close the visible window immediately.

What “visible mode” means in Playwright

A headless browser performs normal browser work without drawing a user interface. In headed, or visible, mode the same automation opens a graphical window. You can watch navigation, inspect a login flow, observe pop-ups and debug selectors while the script runs.

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

Playwright’s Python API supports Chromium, Firefox and WebKit. Choose the engine that matches the browser behavior you need, then pass headless=False to that engine’s launch() method.

Install Playwright and its browsers

Install the Python package and the browser binaries before running a script. Use the current commands in Playwright’s Python browser installation guide, because installation syntax and supported builds can change.

  1. Install Playwright in the Python environment that will run your program.
  2. Install the supported Playwright browser binaries from the same environment.
  3. Run the script on a desktop or remote session that can display a graphical window.

Playwright manages its own browser builds. Its documentation distinguishes regular Chromium, which is suitable for headed work, from a separate headless shell. If you need branded Google Chrome or Microsoft Edge rather than a Playwright-managed browser, review the browser-channel documentation and your organization’s policies first. Enterprise policies can affect whether those channels can be controlled.

Minimal visible Chromium script

This complete synchronous example opens Chromium, navigates to a page and waits for you to close it:

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.
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://example.com")
    input("Press Enter to close the browser...")
    browser.close()

Save it as visible_browser.py and run it with the Python interpreter where Playwright and its browsers are installed. The input() call is only an inspection aid. Remove it when later steps in your program should continue automatically.

Choose Chromium, Firefox or WebKit

Replace p.chromium with another Playwright browser type when your test targets a different engine:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.firefox.launch(headless=False)
    page = browser.new_page()
    page.goto("https://example.com")
    input("Press Enter to close Firefox...")
    browser.close()
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.webkit.launch(headless=False)
    page = browser.new_page()
    page.goto("https://example.com")
    input("Press Enter to close WebKit...")
    browser.close()

The API shape is the same, but rendering and browser-specific behavior can differ. Use the engine your users or deployment actually require instead of assuming Chromium represents every browser.

Make actions easier to watch with slow motion

When a visible run is too fast to follow, pass slow_mo to launch(). The value is a delay in milliseconds applied to Playwright actions:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False, slow_mo=300)
    page = browser.new_page()
    page.goto("https://example.com")
    page.get_by_role("link").first.click()
    input("Press Enter to close the browser...")
    browser.close()

Use slow motion for demonstrations and debugging, not normal test throughput. It deliberately increases runtime.

Keep the window open without manual input

A visible browser closes when your Python process exits. For an automated inspection period, wait for a known condition or use a timed pause rather than an indefinite prompt:

import time
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://example.com")
    page.wait_for_load_state("domcontentloaded")
    time.sleep(10)
    browser.close()

For real workflows, prefer Playwright waits such as locator.wait_for(), page.wait_for_url() or a load-state wait. Fixed sleeps are useful only when you intentionally want a window to remain visible for a short, predictable interval.

Use a branded Chrome or Edge channel carefully

Playwright can target installed branded browsers through browser channels, but availability and control depend on the local installation and enterprise policy. Confirm the current channel names and policy requirements in Playwright’s documentation before relying on them. A Playwright-managed Chromium build is the simpler baseline when you do not need a branded binary.

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

Display requirements outside a desktop

headless=False requests a real window; it does not create a display server. Your Python process must run in an environment capable of showing graphical applications. A normal desktop session can do this. A remote desktop may do so if the session exposes a display. A server, container or CI runner may not.

The cited Playwright pages explain browser installation and launch behavior, but they do not provide one universal setup for every container, CI system or remote-display product. If a headed launch fails on infrastructure without a graphical session, either provide an appropriate display environment according to that platform’s documentation or run headless mode instead.

Common errors and fixes

“Executable doesn’t exist” or missing browser binary

Cause: The Python package is installed but its browser build is not.

Fix: Install the supported browser binaries using the current instructions in the Playwright browser guide, then rerun the script in the same environment.

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

The script opens and closes immediately

Cause: The Python process reached the end of the file.

Fix: Add an explicit wait, such as the input() prompt in the minimal example, or wait for the page event or locator your workflow needs.

No window appears

Cause: The process has no usable graphical display, or it is running in a different desktop or remote session than the one you are watching.

Fix: Run it from a display-capable session and verify that the process belongs to that session. If the host is a non-graphical server or CI worker, headed mode cannot display a window without additional infrastructure.

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.

Actions happen too quickly to diagnose

Cause: Automation executes at machine speed.

Fix: Add slow_mo temporarily, or pause on a meaningful condition. Remove unnecessary delays after debugging.

Chrome or Edge cannot be controlled

Cause: The installed channel, browser policy or organization restrictions prevent Playwright from launching or controlling it.

Fix: Check the current channel documentation and your organization’s browser policies. Try a Playwright-managed browser to separate a channel-policy problem from an automation problem.

Visible mode in a maintainable script

Use a try/finally block when your program has more than a few lines, so the browser closes even after an exception:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from playwright.sync_api import sync_playwright

def inspect_page(url: str) -> None:
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False, slow_mo=150)
        try:
            page = browser.new_page(viewport={"width": 1440, "height": 900})
            page.goto(url, wait_until="domcontentloaded")
            page.get_by_role("heading").first.wait_for()
            print(page.title())
            input("Press Enter to close the browser...")
        finally:
            browser.close()

inspect_page("https://example.com")

A context or page can be configured with the viewport and other options your test needs. Keep the visible switch at the launch boundary so the same workflow can be run headless later by changing one setting.

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

Performance and reliability choices

  • Use headed mode for observation: Rendering a window and adding slow_mo costs time. Use headless mode for unattended throughput when visual inspection is not required.
  • Wait for evidence, not arbitrary time: URL, load-state and locator waits are less fragile than long sleeps.
  • Close resources: The context manager shuts down Playwright; browser.close() releases the browser process.
  • Match the engine to the requirement: A Chromium result does not replace a Firefox or WebKit check.
  • Keep installation aligned: Install browser binaries in the environment that actually runs the script, including a CI image or remote host.

Or skip the browser setup

If your goal is a clean screenshot rather than watching automation, ScreenshotNeo returns an image or PDF from one request. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed; each response identifies the result with X-Page-Verdict and X-Billed headers. You can still control capture behavior with options for full-page and element shots, device and viewport settings, dark mode, retina scale, waits, custom CSS or JavaScript, clicks, hidden selectors, blocked resources, headers, cookies, user agents, authorization, timezone, geolocation, transparency, resizing, caching, signed links, asynchronous webhooks, bulk capture and PDF output.

The service also provides an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Every feature is available on every plan.

One-call examples

See the complete parameter reference in the ScreenshotNeo documentation. Replace the example URL with the page you need.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Create a free ScreenshotNeo account to use the 1,000 monthly screenshots with no card, or choose a paid plan from $5 for 3,000.

Quick decision guide

  • Choose Playwright headed mode when you need to watch clicks, inspect a live browser, debug a locator or test a particular engine.
  • Choose Playwright headless mode when the same workflow must run unattended on infrastructure with no graphical display.
  • Choose ScreenshotNeo when you need a repeatable screenshot or PDF endpoint and do not want to maintain browser installation and display setup.

Frequently Asked Questions

Does Playwright use headed mode by default?

No. Playwright launches browsers headless by default; pass headless=False to launch() to show the UI.

Can I leave the visible browser open after Python exits?

No. The browser process is tied to the automation process. Keep Python alive with a prompt or another wait, and close the browser when inspection is complete.

Which Playwright browsers support visible mode?

The Python API provides visible launches for Chromium, Firefox and WebKit. The required engine depends on the behavior you need to test.

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

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.