Introduction

If you’ve spent any time in the QA or automation space, you know the pain of “flaky” tests—those scripts that fail for no apparent reason because a button took 100ms too long to load. In my experience, moving from legacy tools to modern frameworks is the only way to solve this. That’s why I want to show you how to use Playwright with Python to build a testing suite that actually stays green.

Playwright, developed by Microsoft, has rapidly become my go-to tool because it handles the browser’s asynchronous nature far better than its predecessors. Whether you’re wondering why Playwright is better than Selenium or you’re just starting your automation journey, this guide will get you from zero to your first successful test run in minutes.

Prerequisites

Before we dive into the code, ensure you have the following installed on your machine:

Step-by-Step: Getting Started with Playwright Python

Step 1: Installation

Unlike some tools that require you to manually download browser drivers (looking at you, Selenium), Playwright handles this for you. First, install the Playwright Python library:

pip install playwright

Next, you need to install the actual browser binaries (Chromium, Firefox, and WebKit) that Playwright uses:

playwright install

Step 2: Writing Your First Script

Let’s write a simple script to navigate to a page and take a screenshot. I prefer using the sync_api for simple scripts and the async_api for high-performance scraping or large-scale testing. For this tutorial, we’ll use the synchronous version for clarity.

from playwright.sync_api import sync_playwright

def run():
    with sync_playwright() as p:
        # Launch the browser (headless=False lets you see it happen)
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        # Navigate to the target URL
        page.goto("https://ajmani.dev")
        print(f"Page title is: {page.title()}")
        
        # Take a screenshot
        page.screenshot(path="example.png")
        
        browser.close()

run()

Step 3: Using the Test Runner (pytest-playwright)

Writing standalone scripts is great for debugging, but for real-world production testing, you need a test runner. I always use pytest. To integrate it, install the official plugin:

pip install pytest-playwright

Now, create a file named test_my_app.py. Notice how the page object is automatically injected via fixtures—you don’t need to manually launch the browser anymore!

import pytest

def test_homepage_title(page):
    page.goto("https://ajmani.dev")
    assert "Ajmani" in page.title()

def test_navigation_link(page):
    page.goto("https://ajmani.dev")
    # Playwright's auto-waiting makes this incredibly stable
    page.click("text=Blog")
    assert "/blog" in page.url

Run your tests using the command line:

pytest

As shown in the image below, using the Playwright Inspector allows you to see exactly how the tool identifies elements on the screen, which is a game-changer for writing robust selectors.

Playwright Inspector window showing the element picker and generated Python code
Playwright Inspector window showing the element picker and generated Python code

Step 4: Mastering Selectors and Auto-Waiting

One of the biggest hurdles when learning how to use Playwright with Python is choosing the right selector. Forget fragile XPaths. Playwright encourages user-facing locators:

The real magic is Auto-Waiting. Playwright waits for an element to be visible, stable, and enabled before performing an action. This eliminates the need for time.sleep(), which is the number one cause of slow and unreliable test suites.

Pro Tips for Playwright Success

Troubleshooting Common Issues

Issue: Browser doesn’t launch in CI/CD (GitHub Actions/Jenkins)
Solution: Ensure you are running in headless=True mode (the default) and that you have run playwright install-deps to install the necessary OS-level dependencies for the browsers.

Issue: Selectors not found on dynamic pages
Solution: Use the page.wait_for_selector() method or lean on the auto-waiting locators. If the element is inside an iframe, remember to use page.frame_locator().

What’s Next?

Now that you’ve mastered the basics, it’s time to scale. I recommend looking into the Page Object Model (POM) to organize your code as your test suite grows. If you’re still debating between tools, check out my Playwright vs Cypress comparison to see which fits your architecture better.

Want more automation tips? Subscribe to the newsletter for weekly deep-dives into productivity tools and dev-ops workflows.