Adding E2E Setup With PlayWright And Cucumber In TypeScript Project
Cucumber
Playwright
TypeScript
01/05/2023
In this post, I'll demonstrate how to set up an end-to-end (E2E) testing framework using Cucumber and Playwright in your TypeScript project.
Installing dependencies
First, add the following libraries as dev dependencies to your project.
yarn add --dev @cucumber/cucumber @playwright/test # ORnpm install --save-dev @cucumber/cucumber @playwright/test
Setting up Cucumber
It should be noted that the testing framework is operated entirely by Cucumber, and Playwright is merely plugged 🔌 into it. Theoretically, you can switch it out for any browser automation tool such as Cypress or Selenium.
Features folder
All your E2E code will live in a folder named features
at the root of your project.
Feature file
Inside of your features
folder, you'll will have .feature
files which represent your Cucumber 🥒 files. To test the entire setup, let's create an example file.
Feature: Greeting Scenario: Say hello When the greeter says hello Then I should have heard "hello"
Support file
In the background, your feature files are executed by TypeScript files located in a steps
folder. Their file names must correspond to the name of the feature file they are executing.
import { When, Then } from "@cucumber/cucumber"
interface MyWorld { whatIHeard: string}
When("the greeter says hello", function(this: MyWorld) { this.whatIHeard = "hello"})
Then("I should have heard {string}", function( this: MyWorld, expectedResponse: string) { // Make assertion here})
Configuration file
What we have so far is enough to execute an E2E test. However, for that to happen we have to specify a host of parameters in the CLI, such as the Typescript execution engine, the location of the step definitions, etc. We can avoid repeating 🙏 these parameters on every test run by creating a cucumber.mjs
file at the root of your project that stores theses parameters.
const configuration = { requireModule: ["@swc-node/register"], require: ["features/steps/**/*.ts"], // Optional below format: ["summary", "progress-bar"], formatOptions: { snippetInterface: "async-await" },}
export default configuration
Specify a TypeScript execution engine of your choice in requireModule
, such as @swc-node
or ts-node
. Oddly, ts-node
did not work for me. 🤔
I recommend checking out the overview of all the configuration options for further reference.
Installing Playwright
With the current setup in place, you can already execute 😲 the test with yarn/npm run cucumber-js
with a pass. However, it's passing because we aren't making any assertions, for which we will use Playwright.
Returning to the step file, make the following changes:
+ import { expect } from "@playwright/test";# [...]
Then( "I should have heard {string}", function (this: MyWorld, expectedResponse: string) {+ expect(this.whatIHeard).toEqual(expectedResponse); });
To check if the assertion actually works, simply change the casing of the string "hello"
and you will receive a failed ❌ test after running Cucumber.
- this.whatIHeard = "hello"+ this.whatIHeard = "Hello"
While you are now capable of running tests, you are nevertheless missing the proper setup to keep each test independent of each other. Check out my walk-through on how to do so.