KNOWLEDGE / 05
TypeScript, Playwright and BDD
Type-safe web automation, Playwright patterns, and pragmatic BDD.
Questions and practice
Open a question to see the answer, examples, and exercises.
Why is await important?Junior
Answer
Without awaiting a Promise, the next action may start before the previous one finishes and an error may escape the intended handler.
Examples
- A click without await may race with a navigation assertion.
Practice exercises
- Find a missing await in a short test and explain the possible event order.
What does structural typing mean in TypeScript?Junior
Answer
TypeScript checks compatibility mainly by value shape: an object fits when it has the required fields and types, regardless of its class name. This is convenient for APIs and dependency injection, but compile-time types disappear at runtime, so external data still needs validation.
Examples
- A function accepts an object with a send() method; any implementation with a compatible signature satisfies the contract.
Practice exercises
- Define an interface for an API client and show why a type assertion alone does not make a JSON response safe.
How should stable Playwright locators be chosen?Junior
Answer
Prefer user-facing semantics such as role, accessible name, label, or a stable test id. Long CSS or XPath selectors couple tests to incidental DOM structure and often break after layout changes. A locator should express intent clearly and fail when it unexpectedly matches multiple elements.
Examples
- getByRole('button', { name: 'Save' }) expresses behaviour better than div:nth-child(3) > button.
Practice exercises
- Rewrite five brittle CSS selectors using role, label, or test id and explain each choice.
Why use an isolated browser context?Middle
Answer
It separates cookies and browser state between tests; backend data must be isolated separately.
Examples
- Two tests may have separate browser sessions but still collide on one user record in the database.
Practice exercises
- Run two scenarios in parallel and identify browser and backend state that must be isolated.
How do web-first assertions differ from immediate checks?Middle
Answer
A web-first assertion repeatedly reads state through a locator until success or timeout, accounting for asynchronous UI updates. An immediate snapshot check can land between render cycles. Wait for a business-meaningful state rather than hiding endless loading behind a large timeout.
Examples
- expect(locator).toHaveText('Paid') waits for the target state, while immediately checking textContent may see the old value.
Practice exercises
- Replace manual polling and fixed sleep with web-first assertions in a scenario with an asynchronous status update.
How can Playwright fixtures be used without hidden magic?Middle
Answer
Fixtures should provide clearly named resources with an appropriate scope and automatic cleanup. A worker-scoped fixture suits expensive read-only setup, while test scope suits mutable state. An oversized automatic fixture hides dependencies and makes tests difficult to read and diagnose.
Examples
- authPage creates an isolated context per test, while an API client with base configuration can be worker-scoped.
Practice exercises
- Split one large fixture into authentication, data setup, and page objects; choose scope and cleanup for each.
What should Gherkin describe?Senior
Answer
Observable business behaviour and the expected outcome; small technical actions belong in step implementations.
Examples
- A step such as “the customer completes payment” is more stable than listing every CSS selector and click.
Practice exercises
- Describe checkout in Gherkin and move API setup and technical details into reusable steps.
When is network mocking in a browser test justified?Senior
Answer
Mocking is useful for deterministic failures, slow dependencies, and UI states that are hard to reproduce. It isolates frontend behaviour but risks drifting from the real API. Validate fixture contracts and additionally run critical flows against the real integration.
Examples
- route.fulfill returns 429 with Retry-After to test the message and the user’s retry action.
Practice exercises
- Choose three scenarios for mocks and two for a real backend, then define protection against stale response fixtures.
How do traces help diagnose parallel Playwright tests?Senior
Answer
A trace combines actions, DOM snapshots, network, console, and timing for one test. In CI this is much more useful than a single screenshot, especially for race conditions. Store traces under a clear retention policy, avoid secrets, and pair them with unique test data for reproduction.
Examples
- A trace shows that worker B changed a shared order between worker A’s click and assertion.
Practice exercises
- Configure trace on-first-retry and list the evidence needed to separate a product defect from a test-isolation issue.