One Journey, Two Platforms: Merging Safely with E2E Testing and BDD
How we use E2E tests and BDD to improve alignment across stakeholders and establish an effective safety against regression
One Journey, Two Platforms: Merging Safely with E2E Testing and BDD

When two fast-paced e-commerce platforms merge, the pressure is high: unify features, maintain a seamless user experience, and build new capabilities, all while continuing to deliver a reliable product. At the consumer experience team at GetAway Group, we’ve found that an End-To-End (E2E) testing strategy grounded in Behavior-Driven Development (BDD) is a powerful combination, especially now, that we are kicking off our first big, business critical project.
In this post, I’ll share how we use E2E tests and BDD to unlock potentials to improve communication and alignment across stakeholders, establish an effective safety net against regressions, and leverage AI to accelerate the process.
Reality-Check
In my experience as a developer, we don’t enjoy writing tests — especially if we’ve spent years building software without them. When you’re used to pushing code without tests, you often develop a high tolerance for errors, unexpected outages, or last-minute fixes in production.
Maybe this way of working has worked for many years, but that mindset doesn’t scale. To stay competitive, it’s not enough to deliver something that works right now, most of the time. As developers, our job is to build software that is robust, maintainable, and adaptable to change — while also being performant and secure.
One common reason tests are neglected is that they’re often hard to maintain and even harder to read — especially if someone else wrote them. They’re frequently written with the mindset that “it’s not production code,” which results in poor readability and reusability.
A Developer’s Ode to Testing and BDD
Test code matters just as much as application code. It’s our safety net — the thing that might prevent us from getting a call from our manager at 2 AM on a Sunday. It’s not there to slow us down; it’s there to help us move faster safely. And that’s why it deserves attention.
BDD addresses many of the reasons developers dislike testing. Instead of focusing on technical implementation details, BDD encourages you to write out the intended behavior of the application and the users expectations and actions in simple, readable, human language. Combined with Playwright and its clean architecture (like the Page Object Model), we’re able to keep our tests modular, maintainable, and approachable.
That said, we’re also mindful about what we test. Not everything needs end-to-end coverage. It’s a common pitfall, trying to cover every edge case with E2E tests which results in a huge test suite that takes forever to run in your CI chain. Instead we focus on the most critical paths — like the checkout and payment processes — where failures would impact users the most. For everything else, we rely on unit and integration tests in the right layers.
The tools: Microsoft Playwright and Playwright BDD
What is Playwright
Microsoft Playwright is a browser automation framework that enables end-to-end testing across multiple browsers (Chromium, Firefox, WebKit). Tests are commonly written in Javascript or Typescript.
What is Playwright BDD
Playwright-bdd is a piece of software that allows you to write tests following the BDD principles that can be executed with playwright.
BDD and E2E: From Behavior to Execution
Behavior-Driven Development (BDD) is all about defining how the system should behave, not how it is implemented. To define our test scenarios, we use the Gherkin syntax (Given-When-Then) to describe user journeys in a format that’s both human-readable and machine-executable:
# ~./features/CheckoutWithPaypal.feature
Feature: Checkout with PayPal
Scenario: As a kurz-mal-weg.de customer I successfully book a trip and pay via PayPal
Given I navigate to the booking configuration page for offer "12345"
When I pick the earliest available travel date
And I proceed to the checkout page
And I fill out the billing address form:
| salutation | firstname | lastname | street | zip | city | phone | email |
| Ms | Hannelore | Maffay | Entengasse 4 | 12043 | Berlin | 1234567 | development@example.com |
And I specify the travelers:
| salutation | firstname | lastname |
| Mr | Peter | Maffay |
| Ms | Hannelore | Maffay |
And I fill "Test booking!" in the comment field
And I select that I don't want insurance
And I select paypal as payment method
And I click on 'Pay with PayPal'
And I fill email "development@example.com" on the PayPal login popup
And I click 'Continue' on the PayPal login popup
And I fill out the password on the PayPal login popup
And I click 'Log In' on the PayPal login popup
And I click 'Complete Purchase' on the PayPal login popup
Then I should see "Your booking was successful" on the booking confirmation page
These BDD scenarios are written in natural language, and serve as both documentation and executable end-to-end tests. This dual role makes them a reliable source of truth for expected behavior — clear enough for non-technical stakeholders to read (and even write!) and structured enough for developers to automate and run across both brands.
AI-Powered Test Development
When looking at the example .feature file, you probably already guessed it: Because of its uniform and predictable structure, BDD is a great fit for AI-assisted test generation. If your tickets are written clearly—especially in the form of user stories—you could just copy the content of a Jira ticket into e.g. Gemini, ChatGPT or Claude and have it generate a matching .feature file for you.
Example
Prompt:
You are a software engineer. You received a new ticket with a feature request. Convert the Ticket’s contents into a BDD-Style feature file, following the Gherkin Syntax:
Newsletter subscription request
As a customer i want to subscribe to the newsletter so that I can receive all the latest offers and discounts.
I navigate to /newsletter.html (coming from the link in the footer or the newsletter modal). I can enter my E-Mail address, salutation, firstname, lastname and date of birth. When I click the submit button, I want to see a message: “Click the link in the email that we sent you to confirm your newsletter subscription”. Also, that email has to be sent, containing the confirmation link
ChatGPT 4o output:
Feature: Newsletter subscription request
As a customer,
I want to subscribe to the newsletter,
So that I can receive all the latest offers and discounts.
Background:
Given I am a customer on the newsletter subscription page at "/newsletter.html"
Scenario: Subscribing to the newsletter with Single-Opt-In
When I enter my E-Mail address as "user@example.com"
And I enter my salutation as "Mr."
And I enter my firstname as "John"
And I enter my lastname as "Doe"
And I enter my date of birth as "1980-01-01"
And I click the submit button
Then I should see a message saying "Click the link in the email that we sent you to confirm your newsletter subscription"
And a confirmation email should be sent to "user@example.com"
And the email should contain a link to confirm the newsletter subscription
Generate test implementation
We currently use **Playwright’s Codegen** tool to record browser interactions to automatically generate ready-to-use copy-pasteable code snippets. This eliminates the need to manually search the DOM for selectors, making test development faster, more efficient, and easier to adopt.
In parallel, we’re evaluating **Playwright MCP (Model Context Protocol)** which was launched by Microsoft recently. MCP enables LLMs to interact with web pages in a structured way through the browser’s accessibility tree, offering a more reliable and deterministic approach to tasks like selector generation, navigation, and debugging.
Also the playwright-bdd project is already exploring an integration with MCP (issue #321), which could bring these capabilities directly into our BDD workflows and further streamline test development.
Test Structure: Feature Files, Steps, and Pages
Our test architecture follows a clean and consistent structure consisting of three layers:
- Feature files define the
.featurefile (Gherkin syntax). The users expectations, the applications behavior, the users behavior. Non-technical.
// ...
As a kurz-mal-weg.de customer ...
When I fill out the billing address form:
// ...
- Step definitions implement those behaviors in
.steps.tsfiles. Think of it as a translation layer. Define which actions should happen.
// ~./steps/CheckoutWithPayPal.steps.ts
// ...
When('I fill out the billing address form:', async ({ page, testContext }, billingAddresses: DataTable)=> {
const billingAddress = billingAddresses.hashes()[0];
testContext.checkoutPage = new CheckoutPage(page);
await testContext.checkoutPage.fillOutBillingAddress(billingAddress)
});
// ...
- **Page Object Models (POM)** encapsulate UI logic in reusable components, so-called Pages. That should be the only place where we have to dive into the DOM. Here is the right place to set and assert the state.
// ~./pages/CheckoutPage.ts
// ...
async fillOutBillingAddress(billingAddress: Record<string, string>){
await this.page.locator('#customerSalutation').selectOption(billingAddress.salutation!);
await this.page.locator('#customerFirstname').fill(billingAddress.firstname!);
await this.page.locator('#customerLastname').fill(billingAddress.lastname!);
await this.page.getByRole('textbox', { name: 'Straße und Hausnummer*' }).fill(billingAddress.street!);
await this.page.getByRole('textbox', { name: 'PLZ*' }).fill(billingAddress.zip!);
await this.page.getByRole('textbox', { name: 'Ort*' }).fill(billingAddress.city!);
await this.page.getByRole('textbox', { name: 'Telefon*' }).fill(billingAddress.phone!);
await this.page.getByRole('textbox', { name: 'E-Mail*' }).fill(billingAddress.email!);
}
// ...
This setup makes it easy to extend and maintain tests across our multi-brand ecosystem, without duplicating test logic or rewriting similar flows. Due to the nice separation of concerns, Pages and step definitions are modular and reusable.
CI Integration
We recently switched to a trunk-based CI/CD flow. This is how our E2E testing process works:
- Whenever code is merged into the main branch, the E2E test step gets executed
playwright-bddconverts the feature files and their steps into playwright E2E tests- Playwright runs the tests in parallel in our CI pipelines
- HTML Reports and videos are uploaded to a shared cloud bucket, accessible by everyone in the team
- To make failures visible immediately, we also send a Slack notification to a dedicated channel with a link to the test report whenever a test fails. This helps the team to react quickly, because we know immediately if a recently merged PR potentially broke another part of the system.
This setup ensures we catch regressions early and have clear visibility into how each commit affects critical functionality.
Final Thoughts
As we merge and redesign features from two platforms into a single, cohesive application, the need for clarity and reliability becomes more critical than ever. The E2E tests are not tied to a specific tech stack, run independently so they can easily be rolled out to both platforms we are actively reconsolidating. By combining end-to-end testing with Microsoft Playwright, Behavior-Driven Development, driven by AI-assisted workflows, we’re building a cornerstone of the foundation for a robust and future-proof architecture.
Recommended sources:
메타데이터
- post_id
- 7bb592709d1c
- slug
- one-journey-two-platforms-merging-safely-with-e2e-testing-and-bdd-7bb592709d1c
- url
- https://medium.com/getaway-group-tech-blog/one-journey-two-platforms-merging-safely-with-e2e-testing-and-bdd-7bb592709d1c
- canonical_url
- https://medium.com/getaway-group-tech-blog/one-journey-two-platforms-merging-safely-with-e2e-testing-and-bdd-7bb592709d1c
- author_url
- https://medium.com/@nicolai.storz
- status
- ok
- fetched_at
- 2026-07-17 23:36:04