Test Automation Best Practices in Action ( Part 2)

Core Framework & Test Design – Behavior-Driven Development (BDD) with Cucumber.

In our last post, we conquered the Page Object Model (POM) and cleaned up our test architecture. But let’s face a hard truth: no matter how beautiful your TypeScript code is, your Product Managers and Business Analysts probably aren’t going to read it.

When a feature breaks, non-technical stakeholders want to know what business requirement failed, not that page.locator('.btn').click() threw a timeout exception.

Enter Behavior-Driven Development (BDD) with Cucumber.

BDD bridges the communication gap between business and engineering by writing test scenarios in plain, readable English (Gherkin syntax). In this post, we’ll explore how to elegantly implement BDD in Playwright using the popular playwright-bdd library, and how we leverage our existing Page Objects to do the heavy lifting!


Step 1: Writing the User Story (The Gherkin Feature)

The beauty of BDD starts with the .feature file. This file acts as living documentation. In our repository, we define the background color customization feature like this:

@epic:UI_Components
@feature:Theming
Feature: Home Page Background Color
  As a user
  I want to change the background color
  So that I can customize my viewing experience

  @story:Background_Color_Customization
  @severity:normal
  @jira:UI-456
  Scenario Outline: Change background color
    Given I am on the home page
    When I click the "<color>" color button
    Then the active color text should be "<hex>"
    And the background color should be "<rgb>"

    Examples:
      | color     | hex     | rgb                |
      | Turquoise | #1abc9c | rgb(26, 188, 156)  |
      | Red       | #e74c3c | rgb(231, 76, 60)   |
      | Yellow    | #f1c40f | rgb(241, 196, 15)  |

💡 Expert Best Practices Applied Here:

  1. Rich Tagging for Reporting: Notice the tags at the top (@epic, @feature, @jira:UI-456)? These aren’t just for show. In a mature framework, these tags map directly to your reporting tools (like Allure Reports). When this test runs, it automatically links the results to Jira ticket UI-456 and categorizes it under the “Theming” feature!
  2. Data-Driven BDD: Instead of writing three separate scenarios for Turquoise, Red, and Yellow, we use a Scenario Outline with an Examples table. This keeps the feature file DRY (Don’t Repeat Yourself) and makes it incredibly easy for a Product Manager to add a new color to the test suite without writing any code.

Step 2: The Step Definitions (Where the Magic Happens)

A .feature file is just a text file until we map it to actual automation code. We use the playwright-bdd library to connect our Gherkin steps to Playwright actions. Check the example to repository

Here is how we map those steps in our bdd.spec.ts file:

import { createBdd } from 'playwright-bdd'
import { expect } from '@playwright/test'
import { HomePage } from '../pages/HomePage'

const { Given, When, Then } = createBdd()

let homePage: HomePage

Given('I am on the home page', async ({ page }) => {
  homePage = new HomePage(page)
  await homePage.goto()
})

When('I click the {string} color button', async ({}, color: string) => {
  await homePage.clickColorButton(color)
})

Then('the active color text should be {string}', async ({}, hex: string) => {
  await expect(homePage.currentColorText).toContainText(hex)
})

Then('the background color should be {string}', async ({}, rgb: string) => {
  await expect(homePage.header).toHaveCSS('background-color', rgb)
})

💡 Expert Best Practices Applied Here

  1. Reusing the Page Object Model (POM): The biggest mistake teams make with BDD is writing raw locators (page.locator(...)) directly inside their step definitions. This turns your BDD layer into an unmaintainable nightmare. Notice how our step definitions do almost nothing? They simply act as a proxy, passing the variables directly into the HomePage POM we built in Part 1! If the UI changes, we update the POM, and both our standard E2E tests and our BDD tests are fixed instantly.
  2. Parameterized Steps: By using {string} in our When and Then definitions, playwright-bdd automatically extracts the values from our feature file’s Examples table and passes them as arguments (color, hex, rgb) to our functions.

Summary

Implementing BDD doesn’t mean you have to sacrifice the speed or power of modern tools like Playwright. By combining Gherkin feature files, playwright-bdd, and a strict Page Object Model, you create a test suite that:

  • Product Managers can read and contribute to.
  • Engineers can maintain easily without duplicating locator logic.
  • Reports can parse intelligently using rich tagging.

In the next post, we will tackle the number one enemy of test automation: Flakiness. We’ll look at why you should stop using static waits and how to master network interception!

Do you want to do an exploration on this example together?

You can book some time with me to discuss your current situation and do exploratory testing of the sample of this post or any other kind of issue you met regarding Software Testing & Quality Engineering.