cd /news/developer-tools/run-only-the-playwright-tests-your-c… · home › topics › developer-tools › article
[ARTICLE · art-145217] src=alexop.dev ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Run Only the Playwright Tests Your Change Can Affect

Developer Alexander Op built feature-shop, a Nuxt demo shop, to test a CI approach that runs only the Playwright end-to-end scenarios affected by a code change, using feature folders, @feature tags, and a dependency map in tools/impact.ts. In four pull requests against the same base commit, a checkout view change ran 4 of 14 browser tests, a search view change ran 5 of 14, a cart view change ran 10 of 14, and a shared CSS change ran all 14, with all runs passing in GitHub Actions. The setup requires Node 24 and pnpm 10, and shared styles, test infrastructure, or unknown files trigger the full suite.

by read6 min views1 publishedOct 5, 2026
Run Only the Playwright Tests Your Change Can Affect
Image: Alexop (auto-discovered)

With AI writing more of our code, I keep coming back to the testing discussion. Are unit tests still useful? How much confidence do they give us when an agent writes both the implementation and the tests?

I still want unit tests for business rules. But I also want to open the application, add something to a cart, and complete a checkout. An end-to-end test checks whether those pieces work together, through the interface someone uses.

The problem is the waiting. If I change checkout validation, do I need to run every search scenario before getting feedback?

Last week I built feature-shop, a small Nuxt shop, to try a different approach: run the E2E tests for the changed feature and the features that depend on it.

Feature folders give us a starting point #

In the shop, search, product details, cart, and checkout each have their own feature folder. The browser tests follow the same structure.

app/features/
  search/
  product-detail/
  cart/
  checkout/
tests/e2e/features/
  search/
  product-detail/
  cart/
  checkout/

That makes ownership easier to describe. A change in app/features/checkout/ belongs to checkout. The selector can find the scenarios tagged with @checkout and run them.

Each scenario also has a stable ID. This one checks the result a customer cares about:

@checkout
Feature: Simulated checkout
  @id:checkout-success
  Scenario: Successful checkout clears the cart
    Given my cart contains 1 backpacks
    When I open checkout
    And I enter valid customer details
    And I choose an approved payment
    And I place my order
    Then my order is confirmed
    And my receipt total is "40.00"
    When I open my cart
    Then my cart is empty

I use Playwright-BDD to connect these sentences to Playwright fixtures and page objects. You can use the same selection idea with plain Playwright tests and tags.

A cart change can break checkout #

Folder names alone aren’t enough. Checkout uses the cart. Product details let you add an item to it. If I change cart behavior, I need to test those consumers too.

In tools/impact.ts, I describe the file ownership and dependencies. The selector follows consumers, including indirect ones, until it has the affected set.

The purchase journey crosses feature boundaries, so I tag it with all the features it covers. A checkout change still runs that complete journey.

Shared styles, dependencies, test infrastructure, and unknown files trigger the full suite. So does an unavailable Git comparison. Documentation-only changes select no browser scenarios, but CI still runs the static checks and unit tests.

This depends on keeping the ownership map and scenario tags accurate. A feature folder doesn’t prove isolation. Review dependencies when you add imports, shared state, or API interactions.

What happened in GitHub Actions #

I opened four small pull requests against the same base commit. Each changed one application file.

Change Browser tests executed Result
Checkout view 4 / 14 Passed
Search view 5 / 14 Passed
Cart view 10 / 14 Passed
Shared CSS 14 / 14 Passed

The verification record links to each PR and Actions run. It records comparisons between selected scenario IDs and the tests Playwright executed.

These are test counts, not a speed benchmark. Installing dependencies, building the application, and starting the browser still cost time.

Try the same setup #

Use Node 24 and pnpm 10. These commands check out the published version behind this post, including its tests and workflow:

git clone https://github.com/alexanderop/feature-shop.git
cd feature-shop
git checkout -b try-affected-tests 2bb25da27c6481e52b8e9f19823ae4659b392453
pnpm install --frozen-lockfile
pnpm exec playwright install chromium
pnpm check
pnpm verify run --all

Leave port 3401 free. The runner builds and starts the shop for you. On Linux, use pnpm exec playwright install --with-deps chromium to install browser system dependencies too.

Edit app/features/checkout/CheckoutView.vue, then inspect the selection before running it:

pnpm verify plan --affected
pnpm verify run --affected

Expect the three checkout scenarios and the purchase journey. The default comparison includes uncommitted changes against HEAD. After committing your edits, use --base main to include your branch changes.

For GitHub Actions, fork the repository, enable Actions if GitHub prompts you, and open a PR against your fork’s main branch. The existing complete workflow contains dependency installation, checks, the production build, and report uploads. Its selection step is:

- name: Run affected scenarios
  if: github.event_name == 'pull_request'
  env:
    VERIFY_SKIP_BUILD: '1'
    VERIFY_BASE: ${{ github.event.pull_request.base.sha }}
    VERIFY_HEAD: ${{ github.event.pull_request.head.sha }}
  run: pnpm --silent verify run --affected --base "$VERIFY_BASE" --head "$VERIFY_HEAD" --json

pnpm verify is this project’s CLI, not a built-in Playwright command. It compares changes from the Git merge base, selects scenario IDs, and passes them to Playwright’s --grep filter.

The workflow fetches Git history with fetch-depth: 0 and tests the PR head commit. It runs all scenarios on main, on a weekly schedule, and on manual runs.

To adapt this to your own app, copy the selector and runner with their supporting files in tools/, then map your paths, dependencies, and scenarios. Adapt the Playwright configuration and workflow to your application’s start command. Copying the YAML excerpt alone won’t create that setup.

Keep checking the selection #

Set the repository Actions variable SHADOW_FULL_SUITE=true while evaluating this approach. Successful selective runs will then continue into a full run, so you can look for failures outside the selected tests. In this published workflow, a failed selective step stops that later step.

A full run on main can catch missed dependencies after merging. It cannot protect the PR before merging. Keep the full pre-merge run if you need that assurance.

This fits how I think about a modern quality pipelineA Modern Quality Pipeline and Testing Strategy for Frontend ProjectsA short, framework-agnostic concept of what a modern quality pipeline and testing strategy look like for any JavaScript or TypeScript frontend project.: give yourself and your agent useful feedback at a cost you can afford. I’ve covered what a passing browser test should proveWhat Should a Green Test Prove? Vue Testing with Vitest Browser ModeA CSS bug passes in jsdom but blocks a real purchase. Build Vue tests around behavior, accessibility, and visual regression with Vitest Browser Mode. and where to put code so you can test business rules separatelyHexagonal Architecture in Vue: Where to Put Your Code and WhyLearn what belongs in Vue components, composables, the application core, and adapters. Use ports and adapters to make rules easier to test and changes easier to contain. in earlier posts.

I still want those unit tests. I also want browser tests that tell me whether someone can complete a purchase. With clear feature boundaries, I can run the relevant journeys while working and keep broader regression checks in the pipeline.

── more in #developer-tools 4 stories · sorted by recency
── more on @alexander op 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/run-only-the-playwri…] indexed:0 read:6min 2026-10-05 · —