Skip to content

test: e2e Performance Regression Tracking#40518

Draft
gabriellsh wants to merge 9 commits into
developfrom
chore/performanceRegressionTests
Draft

test: e2e Performance Regression Tracking#40518
gabriellsh wants to merge 9 commits into
developfrom
chore/performanceRegressionTests

Conversation

@gabriellsh
Copy link
Copy Markdown
Member

Proposed changes (including videos or screenshots)

Performance Regression Testing Infrastructure

A generic, opt-in fixture library for Playwright e2e tests. Import the extended test object and destructure only the fixtures you need — unused fixtures are never activated, and no existing tests are affected.

Usage

import { test, expect } from './performance/fixtures'

test('home load vitals', async ({ page, webVitals }) => {
  await page.goto('/home')
  const vitals = await webVitals.getVitals()
  expect(vitals.LCP).toBeLessThan(2500)
  expect(vitals.CLS).toBeLessThan(0.1)
})

Fixtures

Fixture What it provides
cdpSession CDP session with Performance.enable, Memory.prepareForLeakDetection, 4× CPU throttling (mid-range device simulation), and Fast 3G network conditions (offline: false)
webVitals LCP, CLS, INP captured via PerformanceObserver injected before the first byte loads; reads after requestIdleCallback to ensure INP is fully captured
heapSnapshot Heap snapshot helper with a warm-up run and GC-before-snapshot; use detectLeak() to assert heap growth stays within a threshold across N journey iterations
longTaskTracker CDP PerformanceTimeline listener for JS tasks >50ms, each attributed to a navigationId to distinguish initial hydration from SPA route-change tasks
softNavTracker Experimental Soft Navigation API — maps interaction-contentful-paint to "Soft LCP" per route via interactionId matching; falls back silently on non-supporting builds
lighthouseAudit Per-worker Lighthouse helper with a dynamically acquired port (get-port). Call newPage() to authenticate, then runAudit(url). Uses disableStorageReset: true to preserve Playwright auth state

All fixtures that depend on CDP (heapSnapshot, longTaskTracker) automatically activate cdpSession.

Baseline comparison

reporter/baseline.ts stores golden baselines in reporter/baselines/<suite>.json and diffs against them on each run.

import { assertWithinBaseline, saveBaseline } from './performance/reporter/baseline'

test('sidebar render time', async ({ page, cdpSession }) => {
  const before = await getMetrics(cdpSession)
  await page.goto('/home')
  const after = await getMetrics(cdpSession)
  const renderTime = after.TaskDuration - before.TaskDuration

  assertWithinBaseline('sidebar', 'renderTime', renderTime)
})

Adaptive thresholds

Thresholds are applied to the median across runs and scale automatically:

Baseline value Allowed variance
< 200 ms 30%
200 ms – 2 s 20%
> 2 s 10%

Failures include a [View Trace](path) link for direct access to the Playwright Trace Viewer.

Updating baselines

Run with UPDATE_PERF_BASELINES=true to overwrite the stored baseline after an intentional change:

UPDATE_PERF_BASELINES=true npx playwright test --project=performance

CI sharding

When tests are sharded across runners, set PERF_SHARD_RESULTS_DIR to a directory containing per-shard JSON artifacts. baseline.ts will merge them before computing the median.

Playwright project

The performance project in playwright.config.ts runs all tests/e2e/performance/**/*.spec.ts files with:

  • trace: on-first-retry — captures traces for failing tests without bloating artifacts
  • --enable-experimental-web-platform-features — required for the Soft Navigation API
  • repeatEach: 3 in CI — enables statistically stable median calculation

Run it with:

npx playwright test --project=performance

File structure

performance/
├── fixtures.ts                  # Main entry point — import test from here
├── collectors/
│   ├── cdp.ts                   # CDP session helpers
│   ├── web-vitals.ts            # LCP / CLS / INP collection
│   ├── memory.ts                # Heap snapshot and leak detection
│   └── long-tasks.ts            # Long task tracking (>50ms)
├── lighthouse.ts                # Lighthouse fixture
├── soft-navigation.ts           # Soft Navigation API tracker
└── reporter/
    ├── baseline.ts              # Adaptive baseline comparison
    └── baselines/               # Checked-in JSON snapshots

Issue(s)

Steps to test or reproduce

Further comments

@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot Bot commented May 13, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 13, 2026

⚠️ No Changeset found

Latest commit: 3a53d12

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cf270b14-5250-4a90-8184-c9804aecbb03

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.60%. Comparing base (b6b04aa) to head (3a53d12).
⚠️ Report is 21 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop   #40518   +/-   ##
========================================
  Coverage    69.60%   69.60%           
========================================
  Files         3320     3321    +1     
  Lines       122512   122543   +31     
  Branches     21840    21816   -24     
========================================
+ Hits         85273    85299   +26     
- Misses       33910    33915    +5     
  Partials      3329     3329           
Flag Coverage Δ
unit 70.32% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant