PRACTICAL GUIDE / Playwright tracing startHar scoped recording
Record Scoped HAR Files with Playwright Tracing
Learn Playwright tracing startHar scoped recording with working code, failure cases, debugging steps, and CI evidence for reliable QA automation.
In this guide11 sections
- Define the Network Decision and Scope
- Check the Version and Prerequisites
- Build the Smallest Working Implementation
- Capture Request, Response, and Protocol Evidence
- Design Positive, Negative, and Boundary Cases
- Compare the Available Playwright Network APIs
- Protect Secrets in HAR, Traces, and Logs
- Debug Missing or Misleading Network Evidence
- Add Deterministic CI Gates and Artifact Retention
- Frequently Asked Questions
- What does context.tracing.startHar record?
- How do I stop a scoped HAR when a test fails?
- Can two HAR recordings run in the same BrowserContext?
- Which startHar options reduce sensitive capture?
- How is startHar different from recordHar?
- Should CI retain every scoped HAR file?
- Practice the Complete Evidence Decision
What you will learn
- Define the Network Decision and Scope
- Check the Version and Prerequisites
- Build the Smallest Working Implementation
- Capture Request, Response, and Protocol Evidence
Playwright tracing startHar scoped recording captures only the network interval and URL family that matter to one test decision. Start the HAR after setup, trigger the user behavior, assert the first observable result, and always stop recording in cleanup. The file then connects a visible failure to transport evidence without replacing a live integration check.
That boundary is the main advantage over context-wide capture. A focused recording can show which checkout request failed while leaving login and unrelated analytics outside the file. It also complements Playwright HAR network mocking without pretending a recording proves the current backend contract. Pair it with an intentional trace, video, and screenshot evidence pipeline when the UI chronology matters too.
Define the Network Decision and Scope
Begin with a question that a HAR can answer. "Did the save request send the expected method and receive the documented status?" is testable. "Why is checkout broken?" is too broad. Name the first user-visible assertion, the request family that can explain it, and the point after which more recording adds no diagnostic value.
A useful scoped case has three boundaries:
- Time: recording begins after reusable setup and ends after the relevant response is complete.
- URL:
urlFilteradmits only the endpoint family required by the scenario. - content: the
contentandmodeoptions preserve only fields needed for the decision.
For example, an order submission test may begin recording after the authenticated cart is visible, use /\/api\/orders(?:\/|\?|$)/ to include both the exact collection path and its query or descendant forms, then stop after the confirmation state appears. Authentication requests, feature configuration, fonts, and analytics remain outside the HAR. The browser action still reaches the real order service unless another route changes it.
Keep the claim equally narrow. A 201 response and correct confirmation can support the tested order path. They do not prove every API consumer, region, proxy, retry, or certificate path. Use direct Playwright API testing for broader HTTP contracts and keep a small live browser path for user behavior.
Write the failure boundary before code. If the save button never becomes enabled, the case failed before the target request. If the request starts but receives 422, HAR evidence belongs to the decision. If the UI stays pending after a successful response, the transport record is context for a client-state defect, not proof that the network failed.
Check the Version and Prerequisites
The Playwright release notes list tracing.startHar() and tracing.stopHar() as additions in version 1.60. The examples here use installed Playwright 1.61.1. Check the package actually executed by CI, not only a version range in a manifest, because a stale lockfile or container can make valid source code fail at runtime.
The Tracing API reference defines these current rules:
startHar(path, options)belongs toBrowserContext.tracingand returns aDisposable.- Only one HAR recording may be active in a BrowserContext.
stopHar()finalizes the path passed tostartHar().- A
.zippath stores response bodies as attached archive entries by default; other extensions embed them by default. resourcesDirapplies only withcontent: 'attach'and cannot be combined with a.zipHAR path.
Create a unique output path for every test. testInfo.outputPath() gives a test-owned location that remains separate across workers and retries. A shared network.har path can be overwritten by a second worker or leave a previous attempt's bytes where a later test expects fresh evidence.
Decide whether your TypeScript configuration supports explicit resource management before adopting await using. The returned Disposable makes lexical scoping concise, but a try/finally block is clear and works in projects that have not enabled that syntax. Whichever form you choose, one helper must own both start and finalization.
Finally, identify prerequisites that happen before capture: account creation, authentication, cart seeding, and navigation to a stable starting screen. Setup through a limited fixture reduces noise, but it must not hide the business action under test. A trace inspected with the Playwright CLI trace analysis workflow can confirm exactly where the recording window sits relative to the click and assertion.
Build the Smallest Working Implementation
The first implementation should use one context, one target endpoint, one user action, and one result assertion. Start recording only after the page is ready. Place finalization in finally so an assertion failure still produces the file.
Example 1: Record one order submission with explicit cleanup
import { readFile } from 'node:fs/promises';
import { expect, test } from '@playwright/test';
test('records the order submission boundary', async ({ context, page }, testInfo) => {
await page.goto('/cart');
await expect(page.getByRole('heading', { name: 'Your cart' })).toBeVisible();
const harPath = testInfo.outputPath('quarantine', 'order-submit.har');
await context.tracing.startHar(harPath, {
urlFilter: /\/api\/orders(?:\/|\?|$)/,
content: 'omit',
mode: 'full',
});
try {
const responsePromise = page.waitForResponse(response =>
response.url().includes('/api/orders') &&
response.request().method() === 'POST',
);
await page.getByRole('button', { name: 'Place order' }).click();
const response = await responsePromise;
expect(response.status()).toBe(201);
await expect(page.getByRole('status')).toHaveText('Order confirmed');
} finally {
await context.tracing.stopHar();
}
const har = JSON.parse(await readFile(harPath, 'utf8')) as {
log: { entries: Array<{ request: { method: string; url: string } }> };
};
const orderPosts = har.log.entries.filter(entry =>
entry.request.method === 'POST' &&
new URL(entry.request.url).pathname === '/api/orders',
);
expect(orderPosts).toHaveLength(1);
});The response wait is registered before the click, which avoids missing a fast request. The URL predicate and HTTP method distinguish the creation call from later order reads. The UI assertion remains essential: a valid response does not prove the page consumed it correctly.
stopHar() runs inside finally, so an assertion failure still finalizes the file before the original error propagates. The raw HAR remains in a restricted quarantine directory and is not attached to the report. On the passing path, the test parses the finalized HAR and proves that the intended POST exists exactly once. A later policy stage can scan the raw file and publish only an approved sanitized derivative. A production fixture should also prevent a finalization error from replacing the product failure; report cleanup failures separately while preserving the first assertion error and quarantining any partial artifact.
The example uses content: 'omit' because bodies are not required for its decision. That setting reduces exposure but does not remove every sensitive URL, header, cookie, or form field. Use mode: 'full' when timings, cookies, security information, or page-level HAR fields support diagnosis. Use mode: 'minimal' when the file exists mainly to replay matching requests. Minimal mode intentionally omits information not used for routing, so it is a poor choice when the missing fields are the evidence you need.
Capture Request, Response, and Protocol Evidence
A HAR is structured evidence, not a screenshot of DevTools. Correlate each target entry with the test action using method, normalized path, safe request identifier, status, and response content type. If the application emits several similar calls, add a test-owned correlation header or deterministic record identifier where the product permits it.
The Playwright network guide documents the request, response, and request-finished event sequence. A response event means status and headers arrived; request-finished means the body completed. Stop the HAR only after the milestone your decision requires. Stopping immediately after a click can omit a late response, while waiting for unrelated network idle can expand capture far beyond the target.
Do not confuse HAR recording with interception. startHar() observes activity; it does not mock a response, block a request, or make staging deterministic. If page.route(), a Service Worker, or WebSocket mocking changes traffic, record that fact as part of the test boundary. A HAR of fulfilled routes can be useful evidence of browser behavior, but it is not evidence that the real service returned those bodies.
Playwright 1.61 release notes state that HAR and trace recordings include WebSocket requests. Treat the connection request as transport evidence, then use WebSocket-specific frame listeners or routing for message assertions. The WebSocketRoute API controls mock and proxy behavior; a HAR alone should not be assumed to prove application-level message order, acknowledgements, or reconnect handling.
Record safe protocol facts rather than copying complete payloads into logs. Useful fields include method, status, content type, response duration when full mode is selected, and a synthetic correlation ID. For redirects, retain each hop and assert the intended final destination. A final 200 can hide an unexpected login redirect that returned HTML to an API call.
Design Positive, Negative, and Boundary Cases
One happy path proves that capture works, not that the evidence design distinguishes important failures. Build cases around the first observable boundary and state what the HAR should contain for each result.
- Record a successful target action and assert the expected status plus durable UI state.
- Trigger a documented validation failure and confirm the target request and error response are visible without unrelated endpoint families.
- Exercise a transport failure or aborted route and confirm the absence of a completed response is represented clearly.
- Run a case whose failure occurs before the request and prove the HAR has no target entry instead of fabricating a network diagnosis.
- Repeat under parallel execution and verify each test owns a distinct artifact.
- Inspect the retained file for forbidden values before allowing CI publication.
Use a concrete failure matrix during review:
| Scenario | First observable signal | Expected HAR evidence | Failure owner | Release result |
|---|---|---|---|---|
| Order accepted | Confirmation status appears | One POST, 201, expected content type | Product team | Pass |
| Validation rejected | Field error appears | One POST, documented 422 body shape | Product team | Pass for negative case |
| Request aborted | Error state appears | Request exists, no completed response | Network or test route owner | Block |
| Button stays disabled | No request occurs | No matching HAR entry | UI or fixture owner | Block |
| Wrong endpoint called | Unexpected path appears | Entry outside intended contract or missing target | Client owner | Block |
| Artifact contains a token | Product behavior may pass | Forbidden value found in retained file | Test platform and security | Block publication |
Do not regenerate or widen capture as the first response to a missing entry. Check whether the action happened, whether the URL filter matches the full URL, whether a Service Worker owns the request, and whether recording stopped too early. The focused route and Service Worker debugging guide helps separate invisible traffic from an incorrect URL assumption.
Compare the Available Playwright Network APIs
Choose the API from the decision, not from artifact familiarity. Several features use HAR files, but they control different lifecycle and trust boundaries.
| Need | Best starting API | Lifecycle | Main strength | Main limitation |
|---|---|---|---|---|
| Capture one action on an existing context | context.tracing.startHar() | Explicit start and stop or disposal | Tight temporal scope | One active recording per context |
| Capture the context from creation | recordHar context option | Context creation through close | Includes early navigation and setup | Wider secret and noise surface |
| Replay a coherent response set | routeFromHAR() | Route registration through unroute or teardown | Deterministic multi-request fixture | Does not verify the current backend |
| Change one response or inject an error | page.route() | Handler registration through removal | Precise dynamic control | Hand-authored behavior can drift |
| Observe live browser responses | Events and waits | Listener registration through cleanup | Current integration evidence | Environment and data variability |
| Inspect socket messages | WebSocket events or routes | Socket connection lifecycle | Frame-level control and observation | Requires protocol-aware assertions |
Use startHar() when authentication or setup should happen before evidence capture, or when a single context contains several phases that need separate files. Use context recordHar when early boot traffic is itself the subject. Use the HAR replay guide when the goal is deterministic UI behavior against reviewed fixtures.
Do not run startHar() and call the result a mock. Do not call routeFromHAR() and claim current integration coverage. A layered suite can have a scoped live recording for diagnosis, replay for rare UI states, direct API checks for contracts, and a small end-to-end path. Each layer should state which dependency is real.
Protect Secrets in HAR, Traces, and Logs
Capture minimization is the first security control. Start after login, stop as soon as the decision is made, and filter to a path family that does not include identity, payment, analytics, or unrelated tenant data. Use synthetic accounts with the least permission required. If mutual TLS is involved, follow a dedicated client certificate configuration rather than putting certificate material into test output.
content: 'omit' avoids persisted content text and attached resources, but it does not promise that every body-derived field is absent or that URLs, headers, cookies, and metadata are harmless. URL-encoded form parameters can remain in the HAR structure. mode: 'minimal' removes fields that HAR replay does not need, but it is a recording mode, not an arbitrary-value redaction engine. Review the actual artifact as structured data and fail closed when forbidden header names, query keys, form fields, hostnames, or known test secrets remain.
Prefer prevention over post-processing. Put test identifiers in paths and payloads, never real customer records. Keep credentials out of query strings. Disable optional integrations during capture. If a sanitizer rewrites a HAR intended for replay, rerun replay after sanitization because changing request bodies, URLs, or headers can alter matching.
Treat HAR, trace, screenshots, console output, and CI logs as one evidence set. Redacting a HAR while a trace contains the same bearer token does not reduce the incident. Apply the evidence review checklist before publication, restrict artifact readers, define expiry, and record access where policy requires it.
Never print a discovered secret in a scanner failure. Report the artifact, entry index, field name, and rule identifier. Quarantine the file from normal test reports, rotate exposed credentials through the owning system, and preserve only the minimum incident record permitted by policy.
Debug Missing or Misleading Network Evidence
Debug from lifecycle markers rather than file size. Record that start succeeded, the trigger ran, the target response milestone occurred, stop completed, and the finalized path exists. These markers identify whether the gap is setup, observation, product behavior, or artifact handling.
| Symptom | Likely cause | Check first | Corrective action |
|---|---|---|---|
startHar throws immediately | Another recording is active | Context fixture ownership | Stop the earlier recorder or use a separate context |
| HAR exists but has no target entry | Filter mismatch or trigger never sent | Full URL and action state | Fix the tested filter or the precondition |
| Entry has request but no useful response | Recording stopped too early or request failed | Response and request-finished events | Wait for the required milestone |
| Unrelated traffic dominates | Window or filter is broad | Start time and urlFilter | Move start later and narrow the pattern |
| Route events appear absent | Service Worker intercepted traffic | Context Service Worker policy | Test at the correct layer or block it intentionally |
| File cannot be opened | Finalization did not complete | finally and stop error | Await stopHar() before scanning or approval |
| Replay fails after sanitization | Matching fields were changed | URL, method, POST body, headers | Preserve required matching inputs or hand-author the route |
Glob patterns must match the full URL. A pattern such as */api/orders/* may not mean what its author expects across schemes and path separators. Log only a sanitized URL shape during a protected run, then replace guesswork with a tested glob or regular expression.
When routing is involved, inspect registration order and ownership. A context route, page route, HAR replay route, and Service Worker can each change what reaches the server. The Playwright route debugging article provides a deeper sequence for this class of missing event.
Do not fix partial evidence by waiting for generic network idle. Applications with polling, event streams, or background refresh may never become idle, and a long wait captures more sensitive traffic. Wait for the specific response, UI state, or protocol acknowledgement that closes the decision.
Add Deterministic CI Gates and Artifact Retention
A CI gate should validate behavior and evidence handling separately. Product assertions decide whether the scenario worked. Artifact checks decide whether the retained HAR is finalized, scoped, safe enough to publish, and attributable to one test attempt.
Example 2: Centralize scoped recording and always finalize it
import type { BrowserContext, TestInfo } from '@playwright/test';
export async function withOrderHar<T>(
context: BrowserContext,
testInfo: TestInfo,
run: () => Promise<T>,
): Promise<T> {
const path = testInfo.outputPath('quarantine', 'orders.har');
await context.tracing.startHar(path, {
urlFilter: /\/api\/orders(?:\/|\?|$)/,
content: 'omit',
mode: 'full',
});
try {
return await run();
} finally {
await context.tracing.stopHar();
}
}The helper owns one endpoint family and one raw artifact name within a test-owned quarantine directory. Keep assertions in the calling test so the business decision remains visible. A separate policy stage must parse, scan, and approve a sanitized derivative before any attachment or upload occurs. If finalization or scanning fails, preserve that evidence error without replacing the original product assertion unless evidence availability is itself a release requirement.
Use these deterministic gate conditions:
- Fail when the target behavior violates its UI or response contract.
- Fail when an expected target request is absent or duplicated beyond the documented rule.
- Fail artifact publication when finalization, parsing, scope validation, or secret scanning fails.
- Fail when two attempts resolve to the same output path.
- Retain failure evidence only after scanning; keep passing evidence only for sampled or explicitly diagnostic jobs.
- Emit an owner, test ID, retry index, Playwright version, and retention class with every retained artifact.
Keep the scanner deterministic. Validate JSON shape, allowed hostnames, allowed path prefixes, forbidden key names, and known synthetic-secret canaries. A canary placed in a test header can prove the scanner catches a controlled value, but never use a production credential for that purpose.
The Playwright evidence pipeline guide can coordinate retention across HAR, trace, video, and screenshots. Store a small manifest that links those files to the same attempt without copying request bodies into the manifest.
Frequently Asked Questions
What does context.tracing.startHar record?
It records HTTP Archive entries for network activity in one BrowserContext from the start call until stopHar or disposal. The urlFilter, content, and mode options narrow what is stored. The exact fields depend on those options, so inspect the resulting artifact before treating it as complete evidence.
How do I stop a scoped HAR when a test fails?
Put stopHar in a finally block after a successful startHar call, or use the returned Disposable with await using when the project's TypeScript runtime supports it. Either pattern finalizes the file during assertion failures. Do not rely on a later happy-path statement that a failed assertion can skip.
Can two HAR recordings run in the same BrowserContext?
No. Playwright permits only one active HAR recording per BrowserContext. Give each parallel test its own context and artifact path, or serialize intentionally shared-context work. Starting another recording before the first is stopped raises an error and usually indicates unclear lifecycle ownership in the test framework.
Which startHar options reduce sensitive capture?
Use a narrow urlFilter, choose content: 'omit' when persisted body text or attached resources are unnecessary, and consider mode: 'minimal' for HAR replay. These controls reduce material, but headers, URLs, body-derived form parameters, and retained metadata can still contain secrets. They do not replace controlled test data, inspection, access limits, or retention policy.
How is startHar different from recordHar?
recordHar is selected when a BrowserContext is created and normally ends when that context closes. startHar begins later on an existing context and can stop before teardown, which makes action-level capture practical. Both support related content, mode, and URL filtering choices, but their lifecycle boundaries are different.
Should CI retain every scoped HAR file?
Usually CI should retain sanitized HAR evidence for failures and selected diagnostic runs, not every passing case forever. Set size and age limits, restrict artifact readers, and record why an artifact was kept. A passing HAR can contain the same credentials or personal fields as a failed one.
Practice the Complete Evidence Decision
Start with one flaky network-dependent journey and mark the exact action that deserves transport evidence. Add a scoped HAR around that action, retain a real UI assertion, and run the failure matrix against a controlled validation error and an aborted request. Then prove CI finalizes, scans, and isolates the artifact even when the assertion fails.
Use the file to answer a decision, not to accumulate traffic. Compare its chronology with a trace, confirm the target request belongs to the expected attempt, and remove any capture field that has no diagnostic or replay purpose. When the case is stable, practice the same boundary under competitive time pressure in QABattle's automation battles, then review the result against the network evidence checklist before promoting it to a release gate.
// LIVE COURSE / THE TESTING ACADEMY
Playwright Automation Mastery
Go beyond Selenium. Master Playwright with JS/TS in 90 days.
From the instructor behind this guide.
Playwright jobs are growing 8x faster than Selenium. 90 days / 75+ live hrs / Tue-Thu-Sat 7 AM IST.
PRIMARY REFERENCES
Verify the details at the source
QABattle guides are practical explanations. Product behavior, standards, and APIs can change, so use these primary references for the canonical details.
- 01Official playwright.dev reference
playwright.dev
Primary documentation selected and verified for the claims in this guide.
- 02Official playwright.dev reference
playwright.dev
Primary documentation selected and verified for the claims in this guide.
- 03Official playwright.dev reference
playwright.dev
Primary documentation selected and verified for the claims in this guide.
- 04Official playwright.dev reference
playwright.dev
Primary documentation selected and verified for the claims in this guide.
FAQ / QUICK ANSWERS
Questions testers ask
What does context.tracing.startHar record?
It records HTTP Archive entries for network activity in one BrowserContext from the start call until stopHar or disposal. The urlFilter, content, and mode options narrow what is stored. The exact fields depend on those options, so inspect the resulting artifact before treating it as complete evidence.
How do I stop a scoped HAR when a test fails?
Put stopHar in a finally block after a successful startHar call, or use the returned Disposable with await using when the project's TypeScript runtime supports it. Either pattern finalizes the file during assertion failures. Do not rely on a later happy-path statement that a failed assertion can skip.
Can two HAR recordings run in the same BrowserContext?
No. Playwright permits only one active HAR recording per BrowserContext. Give each parallel test its own context and artifact path, or serialize intentionally shared-context work. Starting another recording before the first is stopped raises an error and usually indicates unclear lifecycle ownership in the test framework.
Which startHar options reduce sensitive capture?
Use a narrow urlFilter, choose content: 'omit' when persisted body text or attached resources are unnecessary, and consider mode: 'minimal' for HAR replay. These controls reduce material, but headers, URLs, body-derived form parameters, and retained metadata can still contain secrets. They do not replace controlled test data, inspection, access limits, or retention policy.
How is startHar different from recordHar?
recordHar is selected when a BrowserContext is created and normally ends when that context closes. startHar begins later on an existing context and can stop before teardown, which makes action-level capture practical. Both support related content, mode, and URL filtering choices, but their lifecycle boundaries are different.
Should CI retain every scoped HAR file?
Usually CI should retain sanitized HAR evidence for failures and selected diagnostic runs, not every passing case forever. Set size and age limits, restrict artifact readers, and record why an artifact was kept. A passing HAR can contain the same credentials or personal fields as a failed one.
RELATED GUIDES
Continue the learning route
GUIDE 01
Deterministic Network Tests with Playwright HAR Recording and Replay
Record, sanitize, and replay Playwright HAR fixtures for deterministic network tests, strict request matching, safer updates, and clear failures.
GUIDE 02
Playwright Evidence Pipeline for Traces, Video, and Screenshots
Playwright evidence pipeline architecture: practical design, implementation, debugging, CI, metrics, and interview guidance for QA, SDET, and automation engineers.
GUIDE 03
Debug Missing Playwright Route Events Behind Service Workers and Caches
Trace missing Playwright route events through page, service worker, and cache ownership, then choose deterministic interception or worker-aware assertions.
GUIDE 04
Playwright API Testing: Validate APIs Inside Your E2E Suite
Playwright API testing guide covering request contexts, setup flows, assertions, authentication, fixtures, UI strategy, and CI-ready checks.
GUIDE 05
Review AI-Generated Playwright Tests with an Evidence Checklist
Master review AI generated Playwright tests with practical examples, architecture decisions, failure analysis, CI guidance, metrics, and scenario-led interview answers.