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.

By The Testing AcademyUpdated July 18, 202618 min read
All field guides
In this guide11 sections
  1. Define the Network Decision and Scope
  2. Check the Version and Prerequisites
  3. Build the Smallest Working Implementation
  4. Capture Request, Response, and Protocol Evidence
  5. Design Positive, Negative, and Boundary Cases
  6. Compare the Available Playwright Network APIs
  7. Protect Secrets in HAR, Traces, and Logs
  8. Debug Missing or Misleading Network Evidence
  9. Add Deterministic CI Gates and Artifact Retention
  10. Frequently Asked Questions
  11. What does context.tracing.startHar record?
  12. How do I stop a scoped HAR when a test fails?
  13. Can two HAR recordings run in the same BrowserContext?
  14. Which startHar options reduce sensitive capture?
  15. How is startHar different from recordHar?
  16. Should CI retain every scoped HAR file?
  17. 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: urlFilter admits only the endpoint family required by the scenario.
  • content: the content and mode options 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 to BrowserContext.tracing and returns a Disposable.
  • Only one HAR recording may be active in a BrowserContext.
  • stopHar() finalizes the path passed to startHar().
  • A .zip path stores response bodies as attached archive entries by default; other extensions embed them by default.
  • resourcesDir applies only with content: 'attach' and cannot be combined with a .zip HAR 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

TypeScript
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.

  1. Record a successful target action and assert the expected status plus durable UI state.
  2. Trigger a documented validation failure and confirm the target request and error response are visible without unrelated endpoint families.
  3. Exercise a transport failure or aborted route and confirm the absence of a completed response is represented clearly.
  4. Run a case whose failure occurs before the request and prove the HAR has no target entry instead of fabricating a network diagnosis.
  5. Repeat under parallel execution and verify each test owns a distinct artifact.
  6. Inspect the retained file for forbidden values before allowing CI publication.

Use a concrete failure matrix during review:

ScenarioFirst observable signalExpected HAR evidenceFailure ownerRelease result
Order acceptedConfirmation status appearsOne POST, 201, expected content typeProduct teamPass
Validation rejectedField error appearsOne POST, documented 422 body shapeProduct teamPass for negative case
Request abortedError state appearsRequest exists, no completed responseNetwork or test route ownerBlock
Button stays disabledNo request occursNo matching HAR entryUI or fixture ownerBlock
Wrong endpoint calledUnexpected path appearsEntry outside intended contract or missing targetClient ownerBlock
Artifact contains a tokenProduct behavior may passForbidden value found in retained fileTest platform and securityBlock 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.

NeedBest starting APILifecycleMain strengthMain limitation
Capture one action on an existing contextcontext.tracing.startHar()Explicit start and stop or disposalTight temporal scopeOne active recording per context
Capture the context from creationrecordHar context optionContext creation through closeIncludes early navigation and setupWider secret and noise surface
Replay a coherent response setrouteFromHAR()Route registration through unroute or teardownDeterministic multi-request fixtureDoes not verify the current backend
Change one response or inject an errorpage.route()Handler registration through removalPrecise dynamic controlHand-authored behavior can drift
Observe live browser responsesEvents and waitsListener registration through cleanupCurrent integration evidenceEnvironment and data variability
Inspect socket messagesWebSocket events or routesSocket connection lifecycleFrame-level control and observationRequires 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.

SymptomLikely causeCheck firstCorrective action
startHar throws immediatelyAnother recording is activeContext fixture ownershipStop the earlier recorder or use a separate context
HAR exists but has no target entryFilter mismatch or trigger never sentFull URL and action stateFix the tested filter or the precondition
Entry has request but no useful responseRecording stopped too early or request failedResponse and request-finished eventsWait for the required milestone
Unrelated traffic dominatesWindow or filter is broadStart time and urlFilterMove start later and narrow the pattern
Route events appear absentService Worker intercepted trafficContext Service Worker policyTest at the correct layer or block it intentionally
File cannot be openedFinalization did not completefinally and stop errorAwait stopHar() before scanning or approval
Replay fails after sanitizationMatching fields were changedURL, method, POST body, headersPreserve 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

TypeScript
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:

  1. Fail when the target behavior violates its UI or response contract.
  2. Fail when an expected target request is absent or duplicated beyond the documented rule.
  3. Fail artifact publication when finalization, parsing, scope validation, or secret scanning fails.
  4. Fail when two attempts resolve to the same output path.
  5. Retain failure evidence only after scanning; keep passing evidence only for sampled or explicitly diagnostic jobs.
  6. 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.

Code PROMODE / 10% offJoin the batch

The Testing Academy editorial desk

Practical QA guidance built around test evidence, production tradeoffs, and interview-ready explanations.

Published July 18, 2026 / Reviewed July 18, 2026

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.

  1. 01
    Official playwright.dev reference

    playwright.dev

    Primary documentation selected and verified for the claims in this guide.

  2. 02
    Official playwright.dev reference

    playwright.dev

    Primary documentation selected and verified for the claims in this guide.

  3. 03
    Official playwright.dev reference

    playwright.dev

    Primary documentation selected and verified for the claims in this guide.

  4. 04
    Official 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.