Skip to content

Instantly share code, notes, and snippets.

@didmar
Created February 15, 2026 14:47
Show Gist options
  • Select an option

  • Save didmar/2cd80f619f615925c46b73bc0e371b9d to your computer and use it in GitHub Desktop.

Select an option

Save didmar/2cd80f619f615925c46b73bc0e371b9d to your computer and use it in GitHub Desktop.

End-to-end tests with Playwright BDD

Our end-to-end tests are written with the help of the Playwright BDD framework.

The e2e folder (this folder) contains the global setup for the tests:

  • Global setup file e2e/global-setup.ts that runs once before all tests and resets the test user quotas
  • Fixtures file e2e/fixtures.ts that automatically logs in the test user before each test
  • Shared step files e2e/shared.steps.ts that implement shared steps for all features

Each feature or component in our application may have a tests sub-folder which contains:

  • Gherkin feature files tests/<bdd-feature-name>.feature
  • Step files tests/<bdd-feature-name>.steps.ts that implement the steps for each corresponding feature file
  • Shared step files tests/shared.steps.ts that implement shared steps for the feature or component

See also playwright.config.ts for the configuration of the tests, which is located in the parent folder.

Installation

Playwright needs to be installed:

pnpm exec playwright install

Test User Configuration

We use test users that are already signed up and ready to used for the tests.

The user credentials are stored in environment variables PLAYWRIGHT_EMAIL_1 and PLAYWRIGHT_PASSWORD_1. Load them from .env.e2e.

Note: If tests run sequentially (workers: 1), only one test user (_1) is needed. If that number of workers in playwright.config.ts is higher than 1, add additional test users with corresponding suffixes (_2, _3, etc.).

Running tests

Run all end-to-end tests:

pnpm run e2e

Run a specific test:

pnpm run e2e:grep "Name of the scenario"

View test report:

pnpm exec playwright show-report

Debug tests with Playwright UI (see video, console logs, etc.):

pnpm run e2e:ui

# Can also filter which scenarios will be listed (it won't run them directly, only list them), e.g.,
pnpm run e2e:ui -- viewing-and-editing
pnpm run e2e:ui -- viewing-and-editing-documents.feature:10

Writing a new end-to-end test

  1. The user should provide a rough outline of the scenarios that they intend to test.
  2. Create a tests folder in your feature/component directory (if it doesn't exist)
  3. Create a *.feature file with Gherkin syntax to describe the scenarios that they intend to test:
    • The file name should be the name of the feature or component, or of the scenario if there are already feature files, e.g., viewing-and-editing.feature in the documents feature.
    • Reuse the existing steps whenever possible: run grep "\(Given\|When\|Then\)(" **/shared.steps.ts to list all shared steps that are implemented. Those will be automatically discovered by Playwright BDD, so no need to import them in the step file.
  4. IMPORTANT: Ask the user to review the feature file and provide feedback on the scenarios and steps.
  5. Once the user is happy with the feature file, do NOT write any code yet. Instead, use Playwright MCP to manually perform the scenarios and take notes on the selectors and actions that you need to implement in the step file (write those down in a markdown file). It is very likely that the steps will need to be adjusted to how the UI actually works, so update the feature file accordingly.
  6. Based on your notes, add all necessary ARIA attributes in order to make selection more straightforward, while making the application more accessible at the same time.
  7. Check with the user that the changes made to the feature file are OK.
  8. Run pnpm run e2e:bddgen to generate snippets for the new steps.
  9. Fill in the new steps in the generated .steps.ts file, using your notes from the previous step.
  10. Run the test with pnpm run e2e -- <feature-file-name>.feature or pnpm run e2e:grep "Name of the scenario" for a specific scenario (if there are more than one).
  11. Fix any issues until the test passes. Keep the Playwright MCP open to help you debug any issues quickly, as this will be faster than re-running the tests multiple times!
  12. When the test passes, ask the user for review.
  13. Check any refactoring that could be done to improve the test, e.g. a step that is duplicated in multiple places, a step that is not DRY, etc.
  14. Ask the user for final review, and if they are happy, you may close the Playwright MCP.

Modifying an existing end-to-end test

Follow a similar process to writing a new end-to-end test:

  • Understand the changes that need to be made
  • Adapt the feature file to reflect the changes
  • Manually perform the updated scenarios
  • Update the feature file and step file to reflect the changes

Playwright Best Practices

Refer to the Playwright Best Practices documentation for more details.

Waiting Best Practices

  1. Never use page.waitForTimeout() - Only for debugging, never in production tests
  2. Trust auto-waiting - Most Playwright actions (click, fill, etc.) already wait for elements to be actionable
  3. Wait for specific conditions, not page states - Wait for observable changes (URL, element, response), not generic "page loaded"

Common Patterns

Navigation/Redirects

await page.click('#button') await page.waitForURL('**/expected-path')

Content Appears

await page.click('#load') await expect(page.locator('text=Success')).toBeVisible()

API Responses

await Promise.all([ page.waitForResponse('**/api/endpoint'), page.click('#fetch') ])

Element State Changes

await expect(page.locator('#element')).toBeVisible() await expect(page.locator('#element')).toBeHidden()

Load States (Rarely Needed)

  • page.goto(url) already waits for 'load' event - usually sufficient
  • Only specify waitUntil: 'domcontentloaded' if you need faster tests and don't need images
  • Avoid networkidle unless dealing with apps that have continuous network activity
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment