<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.XX]</li>
<li>Operating System: [All, Windows 11, Ubuntu 20, macOS 13.2, etc.]</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>Config file</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'], },
    },
]
});"><pre class="notranslate"><span class="pl-c">// playwright.config.ts</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">defineConfig</span><span class="pl-kos">,</span> <span class="pl-s1">devices</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-k">export</span> <span class="pl-k">default</span> <span class="pl-en">defineConfig</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">projects</span>: <span class="pl-kos">[</span>
    <span class="pl-kos">{</span>
      <span class="pl-c1">name</span>: <span class="pl-s">'chromium'</span><span class="pl-kos">,</span>
      <span class="pl-c1">use</span>: <span class="pl-kos">{</span> ...<span class="pl-s1">devices</span><span class="pl-kos">[</span><span class="pl-s">'Desktop Chrome'</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-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">No custom config but the bug is also present if you set, there is a full test below which reproduces it so no need to modify config unless you want to also try to setting the headers in the config once reproduced.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="use: {
extraHTTPHeaders: {
      &quot;x-my-custom-header&quot;: &quot;test&quot;,
}
}"><pre class="notranslate"><code class="notranslate">use: {
extraHTTPHeaders: {
      "x-my-custom-header": "test",
}
}
</code></pre></div>
<p dir="auto"><strong>Test file (self-contained)</strong></p>
<p dir="auto">This test uses test-cors to make a cors request to playwright.dev site for <code class="notranslate">https://playwright.dev/img/playwright-logo.svg</code> which has  <code class="notranslate">access-control-allow-origin: *</code> set</p>
<p dir="auto">When setExtraHTTPHeaders is used test fails, when it is not, test passes.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import { test, expect } from &quot;@playwright/test&quot;;

test.describe(&quot;extraHTTPHeaders bug&quot;, () =&gt; {
  test.only(&quot;cors errors&quot;, async ({ page }) =&gt; {
    await page.setExtraHTTPHeaders({
      &quot;x-my-custom-header&quot;: &quot;test&quot;,
    });

    page.on(&quot;request&quot;, async (r) =&gt; {
      if (r.url().includes(&quot;playwright&quot;)) {
        const headers = await r.allHeaders();
        console.log(r.url(), &quot;request headers&quot;, Object.keys(headers).length);
      }
    });
    page.on(&quot;response&quot;, async (r) =&gt; {
      if (r.url().includes(&quot;playwright&quot;)) {
        const headers = await r.allHeaders();
        console.log(r.url(), &quot;response headers&quot;, Object.keys(headers).length);
      }
    });
    page.on(&quot;requestfailed&quot;, async (request) =&gt; {
      console.error(&quot;ERROR&quot;, request.url() + &quot; &quot; + request.failure().errorText);
    });
    await page.goto(
      &quot;https://www.test-cors.org/#?client_method=GET&amp;client_credentials=false&amp;server_url=https%3A%2F%2Fplaywright.dev&amp;server_enable=true&amp;server_status=200&amp;server_credentials=false&amp;server_tabs=remote&quot;
    );
    await page.click(&quot;#btnSendRequest&quot;);
    await expect(page.getByText(&quot;XHR status: 200&quot;)).toBeVisible();
  });
});
"><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-s1">expect</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-s1">test</span><span class="pl-kos">.</span><span class="pl-en">describe</span><span class="pl-kos">(</span><span class="pl-s">"extraHTTPHeaders bug"</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-s1">test</span><span class="pl-kos">.</span><span class="pl-en">only</span><span class="pl-kos">(</span><span class="pl-s">"cors errors"</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">{</span> page <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">setExtraHTTPHeaders</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
      <span class="pl-s">"x-my-custom-header"</span>: <span class="pl-s">"test"</span><span class="pl-kos">,</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

    <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">"request"</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-s1">r</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
      <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">r</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-en">includes</span><span class="pl-kos">(</span><span class="pl-s">"playwright"</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">headers</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">r</span><span class="pl-kos">.</span><span class="pl-en">allHeaders</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">r</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-s">"request headers"</span><span class="pl-kos">,</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">keys</span><span class="pl-kos">(</span><span class="pl-s1">headers</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">length</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-s1">page</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">"response"</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-s1">r</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
      <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">r</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-en">includes</span><span class="pl-kos">(</span><span class="pl-s">"playwright"</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">headers</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">r</span><span class="pl-kos">.</span><span class="pl-en">allHeaders</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">r</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-s">"response headers"</span><span class="pl-kos">,</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">keys</span><span class="pl-kos">(</span><span class="pl-s1">headers</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">length</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-s1">page</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">"requestfailed"</span><span class="pl-kos">,</span> <span class="pl-k">async</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-smi">console</span><span class="pl-kos">.</span><span class="pl-en">error</span><span class="pl-kos">(</span><span class="pl-s">"ERROR"</span><span class="pl-kos">,</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-c1">+</span> <span class="pl-s">" "</span> <span class="pl-c1">+</span> <span class="pl-s1">request</span><span class="pl-kos">.</span><span class="pl-en">failure</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">errorText</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">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">goto</span><span class="pl-kos">(</span>
      <span class="pl-s">"https://www.test-cors.org/#?client_method=GET&amp;client_credentials=false&amp;server_url=https%3A%2F%2Fplaywright.dev&amp;server_enable=true&amp;server_status=200&amp;server_credentials=false&amp;server_tabs=remote"</span>
    <span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">click</span><span class="pl-kos">(</span><span class="pl-s">"#btnSendRequest"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">getByText</span><span class="pl-kos">(</span><span class="pl-s">"XHR status: 200"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toBeVisible</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-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">You can comment out extraHTTPHeaders and this test will pass.</p>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>Use setExtraHTTPHeaders to set a custom header, in my case it was for setting a WAF headers</li>
<li>Go to a site which relies on CORS. See requests fail.</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<ul dir="auto">
<li>Extra header is added</li>
</ul>
<p dir="auto"><strong>Actual</strong></p>
<ul dir="auto">
<li>Extra header is added BUT it also removes other headers such as CORS headers.</li>
</ul>
<h2 dir="auto">Screenshots</h2>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/9056958/226428906-521ef9f2-d56a-4910-901b-5f799fc21766.png"><img src="https://user-images.githubusercontent.com/9056958/226428906-521ef9f2-d56a-4910-901b-5f799fc21766.png" alt="image" style="max-width: 100%;"></a><br>
Sorry about terrible quality video, github wouldnt let me do more than 10 MB<br>
<a href="https://user-images.githubusercontent.com/9056958/226429554-af9b4f5c-0c0b-4a78-a7e3-5cdb209612b2.mov" rel="nofollow">https://user-images.githubusercontent.com/9056958/226429554-af9b4f5c-0c0b-4a78-a7e3-5cdb209612b2.mov</a></p>
<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.36.1]</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"><a href="https://playwright.dev/docs/test-parameterize#create-tests-via-a-csv-file" rel="nofollow">https://playwright.dev/docs/test-parameterize#create-tests-via-a-csv-file</a></p>
<p dir="auto">Example with reading CSV file and generating tests out of it works perfectly fine</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import { test } from &quot;@playwright/test&quot;;
import * as fs from &quot;fs&quot;;
import { parse } from &quot;csv-parse/sync&quot;;

const records = parse(fs.readFileSync(&quot;input.csv&quot;), {
  columns: true,
  skip_empty_lines: true,
});

for (const record of records) {
  test(`foo: ${record.test_case}`, async () =&gt; {
    console.log(record.test_case);
  });
}"><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-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">fs</span> <span class="pl-k">from</span> <span class="pl-s">"fs"</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">parse</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"csv-parse/sync"</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-s1">records</span> <span class="pl-c1">=</span> <span class="pl-en">parse</span><span class="pl-kos">(</span><span class="pl-s1">fs</span><span class="pl-kos">.</span><span class="pl-en">readFileSync</span><span class="pl-kos">(</span><span class="pl-s">"input.csv"</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
  <span class="pl-c1">columns</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
  <span class="pl-c1">skip_empty_lines</span>: <span class="pl-c1">true</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">for</span> <span class="pl-kos">(</span><span class="pl-k">const</span> <span class="pl-s1">record</span> <span class="pl-k">of</span> <span class="pl-s1">records</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-en">test</span><span class="pl-kos">(</span><span class="pl-s">`foo: <span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">record</span><span class="pl-kos">.</span><span class="pl-c1">test_case</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">record</span><span class="pl-kos">.</span><span class="pl-c1">test_case</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></pre></div>
<p dir="auto">with a result</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Running 4 tests using 1 worker

  ✓  1 debug.spec.ts:12:7 › foo: value 1 (9ms)
value 1
  ✓  2 debug.spec.ts:12:7 › foo: value 2 (6ms)
value 2
  ✓  3 debug.spec.ts:12:7 › foo: value 3 (4ms)
value 3
  ✓  4 debug.spec.ts:12:7 › foo: value 4 (2ms)
value 4

  4 passed (184ms)"><pre class="notranslate"><code class="notranslate">Running 4 tests using 1 worker

  ✓  1 debug.spec.ts:12:7 › foo: value 1 (9ms)
value 1
  ✓  2 debug.spec.ts:12:7 › foo: value 2 (6ms)
value 2
  ✓  3 debug.spec.ts:12:7 › foo: value 3 (4ms)
value 3
  ✓  4 debug.spec.ts:12:7 › foo: value 4 (2ms)
value 4

  4 passed (184ms)
</code></pre></div>
<p dir="auto">But when I do the same with sync fetch</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import { test } from &quot;@playwright/test&quot;;
import _fetch from &quot;sync-fetch&quot;;

const json = _fetch(&quot;https://random-data-api.com/api/v2/users?size=2&amp;is_xml=true&quot;).json();
for (const data of json) {
  test(`bar: ${data.uid}`, async () =&gt; {
    console.log(data.uid);
  });
}"><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-k">import</span> <span class="pl-s1">_fetch</span> <span class="pl-k">from</span> <span class="pl-s">"sync-fetch"</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-s1">json</span> <span class="pl-c1">=</span> <span class="pl-en">_fetch</span><span class="pl-kos">(</span><span class="pl-s">"https://random-data-api.com/api/v2/users?size=2&amp;is_xml=true"</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">json</span><span class="pl-kos">(</span><span class="pl-kos">)</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">data</span> <span class="pl-k">of</span> <span class="pl-s1">json</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-en">test</span><span class="pl-kos">(</span><span class="pl-s">`bar: <span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">data</span><span class="pl-kos">.</span><span class="pl-c1">uid</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">.</span><span class="pl-c1">uid</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></pre></div>
<p dir="auto">it comes to</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="Running 2 tests using 1 worker


  ✘  1 debug.spec.ts:6:7 › bar: 440fe159-3301-4985-ad8e-a9026bcd49af (0ms)
  -  2 debug.spec.ts:6:7 › bar: 81921e9c-2ef9-4999-bf9d-d1ef0f83ee31


  1) debug.spec.ts:6:7 › bar: 440fe159-3301-4985-ad8e-a9026bcd49af ─────────────────────────────────

    Test(s) not found in the worker process. Make sure test titles do not change:
     &gt; debug.spec.ts &gt; bar: 440fe159-3301-4985-ad8e-a9026bcd49af
     &gt; debug.spec.ts &gt; bar: 81921e9c-2ef9-4999-bf9d-d1ef0f83ee31

  1 failed
    debug.spec.ts:6:7 › bar: 440fe159-3301-4985-ad8e-a9026bcd49af ──────────────────────────────────
  1 skipped"><pre class="notranslate">Running 2 tests using 1 worker


  ✘  1 debug.spec.ts:6:7 › bar: 440fe159-3301-4985-ad8e-a9026bcd49af (0ms)
  -  2 debug.spec.ts:6:7 › bar: 81921e9c-2ef9-4999-bf9d-d1ef0f83ee31


  1) debug.spec.ts:6:7 › bar: 440fe159-3301-4985-ad8e-a9026bcd49af ─────────────────────────────────

    Test(s) not found <span class="pl-k">in</span> the worker process. Make sure <span class="pl-c1">test</span> titles <span class="pl-k">do</span> not change:
     <span class="pl-k">&gt;</span> debug.spec.ts <span class="pl-k">&gt;</span> bar: 440fe159-3301-4985-ad8e-a9026bcd49af
     <span class="pl-k">&gt;</span> debug.spec.ts <span class="pl-k">&gt;</span> bar: 81921e9c-2ef9-4999-bf9d-d1ef0f83ee31

  1 failed
    debug.spec.ts:6:7 › bar: 440fe159-3301-4985-ad8e-a9026bcd49af ──────────────────────────────────
  1 skipped</pre></div>
<p dir="auto">What is wrong here? Why is the test title error thrown in this case and not in the previous one?</p>