<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: 1.36.1</li>
<li>Operating System: Ubuntu LTS</li>
<li>Browser: Chromium</li>
<li>Other info:</li>
</ul>
<h3 dir="auto">Source code</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I provided exact source code that allows reproducing the issue locally.</li>
</ul>




<p dir="auto"><strong>Test file (self-contained)</strong></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import { test } from '@playwright/test';

test('', async(fixtures, testInfo) =&gt; {
	fixtures;
});"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">test</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'@playwright/test'</span><span class="pl-kos">;</span>

<span class="pl-en">test</span><span class="pl-kos">(</span><span class="pl-s">''</span><span class="pl-kos">,</span> <span class="pl-k">async</span><span class="pl-kos">(</span><span class="pl-s1">fixtures</span><span class="pl-kos">,</span> <span class="pl-s1">testInfo</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
	<span class="pl-s1">fixtures</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">According to <a href="https://playwright.dev/docs/api/class-test#test-call" rel="nofollow">docs</a>, 1st argument of <code class="notranslate">testFunction</code> is <a href="https://playwright.dev/docs/api/class-fixtures" rel="nofollow">Fixtures</a>. However, when actually writing code, I am seeing <em>properties</em> of fixtures in addition to fixtures:</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://user-images.githubusercontent.com/3331946/256612940-90e247d8-257e-473e-96f4-89fc4167ca7d.png"><img src="https://user-images.githubusercontent.com/3331946/256612940-90e247d8-257e-473e-96f4-89fc4167ca7d.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto">This doesn't really make sense from the documentation point of since <a href="https://playwright.dev/docs/test-fixtures#built-in-fixtures" rel="nofollow">built-in fixtures</a> only list 6 fixtures. Further more, in <a href="https://playwright.dev/docs/auth#moderate-one-account-per-parallel-worker" rel="nofollow">Auth guide</a> we are shown that we can override <code class="notranslate">storageState</code> "fixture". However, <code class="notranslate">storageState</code> is really property of <a href="https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state" rel="nofollow">Context fixture</a> and not a standalone fixture.</p>
<p dir="auto">I guess for newcomers it's a bit confusing since fixtures and their properties are used interchangeably. For example, you can override the entire <code class="notranslate">Page</code> class or just <code class="notranslate">storageState</code>. Also, it is not really stated that <code class="notranslate">testFunction</code> splats fixtures where you can also access properties of the fixtures. It's really confusing when you expect 6 fixtures but instead presented with a list of dozens and not really sure (initially) where those come from.</p>
<p dir="auto">Similar to Fiddler's autoresponder feature we could use the <code class="notranslate">BrowserContext.route</code> function to create responses based on an exported har file from a previous playwright run</p>
<p dir="auto">maybe something like this:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import * as playwright from 'playwright';
import { Har, Entry, Response } from './har';

export interface HarAutoResponderOptions {
    unmatchedRequestHandling?: 'ignore' | 'continue';
}

type AutoResponderResponse = {
    body?: string;

    contentType?: string;

    headers?: { [key: string]: string; };

    status?: number;
}

export class HarAutoResponder {

    constructor(
        private readonly har: Har,
        private readonly options: HarAutoResponderOptions = {}) {
    }

    async applyTo(context: playwright.BrowserContext | playwright.Page) {
        context.route(_ =&gt; true, async (route, request) =&gt; {
            const matchedEntry = this.matchEntry(request);
            if (!matchedEntry) {
                if (this.options.unmatchedRequestHandling === 'continue') {
                    return await route.continue();
                } else {
                    return;
                }
            }

            const response = this.createResponse(matchedEntry.response);
            await route.fulfill(response);
        });
    }
    private createResponse(response: Response): AutoResponderResponse {
        const headers = response.headers.reduce((acc, header) =&gt; {
            acc[header.name] = header.value;
            return acc;
        }, {});
        const body = response.content.text;
        const status = response.status;
        const contentType = response.content.mimeType;
        return {
            headers,
            body,
            status,
            contentType
        }
    }

    private matchEntry(request: playwright.Request): Entry | undefined {
        for (const entry of this.har.log.entries) {
            if (entry.request.url === request.url()) {
                return entry;
            }
        }

        return undefined;
    }
}"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">playwright</span> <span class="pl-k">from</span> <span class="pl-s">'playwright'</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-smi">Har</span><span class="pl-kos">,</span> <span class="pl-smi">Entry</span><span class="pl-kos">,</span> <span class="pl-smi">Response</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'./har'</span><span class="pl-kos">;</span>

<span class="pl-k">export</span> <span class="pl-k">interface</span> <span class="pl-smi">HarAutoResponderOptions</span> <span class="pl-kos">{</span>
    <span class="pl-c1">unmatchedRequestHandling</span>?: <span class="pl-s">'ignore'</span> <span class="pl-c1">|</span> <span class="pl-s">'continue'</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">type</span> <span class="pl-smi">AutoResponderResponse</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
    <span class="pl-c1">body</span>?: <span class="pl-smi">string</span><span class="pl-kos">;</span>

    <span class="pl-c1">contentType</span>?: <span class="pl-smi">string</span><span class="pl-kos">;</span>

    <span class="pl-c1">headers</span>?: <span class="pl-kos">{</span> <span class="pl-kos">[</span><span class="pl-s1">key</span>: <span class="pl-smi">string</span><span class="pl-kos">]</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>

    <span class="pl-c1">status</span>?: <span class="pl-smi">number</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-smi">HarAutoResponder</span> <span class="pl-kos">{</span>

    <span class="pl-en">constructor</span><span class="pl-kos">(</span>
        <span class="pl-k">private</span> <span class="pl-k">readonly</span> <span class="pl-s1">har</span>: <span class="pl-smi">Har</span><span class="pl-kos">,</span>
        <span class="pl-k">private</span> <span class="pl-k">readonly</span> <span class="pl-s1">options</span>: <span class="pl-smi">HarAutoResponderOptions</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-kos">}</span>

    <span class="pl-k">async</span> <span class="pl-en">applyTo</span><span class="pl-kos">(</span><span class="pl-s1">context</span>: <span class="pl-s1">playwright</span><span class="pl-kos">.</span><span class="pl-smi">BrowserContext</span> <span class="pl-c1">|</span> <span class="pl-s1">playwright</span><span class="pl-kos">.</span><span class="pl-smi">Page</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-en">route</span><span class="pl-kos">(</span><span class="pl-s1">_</span> <span class="pl-c1">=&gt;</span> <span class="pl-c1">true</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-s1">route</span><span class="pl-kos">,</span> <span class="pl-s1">request</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
            <span class="pl-k">const</span> <span class="pl-s1">matchedEntry</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">matchEntry</span><span class="pl-kos">(</span><span class="pl-s1">request</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">matchedEntry</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">options</span><span class="pl-kos">.</span><span class="pl-c1">unmatchedRequestHandling</span> <span class="pl-c1">===</span> <span class="pl-s">'continue'</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                    <span class="pl-k">return</span> <span class="pl-k">await</span> <span class="pl-s1">route</span><span class="pl-kos">.</span><span class="pl-en">continue</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
                <span class="pl-kos">}</span> <span class="pl-k">else</span> <span class="pl-kos">{</span>
                    <span class="pl-k">return</span><span class="pl-kos">;</span>
                <span class="pl-kos">}</span>
            <span class="pl-kos">}</span>

            <span class="pl-k">const</span> <span class="pl-s1">response</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">createResponse</span><span class="pl-kos">(</span><span class="pl-s1">matchedEntry</span><span class="pl-kos">.</span><span class="pl-c1">response</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            <span class="pl-k">await</span> <span class="pl-s1">route</span><span class="pl-kos">.</span><span class="pl-en">fulfill</span><span class="pl-kos">(</span><span class="pl-s1">response</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
    <span class="pl-k">private</span> <span class="pl-en">createResponse</span><span class="pl-kos">(</span><span class="pl-s1">response</span>: <span class="pl-smi">Response</span><span class="pl-kos">)</span>: <span class="pl-smi">AutoResponderResponse</span> <span class="pl-kos">{</span>
        <span class="pl-k">const</span> <span class="pl-s1">headers</span> <span class="pl-c1">=</span> <span class="pl-s1">response</span><span class="pl-kos">.</span><span class="pl-c1">headers</span><span class="pl-kos">.</span><span class="pl-en">reduce</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">acc</span><span class="pl-kos">,</span> <span class="pl-s1">header</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
            <span class="pl-s1">acc</span><span class="pl-kos">[</span><span class="pl-s1">header</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">header</span><span class="pl-kos">.</span><span class="pl-c1">value</span><span class="pl-kos">;</span>
            <span class="pl-k">return</span> <span class="pl-s1">acc</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-k">const</span> <span class="pl-s1">body</span> <span class="pl-c1">=</span> <span class="pl-s1">response</span><span class="pl-kos">.</span><span class="pl-c1">content</span><span class="pl-kos">.</span><span class="pl-c1">text</span><span class="pl-kos">;</span>
        <span class="pl-k">const</span> <span class="pl-s1">status</span> <span class="pl-c1">=</span> <span class="pl-s1">response</span><span class="pl-kos">.</span><span class="pl-c1">status</span><span class="pl-kos">;</span>
        <span class="pl-k">const</span> <span class="pl-s1">contentType</span> <span class="pl-c1">=</span> <span class="pl-s1">response</span><span class="pl-kos">.</span><span class="pl-c1">content</span><span class="pl-kos">.</span><span class="pl-c1">mimeType</span><span class="pl-kos">;</span>
        <span class="pl-k">return</span> <span class="pl-kos">{</span>
            headers<span class="pl-kos">,</span>
            body<span class="pl-kos">,</span>
            status<span class="pl-kos">,</span>
            contentType
        <span class="pl-kos">}</span>
    <span class="pl-kos">}</span>

    <span class="pl-k">private</span> <span class="pl-en">matchEntry</span><span class="pl-kos">(</span><span class="pl-s1">request</span>: <span class="pl-s1">playwright</span><span class="pl-kos">.</span><span class="pl-smi">Request</span><span class="pl-kos">)</span>: <span class="pl-smi">Entry</span> <span class="pl-c1">|</span> <span class="pl-c1">undefined</span> <span class="pl-kos">{</span>
        <span class="pl-k">for</span> <span class="pl-kos">(</span><span class="pl-k">const</span> <span class="pl-s1">entry</span> <span class="pl-k">of</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">har</span><span class="pl-kos">.</span><span class="pl-c1">log</span><span class="pl-kos">.</span><span class="pl-c1">entries</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
            <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">entry</span><span class="pl-kos">.</span><span class="pl-c1">request</span><span class="pl-kos">.</span><span class="pl-c1">url</span> <span class="pl-c1">===</span> <span class="pl-s1">request</span><span class="pl-kos">.</span><span class="pl-en">url</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                <span class="pl-k">return</span> <span class="pl-s1">entry</span><span class="pl-kos">;</span>
            <span class="pl-kos">}</span>
        <span class="pl-kos">}</span>

        <span class="pl-k">return</span> <span class="pl-c1">undefined</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>