Next Talk: KI-Agenten als QA-Engineer: Automatisierte Qualitätssicherung mit Claude Code & GitHub Actions

November 11, 2026 — QS-Tag, Frankfurt am Main

Conference
Skip to content

Run Only the Playwright Tests Your Change Can Affect

Published: at 

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.

From a code change to browser testsCompare Git revisions, map changed files to features, include dependent features, then select scenarios by their coverage tags.From a code change tobrowser testsChanged filesFeatures that own thosefilesInclude dependentfeaturesRun matching E2Escenarios

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 scope depends on what changedCheckout changes select checkout coverage. Cart changes also select consumers. Shared or unknown changes select the full suite. Counts include the purchase journey.The scope depends on what changedCheckout change• Checkout scenarios• Purchase journey• 4 of 14 testsCart change• Cart + productdetails + checkout• Purchase journey• 10 of 14 testsShared CSS change• All featurescenarios• Purchase journey• 14 of 14 tests

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.

ChangeBrowser tests executedResult
Checkout view4 / 14Passed
Search view5 / 14Passed
Cart view10 / 14Passed
Shared CSS14 / 14Passed

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:

# Excerpt from .github/workflows/verify.yml
- 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.testingtoolingci+2: 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.vuetestingvitest+2 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.vuearchitecturetypescript+1 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.

Press Esc or click outside to close

Stay Updated!

Subscribe to my newsletter for more TypeScript, Vue, and web dev insights directly in your inbox.

  • Background information about the articles
  • Weekly Summary of all the interesting blog posts that I read
  • Small tips and trick
Subscribe Now

Most Related Posts