<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.34.3]</li>
<li>Operating System: [macOS 13.2.1]</li>
<li>Browser: [Chromium, Firefox]</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">When I use newContext() and post() api to send multipart form which includes a file, I get the error <code class="notranslate">apiRequestContext.post: Unexpected buffer type of 'data.file'</code>.</p>
<p dir="auto">I have this fixture:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import {  test as base, APIRequestContext, request } from '@playwright/test';

export const test = base.extend({
  apiRequest: async ({apiBaseURL}, use) =&gt; {
    const apiRequestContext = await request.newContext({
      baseURL: process.env.REACT_APP_API_URL
    })
    await use(apiRequestContext);
    await apiRequestContext.dispose();
  },
  post: async ({ apiRequest }, use) =&gt; {
    await use(async ({ url, options, context }) =&gt; {
      if (options &amp;&amp; options.data) {
        options.data = snakecaseKeys(options.data, { exclude: options.exclude || [] });
      }

      if (options &amp;&amp; options.multipart) {
        options.multipart = snakecaseKeys(options.multipart, { exclude: options.exclude || [] });
      }

      const response = await apiRequest.post(url, options);

      return camelcaseKeys(await response.json(), { deep: true });
    });
  },
});"><pre class="notranslate"><code class="notranslate">import {  test as base, APIRequestContext, request } from '@playwright/test';

export const test = base.extend({
  apiRequest: async ({apiBaseURL}, use) =&gt; {
    const apiRequestContext = await request.newContext({
      baseURL: process.env.REACT_APP_API_URL
    })
    await use(apiRequestContext);
    await apiRequestContext.dispose();
  },
  post: async ({ apiRequest }, use) =&gt; {
    await use(async ({ url, options, context }) =&gt; {
      if (options &amp;&amp; options.data) {
        options.data = snakecaseKeys(options.data, { exclude: options.exclude || [] });
      }

      if (options &amp;&amp; options.multipart) {
        options.multipart = snakecaseKeys(options.multipart, { exclude: options.exclude || [] });
      }

      const response = await apiRequest.post(url, options);

      return camelcaseKeys(await response.json(), { deep: true });
    });
  },
});
</code></pre></div>
<p dir="auto">Also, second fixture which uses <code class="notranslate">post</code> that relies on <code class="notranslate">newContext()</code> (this is not working, getting error from the title):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import { faker } from '@faker-js/faker';
import { tests as base } from '@fixtures/util/util.fixture.ts';
import snakecaseKeys from 'snakecase-keys';


export const fileTest = base.extend({
  submitFile: async ({ post }, use) =&gt; {
    await use(async (data, token) =&gt; {
      const { orderId } = data;
      const file = {
        name: 'file.pdf',
        mimeType: 'application/pdf',
        buffer: Buffer.from('file content'),
      };

      const payload = snakecaseKeys({
        orderId
      });

      return post(
        {
          url: someUrl,
          options: {
            multipart: {
              ...payload,
              file,
            },
            headers: {
              'api-token': token,
            },
            exclude: ['mimeType']
          },
        }
      );
    });
  },
});"><pre class="notranslate"><code class="notranslate">import { faker } from '@faker-js/faker';
import { tests as base } from '@fixtures/util/util.fixture.ts';
import snakecaseKeys from 'snakecase-keys';


export const fileTest = base.extend({
  submitFile: async ({ post }, use) =&gt; {
    await use(async (data, token) =&gt; {
      const { orderId } = data;
      const file = {
        name: 'file.pdf',
        mimeType: 'application/pdf',
        buffer: Buffer.from('file content'),
      };

      const payload = snakecaseKeys({
        orderId
      });

      return post(
        {
          url: someUrl,
          options: {
            multipart: {
              ...payload,
              file,
            },
            headers: {
              'api-token': token,
            },
            exclude: ['mimeType']
          },
        }
      );
    });
  },
});
</code></pre></div>
<p dir="auto">The same fixture is working if I use <code class="notranslate">context</code> to call <code class="notranslate">post</code> (I would prefer to use <code class="notranslate">newContext()</code> since I don't have to repeat baseUrl every time):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import { faker } from '@faker-js/faker';
import { tests as base } from '@fixtures/util/util.fixture.ts';
import snakecaseKeys from 'snakecase-keys';


export const fileTest = base.extend({
  submitFile: async ({ context }, use) =&gt; {
    await use(async (data, token) =&gt; {
      const { orderId } = data;
      const file = {
        name: 'file.pdf',
        mimeType: 'application/pdf',
        buffer: Buffer.from('file content'),
      };

      const payload = snakecaseKeys({
        orderId
      });

      return context.request.post(
          url: process.env.REACT_APP_API_URL + someUrl,
          options: {
            multipart: {
              ...payload,
              file,
            },
            headers: {
              'api-token': token,
            },
          },
      );
    });
  },
});"><pre class="notranslate"><code class="notranslate">import { faker } from '@faker-js/faker';
import { tests as base } from '@fixtures/util/util.fixture.ts';
import snakecaseKeys from 'snakecase-keys';


export const fileTest = base.extend({
  submitFile: async ({ context }, use) =&gt; {
    await use(async (data, token) =&gt; {
      const { orderId } = data;
      const file = {
        name: 'file.pdf',
        mimeType: 'application/pdf',
        buffer: Buffer.from('file content'),
      };

      const payload = snakecaseKeys({
        orderId
      });

      return context.request.post(
          url: process.env.REACT_APP_API_URL + someUrl,
          options: {
            multipart: {
              ...payload,
              file,
            },
            headers: {
              'api-token': token,
            },
          },
      );
    });
  },
});
</code></pre></div>
<p dir="auto">So, it seems newContext() have some issues with multipart form and Buffer.</p>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">Expected multipart form data to be submitted when using <code class="notranslate">newContext()</code></p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">Getting the error  <code class="notranslate">Error: apiRequestContext.post: Unexpected buffer type of 'data.file'</code> on the line which points to <code class="notranslate">post</code> method in my first fixture.</p>
<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.XX]: 1.32.3</li>
<li>Operating System: [All, Windows 11, Ubuntu 20, macOS 13.2, etc.]: Windows 10</li>
<li>Browser: [All, Chromium, Firefox, WebKit]: 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"> I provided exact source code that allows reproducing the issue locally.</li>
</ul>




<p dir="auto"><strong>Link to the GitHub repository with the repro</strong></p>
<p dir="auto">[https://github.com/your_profile/playwright_issue_title]</p>
<p dir="auto">or</p>
<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-ct.config.ts
// @ts-check
import { defineConfig, devices } from '@playwright/experimental-ct-react';
import { resolve } from &quot;path&quot;;

/**
 * @see https://playwright.dev/docs/test-configuration
 */
module.exports = defineConfig({
  retries: 1,
  testDir: './tests/component',
  timeout: 30 * 1000,
  // fullyParallel: true,
  use: {
    trace: 'on-first-retry',
    ctPort: 3100,
    ctViteConfig: {
      resolve: {
        alias: {
          '@': resolve(__dirname, './src'),
          '@/*': resolve(__dirname, './src'),
        }
      }
    }
  },
  /* Configure projects for major browsers */
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] }
    },
  ]
});"><pre class="notranslate"><span class="pl-c">// playwright-ct.config.ts</span>
<span class="pl-c">// <span class="pl-k">@ts</span>-check</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/experimental-ct-react'</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">resolve</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"path"</span><span class="pl-kos">;</span>

<span class="pl-c">/**</span>
<span class="pl-c"> * <span class="pl-k">@see</span> https://playwright.dev/docs/test-configuration</span>
<span class="pl-c"> */</span>
<span class="pl-smi">module</span><span class="pl-kos">.</span><span class="pl-c1">exports</span> <span class="pl-c1">=</span> <span class="pl-en">defineConfig</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">retries</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span>
  <span class="pl-c1">testDir</span>: <span class="pl-s">'./tests/component'</span><span class="pl-kos">,</span>
  <span class="pl-c1">timeout</span>: <span class="pl-c1">30</span> <span class="pl-c1">*</span> <span class="pl-c1">1000</span><span class="pl-kos">,</span>
  <span class="pl-c">// fullyParallel: true,</span>
  <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">trace</span>: <span class="pl-s">'on-first-retry'</span><span class="pl-kos">,</span>
    <span class="pl-c1">ctPort</span>: <span class="pl-c1">3100</span><span class="pl-kos">,</span>
    <span class="pl-c1">ctViteConfig</span>: <span class="pl-kos">{</span>
      <span class="pl-c1">resolve</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">alias</span>: <span class="pl-kos">{</span>
          <span class="pl-s">'@'</span>: <span class="pl-en">resolve</span><span class="pl-kos">(</span><span class="pl-s1">__dirname</span><span class="pl-kos">,</span> <span class="pl-s">'./src'</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
          <span class="pl-s">'@/*'</span>: <span class="pl-en">resolve</span><span class="pl-kos">(</span><span class="pl-s1">__dirname</span><span class="pl-kos">,</span> <span class="pl-s">'./src'</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-c">/* Configure projects for major browsers */</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></pre></div>
<p dir="auto"><strong>Test file (self-contained)</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="it('should check the box using setChecked', async ({ page }) =&gt; {
  await page.setContent(`&lt;input id='checkbox' type='checkbox'&gt;&lt;/input&gt;`);
  await page.getByRole('checkbox').check();
  await expect(page.getByRole('checkbox')).toBeChecked();
});"><pre class="notranslate"><span class="pl-en">it</span><span class="pl-kos">(</span><span class="pl-s">'should check the box using setChecked'</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">setContent</span><span class="pl-kos">(</span><span class="pl-s">`&lt;input id='checkbox' type='checkbox'&gt;&lt;/input&gt;`</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">getByRole</span><span class="pl-kos">(</span><span class="pl-s">'checkbox'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">check</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">getByRole</span><span class="pl-kos">(</span><span class="pl-s">'checkbox'</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toBeChecked</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"><strong>Steps</strong></p>
<ul dir="auto">
<li>execute command <code class="notranslate">cross-env PW_EXPERIMENTAL_TS_ESM=1 playwright test --ui -c playwright-ct.config.ts</code></li>
<li>run specific one test on left side from UI</li>
<li>wait for complete test</li>
<li>rerun this test again</li>
<li>i am getting error below</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">Should be able to rerun same test in UI.</p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">Since I opened GUI, first test always gets working, but every time after first attempt I am being blocked by below error:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="vite v4.2.2 building for production...
transforming (1) playwright\index.htmlError when using sourcemap for reporting an error: Can't resolve original location of error.
✓ 3 modules transformed.
✓ built in 67ms
Identifier '__pwReact' has already been declared (Note that you need plugins to import files that are not JavaScript)
file: C:/dev/tester/frontend/playwright/index.ts:139:12
137: // This file is injected into the registry as text, no dependencies are allowed.
138: 
139: import * as __pwReact from 'react';
                 ^
140: import { createRoot as __pwCreateRoot } from 'react-dom/client';
RollupError: Identifier '__pwReact' has already been declared (Note that you need plugins to import files that are not JavaScript)

    at error (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:2125:30)
    at Module.error (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:13334:16)
    at Module.tryParse (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:14011:25)
    at Module.setSource (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:13621:39)
    at ModuleLoader.addModuleSource (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:23586:20)
RollupError: Identifier '__pwReact' has already been declared (Note that you need plugins to import files that are not JavaScript)
    at error (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:2125:30)
    at Module.error (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:13334:16)
    at Module.tryParse (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:14011:25)
    at Module.setSource (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:13621:39)
    at ModuleLoader.addModuleSource (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:23586:20)"><pre class="notranslate"><code class="notranslate">vite v4.2.2 building for production...
transforming (1) playwright\index.htmlError when using sourcemap for reporting an error: Can't resolve original location of error.
✓ 3 modules transformed.
✓ built in 67ms
Identifier '__pwReact' has already been declared (Note that you need plugins to import files that are not JavaScript)
file: C:/dev/tester/frontend/playwright/index.ts:139:12
137: // This file is injected into the registry as text, no dependencies are allowed.
138: 
139: import * as __pwReact from 'react';
                 ^
140: import { createRoot as __pwCreateRoot } from 'react-dom/client';
RollupError: Identifier '__pwReact' has already been declared (Note that you need plugins to import files that are not JavaScript)

    at error (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:2125:30)
    at Module.error (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:13334:16)
    at Module.tryParse (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:14011:25)
    at Module.setSource (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:13621:39)
    at ModuleLoader.addModuleSource (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:23586:20)
RollupError: Identifier '__pwReact' has already been declared (Note that you need plugins to import files that are not JavaScript)
    at error (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:2125:30)
    at Module.error (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:13334:16)
    at Module.tryParse (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:14011:25)
    at Module.setSource (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:13621:39)
    at ModuleLoader.addModuleSource (C:\dev\tester\frontend\node_modules\vite\node_modules\rollup\dist\es\shared\node-entry.js:23586:20)
</code></pre></div>