Skip to content

[Feature]: Skip a single step at runtime with $step.skip() #401

Open

Description

@lemonlion

PR with an implementation, tests and docs: #400

The Problem

I run the same playwright-bdd suite against two setups: a local stack where the dependencies are mocks and databases I control, and a deployed environment where they're real. Nearly every step works in both, but a handful only make sense locally, for example checking that a mock received a request, or that a row landed in the local database.

Right now there's no way to skip just one of those steps. $test.skip() takes the rest of the scenario down with it. Take this checkout scenario, run against a deployed environment where the payment mock doesn't exist:

Scenario: Customer pays by card
  Given the basket has 2 items
  When the customer pays by card
  Then the payment mock received one charge
  And the order confirmation is shown
  And the basket is empty

With $test.skip() in the payment mock step, Playwright's report draws that step with a red cross, just like a failure. The two steps after it never run, even though they'd pass against the deployed environment, so the report only lists three of the five steps. And because the whole test now counts as skipped, it drops out of the report's default view, which says "No tests found" until you click Skipped:

Playwright HTML report with $test.skip(): the test is marked skipped, the payment mock step shows a red cross like a failure, and only three of the five steps are listed because the last two never ran

The Cucumber report lists all five steps, which makes the gap easier to see. Everything from the payment mock step onwards is skipped:

Cucumber HTML report with $test.skip(): the first two steps passed, and the payment mock step and both steps after it are skipped

The other workarounds aren't much better. Returning early from the step makes it go green without checking anything, and keeping trimmed copies of those scenarios means two copies of everything that slowly drift apart.

Proposed Solution

A $step.skip() method on the $step fixture that works like Playwright's own testStepInfo.skip() (added in 1.51). It stops the current step, marks it as skipped, and the scenario carries on with the next step:

Then('the payment mock received one charge', async ({ $step, request }) => {
  $step.skip(process.env.TARGET !== 'local', 'The payment mock only runs locally');
  const charges = await request.get('http://localhost:3001/charges');
  expect(await charges.json()).toHaveLength(1);
});

Here's the same scenario with the change in #400. The test passes, the payment mock step shows as skipped with its reason, and the two steps after it run and pass:

Playwright HTML report with $step.skip(): the test passed, the payment mock step shows as skipped with its reason, and the two steps after it ran and passed

And in the Cucumber HTML report, compared with the one above, the step gets the SKIPPED status with the reason shown under it, and the two steps after it now pass:

Cucumber HTML report with $step.skip(): the skipped step shows its reason in italics and the two steps after it passed, while the summary reads 0% (0 / 1) passed

Happy to change anything about the approach.

Additional Context

LightBDD in .NET has a step-level bypass for exactly this, and it made it easy to keep one suite for both a local run and a run against a deployed environment. Playwright's step skip gets most of the way there already, it just isn't reachable from a step definition yet.

Priority Level

Medium

Activity

  1. added a commit that references this issue on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions