Free tools Windows power users keep installed
One-click scans. No signup required.
Install the Python package, download Playwright’s browser binaries, then choose either a small library script or the official pytest plugin for end-to-end tests. This tutorial walks through both paths, synchronous and asynchronous APIs, reliable locators, screenshots, cross-browser runs, CI, and fixes for common failures. Playwright is free and supports Chromium, Firefox, and WebKit.
What you need before starting
Playwright’s current installation page lists Python 3.8 or newer. Its supported environments include Windows 11 or newer (and Windows Server 2019+ or WSL), macOS 14 Sonoma or newer, and Debian 12/13 or Ubuntu 22.04, 24.04, or 26.04 on x86-64 or arm64. These requirements can change, so check the official installation page for the version you are using.
Create and activate a virtual environment so the browser-automation dependencies stay isolated:
python -m venv .venv
# macOS/Linux
source .venv/bin/activate
# Windows PowerShell
.venvScriptsActivate.ps1
Choose the Playwright Python style
| Use case | Recommended setup | Why |
|---|---|---|
| One-off automation, scraping, or a utility | playwright library |
Direct control over the browser from your script |
| Repeatable end-to-end tests | pytest-playwright plugin |
Fixtures, configuration, parallel test structure, and web-first assertions |
Playwright’s documentation says it recommends the official pytest plugin for end-to-end tests. The library remains the better starting point when you need a single script rather than a test suite.
#1 Best Overall
Install Playwright and its browsers
Standalone library
python -m pip install playwright
playwright install
Pytest plugin
python -m pip install pytest-playwright
playwright install
The package and browser binaries are separate. Installing the Python package alone does not install Chromium, Firefox, or WebKit. After upgrading Playwright, run playwright install again when the required browser revision changes. The browser documentation explains browser channels and version matching.
Poetry and uv workflows are also documented in the official guides. For example, with uv you can add the dependency to the project and then run the Playwright install command in the project environment.
Run your first synchronous script
The synchronous API is easiest for a normal command-line program. Save this as capture_title.py:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={"width": 1280, "height": 800})
page.goto("https://example.com", wait_until="domcontentloaded")
print(page.title())
page.screenshot(path="example.png", full_page=True)
browser.close()
Run it with python capture_title.py. The script starts Chromium, creates a page, navigates, reads the title, saves a full-page PNG, and closes the browser. Always close the browser in longer-lived programs; the context manager shown above does that even if an exception occurs.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Use the asynchronous API with asyncio
Choose async when the surrounding application already uses asyncio, such as an async web service or a queue worker. Do not mix the synchronous API into a running event loop.
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", wait_until="domcontentloaded")
print(await page.title())
await page.screenshot(path="example-async.png", full_page=True)
await browser.close()
asyncio.run(main())
The browser and page methods are the same conceptually, but every operation that performs I/O is awaited.
Rank #2
Write an end-to-end test with pytest
Create tests/test_home.py:
from playwright.sync_api import Page, expect
def test_homepage_has_expected_heading(page: Page):
page.goto("https://example.com")
expect(page).to_have_title("Example Domain")
expect(page.get_by_role("heading", name="Example Domain")).to_be_visible()
The plugin supplies the page fixture, launches the configured browser, and manages cleanup. Test functions must use the test_ naming convention. Run the suite with:
pytest
For a visible browser while developing, use pytest --headed. Select an engine with pytest --browser firefox or run several with pytest --browser chromium --browser firefox --browser webkit. The exact available command-line options are maintained in the Python installation guide.
Choose locators that survive UI changes
Prefer user-facing locators over CSS paths tied to layout:
page.get_by_role("button", name="Save")for accessible controls.page.get_by_label("Email")for form fields with labels.page.get_by_text("Welcome")for visible text when role or label is unsuitable.page.get_by_test_id("order-row")when your application exposes a stable test identifier.
Assertions such as expect(locator).to_be_visible() are web-first: they retry until the condition is met or the timeout expires. This is more reliable than inserting arbitrary sleeps. Use a short, deliberate wait only when the application has a known external transition that cannot be observed through a locator or network state.
Record a workflow with Codegen
Codegen can open a browser, record clicks and typing, and suggest locators:
playwright codegen https://example.com
It prioritizes role, text, and test-id locators and tries to make ambiguous locators unique. Treat the generated file as a first draft: remove accidental steps, replace brittle text, add assertions, and move repeated setup into fixtures. The Codegen guide describes recording options and locator inspection.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallNavigation, forms, and practical actions
from playwright.sync_api import sync_playwright, expect
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://your-app.example/login")
page.get_by_label("Email").fill("user@example.com")
page.get_by_label("Password").fill("correct horse battery staple")
page.get_by_role("button", name="Sign in").click()
expect(page.get_by_role("heading", name="Dashboard")).to_be_visible()
browser.close()
For a download, wait for the event while clicking:
with page.expect_download() as download_info:
page.get_by_role("link", name="Export CSV").click()
download = download_info.value
download.save_as("export.csv")
For a new tab:
with page.expect_popup() as popup_info:
page.get_by_role("link", name="Open report").click()
report = popup_info.value
report.wait_for_load_state()
print(report.url)
Browser, context, and page choices
Use p.chromium, p.firefox, or p.webkit to test the three Playwright browser engines. A browser context is an isolated session containing its own cookies, storage, permissions, and pages:
context = browser.new_context(
locale="en-US",
timezone_id="America/New_York",
viewport={"width": 1440, "height": 900},
)
page = context.new_page()
Close the context before closing the browser when you create contexts manually. Playwright also supports selected branded browser channels; availability depends on the installed browser and operating system.
Screenshots and PDFs from Python
Capture the viewport with page.screenshot(path="view.png"), the entire document with full_page=True, or a single element:
page.locator("main article").screenshot(path="article.png")
page.pdf(path="report.pdf", format="A4", print_background=True)
PDF generation is supported when using Chromium. If lazy-loaded images are missing, scroll the page or wait for the relevant image locator before capturing. For deterministic output, set a fixed viewport, locale, timezone, and color scheme.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsConfiguration and CI
Keep test settings in pytest.ini or pyproject.toml, and use environment variables for credentials. Never commit passwords or session tokens. A minimal CI sequence is:
python -m pip install -r requirements.txt
playwright install --with-deps
pytest
Linux CI runners may need operating-system libraries; playwright install --with-deps is the documented convenience command on supported Linux environments. The continuous-integration guide contains provider-specific examples, caching notes, and worker recommendations.
Troubleshoot common failures
“Executable doesn’t exist” or browser launch errors
Cause: the Python package is installed but its binaries are not. Run playwright install in the same virtual environment. After an upgrade, repeat the command so the browser revision matches the package.
Missing shared libraries on Linux
Cause: a minimal CI image lacks browser dependencies. Use playwright install --with-deps on a supported Debian/Ubuntu runner, or install the libraries listed by the CI documentation.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Timeout while clicking or asserting
Cause: the locator is wrong, the element is not actionable, or the application has not reached the expected state. Inspect with playwright codegen, prefer a role or label locator, and assert a visible state instead of adding a long sleep. Use page.screenshot() and tracing in a debug run to see the actual page.
Strict-mode violation
Cause: a locator matches more than one element. Narrow it with an accessible name, a parent locator, or a test id; do not silently select the first match unless order is genuinely part of the requirement.
Tests pass locally but fail in CI
Check browser installation, OS dependencies, viewport differences, timezone, network access, and secrets. Capture artifacts on failure and avoid depending on third-party sites for critical assertions.
Performance and reliability practices
- Reuse a browser process, but create isolated contexts for independent users or tests.
- Wait on observable states such as a response, URL change, or visible control rather than fixed delays.
- Block unnecessary media or analytics only when doing so cannot change the behavior under test.
- Use retries sparingly. A retry can hide a race condition; fix the locator or readiness signal first.
- Pin Python and Playwright versions in CI, and schedule deliberate upgrades followed by
playwright install. - Save screenshots, traces, and console output for failed runs so a timeout is diagnosable.
Or skip the browser setup
If your goal is simply to obtain a clean website image or PDF rather than interact with a page, ScreenshotNeo provides a single HTTP request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. It also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
Install requests for the Python example, then call the API:
Best Value
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)
Equivalent cURL and Node.js calls are useful in scripts and CI:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo documentation for all options, including full-page and element capture, dark mode, device presets, retina scale, PDF paper and page ranges, custom CSS or JavaScript, clicks, selector waits, network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage reporting, and the OpenAPI specification. Every feature is included on every plan. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
FAQ
Can Playwright automate an already installed Chrome?
Playwright can use supported branded browser channels, but its managed browser binaries provide the version Playwright expects. For reproducible tests, install the browsers with the project’s Playwright version.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Should every test use a new browser?
No. Reuse the browser process and isolate tests with separate contexts or the fixtures supplied by the pytest plugin.
Is Codegen a test generator I can ship unchanged?
No. It is a recording and locator-inspection aid. Review its selectors, delete incidental actions, and add assertions that express the behavior your application must guarantee.
Frequently Asked Questions
Can Playwright automate an already installed Chrome?
Playwright can use supported branded browser channels, but its managed browser binaries provide the version Playwright expects. For reproducible tests, install the browsers with the project’s Playwright version.
Should every test use a new browser?
No. Reuse the browser process and isolate tests with separate contexts or the fixtures supplied by the pytest plugin.
Recommended Free Tools
Is Codegen a test generator I can ship unchanged?
No. It is a recording and locator-inspection aid. Review its selectors, delete incidental actions, and add assertions that express the behavior your application must guarantee.
Quick Recap
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.

