DEV Community

Jessica Sales Melo
Jessica Sales Melo

Posted on Originally published at github.com

Playwright + BDD: Building an End-to-End Test Automation Framework from Scratch

Playwright + BDD: Building an End-to-End Test Automation Framework from Scratch

A practical guide to building a maintainable E2E test suite with Playwright, TypeScript and Gherkin.


Why this article? As a QA Engineer, I often hear that test automation is "just clicking buttons with code." In this post I walk through a production-ready approach: a BDD-driven E2E framework that is readable by devs/POs/QAs, easy to maintain, and green in CI — built with Playwright, TypeScript and playwright-bdd (Gherkin in Portuguese, the Belgium of the project's origin, but the pattern applies to any language).

This is a write-up of a portfolio project — the full, runnable source is on GitHub.

The stack

Tool Why
Playwright (1.6x) Reliable cross-browser automation (Chromium + Firefox here)
TypeScript (strict) Type safety across page objects and steps
playwright-bdd (9.x) Writes scenarios in Gherkin and executes them with the Playwright runner
Page Objects (POM) Centralized selectors, no hardcoding in tests
Allure Report Rich report with steps, screenshots and history
GitHub Actions CI that runs the suite and publishes the report on GitHub Pages

Project structure

├── features/            # BDD scenarios (Gherkin)
│   ├── login.feature
│   ├── inventory.feature
│   └── checkout.feature
├── steps/               # Step definitions (bridge Gherkin to code)
├── fixtures/            # Extended fixtures + injected Page Objects
├── src/pages/           # Page Objects
├── support/             # Environment config (.env)
└── playwright.config.ts # Playwright + playwright-bdd config
Enter fullscreen mode Exit fullscreen mode

1. BDD-first: write the feature, then the code

The beauty of BDD is the conversation. Scenarios are written in plain language, so Product Owners, Devs and QAs share the same understanding:

Feature: Login
  Scenario: Login with valid credentials
    Given I am on the login page
    When I fill in the valid credentials
    Then I am taken to the products page
Enter fullscreen mode Exit fullscreen mode

2. Bind Gherkin to code with step definitions

Each Given/When/Then maps to a step definition that uses fixtures to inject Page Objects:

Given('I am on the login page', async ({ loginPage }) => {
  await loginPage.open();
});

When('I fill in the valid credentials', async ({ loginPage }) => {
  await loginPage.login(STANDARD_USER, PASSWORD);
});

Then('I am taken to the products page', async ({ inventoryPage }) => {
  await inventoryPage.expectVisible();
});
Enter fullscreen mode Exit fullscreen mode

3. Page Objects: keep selectors in one place

A Page Object encapsulates the page's elements and actions, so the framework stays maintainable when the UI changes:

export class LoginPage {
  constructor(readonly page: Page) {
    this.username = page.locator('#user-name');
    this.password = page.locator('#password');
    this.submit = page.locator('#login-button');
  }

  async login(user: string, pass: string) {
    await this.page.goto('/');
    await this.username.fill(user);
    await this.password.fill(pass);
    await this.submit.click();
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Pluggable fixtures make steps concise

Using test.extend() + createBdd(), the Page Objects are injected into every step — no globals, no setup duplication.

5. Report & CI

  • Allure gives a rich, visual report; the CI publishes it on GitHub Pages (a live, navigable link in your README).
  • Robustness is a feature: workers: 1 + navigation retries tame flaky network access to public demo apps — the same lesson applies to single-session systems.

Takeaways

  • BDD is a collaboration tool, not just syntax.
  • Page Objects + typed fixtures = the difference between a script that breaks and a framework that scales.
  • Green CI with published reports is what makes a portfolio credible.

Want the full code? Check out the open-source project linked on my GitHub, where all 7 scenarios run green in CI with an Allure report deployed to GitHub Pages.


Jessica Sales — QA Engineer, focused on end-to-end automation, API testing and applying AI to the QA lifecycle.

Top comments (0)