<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: v1.31.2</li>
<li>Operating System: macOS 13.2.1</li>
<li>Browser: All</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>Link to the GitHub repository with the repro</strong></p>
<p dir="auto"><a href="https://github.com/chris13524/sentry-nextjs-playwright-broken">https://github.com/chris13524/sentry-nextjs-playwright-broken</a></p>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>run <code class="notranslate">npm run test-ct</code> to reproduce error</li>
<li>edit <code class="notranslate">pages/index.tsx</code> and comment out the call to <code class="notranslate">addBreadcrumb()</code></li>
<li>run <code class="notranslate">npm run test-ct</code> to reproduce no error</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">I should be able to use the <a href="https://www.npmjs.com/package/@sentry/nextjs" rel="nofollow">@sentry/nextjs</a> library in my component and in the helper files that my component calls.</p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">Test times out while mounting the component.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="chris13524@host sentry-nextjs-playwright-broken % npm run test-ct

&gt; sentry-nextjs-playwright-broken@0.1.0 test-ct
&gt; playwright test -c playwright-ct.config.ts


Running 3 tests using 3 workers
  1) [webkit] › pages/index.spec.tsx:6:5 › should work ─────────────────────────────────────────────

    Test timeout of 10000ms exceeded.

    Target closed

       5 |
       6 | test('should work', async ({ mount }) =&gt; {
    &gt;  7 |   const component = await mount(&lt;Home /&gt;);
         |                           ^
       8 |   await expect(component).toContainText('Get started');
       9 | });
      10 |

        at /Users/chris13524/git/github.com/chris13524/sentry-nextjs-playwright-broken/pages/index.spec.tsx:7:27

  2) [chromium] › pages/index.spec.tsx:6:5 › should work ───────────────────────────────────────────

    Test timeout of 10000ms exceeded.

    Target closed

       5 |
       6 | test('should work', async ({ mount }) =&gt; {
    &gt;  7 |   const component = await mount(&lt;Home /&gt;);
         |                           ^
       8 |   await expect(component).toContainText('Get started');
       9 | });
      10 |

        at /Users/chris13524/git/github.com/chris13524/sentry-nextjs-playwright-broken/pages/index.spec.tsx:7:27

  3) [firefox] › pages/index.spec.tsx:6:5 › should work ────────────────────────────────────────────

    Test timeout of 10000ms exceeded.

    Target closed

       5 |
       6 | test('should work', async ({ mount }) =&gt; {
    &gt;  7 |   const component = await mount(&lt;Home /&gt;);
         |                           ^
       8 |   await expect(component).toContainText('Get started');
       9 | });
      10 |

        at /Users/chris13524/git/github.com/chris13524/sentry-nextjs-playwright-broken/pages/index.spec.tsx:7:27

  3 failed
    [chromium] › pages/index.spec.tsx:6:5 › should work ────────────────────────────────────────────
    [firefox] › pages/index.spec.tsx:6:5 › should work ─────────────────────────────────────────────
    [webkit] › pages/index.spec.tsx:6:5 › should work ──────────────────────────────────────────────

  Serving HTML report at http://localhost:9323. Press Ctrl+C to quit.
"><pre class="notranslate"><code class="notranslate">chris13524@host sentry-nextjs-playwright-broken % npm run test-ct

&gt; sentry-nextjs-playwright-broken@0.1.0 test-ct
&gt; playwright test -c playwright-ct.config.ts


Running 3 tests using 3 workers
  1) [webkit] › pages/index.spec.tsx:6:5 › should work ─────────────────────────────────────────────

    Test timeout of 10000ms exceeded.

    Target closed

       5 |
       6 | test('should work', async ({ mount }) =&gt; {
    &gt;  7 |   const component = await mount(&lt;Home /&gt;);
         |                           ^
       8 |   await expect(component).toContainText('Get started');
       9 | });
      10 |

        at /Users/chris13524/git/github.com/chris13524/sentry-nextjs-playwright-broken/pages/index.spec.tsx:7:27

  2) [chromium] › pages/index.spec.tsx:6:5 › should work ───────────────────────────────────────────

    Test timeout of 10000ms exceeded.

    Target closed

       5 |
       6 | test('should work', async ({ mount }) =&gt; {
    &gt;  7 |   const component = await mount(&lt;Home /&gt;);
         |                           ^
       8 |   await expect(component).toContainText('Get started');
       9 | });
      10 |

        at /Users/chris13524/git/github.com/chris13524/sentry-nextjs-playwright-broken/pages/index.spec.tsx:7:27

  3) [firefox] › pages/index.spec.tsx:6:5 › should work ────────────────────────────────────────────

    Test timeout of 10000ms exceeded.

    Target closed

       5 |
       6 | test('should work', async ({ mount }) =&gt; {
    &gt;  7 |   const component = await mount(&lt;Home /&gt;);
         |                           ^
       8 |   await expect(component).toContainText('Get started');
       9 | });
      10 |

        at /Users/chris13524/git/github.com/chris13524/sentry-nextjs-playwright-broken/pages/index.spec.tsx:7:27

  3 failed
    [chromium] › pages/index.spec.tsx:6:5 › should work ────────────────────────────────────────────
    [firefox] › pages/index.spec.tsx:6:5 › should work ─────────────────────────────────────────────
    [webkit] › pages/index.spec.tsx:6:5 › should work ──────────────────────────────────────────────

  Serving HTML report at http://localhost:9323. Press Ctrl+C to quit.

</code></pre></div>
<h2 dir="auto">Context</h2>
<p dir="auto">Playwright Version: 1.33.0<br>
Operating System: OS X<br>
Node.js version: 16.20.0<br>
MSW version: 1.2.1</p>
<p dir="auto">We are currently migrating the E2E test suite of a <strong>React Native app</strong> from Cypress to Playwright. Both Playwright and msw work perfectly for us. We use MSW also in combination with our Jest test suite, as well as for local manual testing. We would like to intercept and mock network requests that are performed by browsers during Playwright tests. In Cypress we managed to achieve it like this:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    cy.window().then((window) =&gt; {
      const {worker, rest} = window.msw;
      worker.use(
        rest.post(`*${api.customName}`, (_, res, ctx) =&gt; {
          const response = cloneDeep(responses.customName);
          response.days = 5;

          return res(ctx.status(200), ctx.json(response));
        }),
      );
    });"><pre class="notranslate">    <span class="pl-s1">cy</span><span class="pl-kos">.</span><span class="pl-en">window</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">window</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-kos">{</span>worker<span class="pl-kos">,</span> rest<span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-smi">window</span><span class="pl-kos">.</span><span class="pl-c1">msw</span><span class="pl-kos">;</span>
      <span class="pl-s1">worker</span><span class="pl-kos">.</span><span class="pl-en">use</span><span class="pl-kos">(</span>
        <span class="pl-s1">rest</span><span class="pl-kos">.</span><span class="pl-en">post</span><span class="pl-kos">(</span><span class="pl-s">`*<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">api</span><span class="pl-kos">.</span><span class="pl-c1">customName</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-s1">_</span><span class="pl-kos">,</span> <span class="pl-s1">res</span><span class="pl-kos">,</span> <span class="pl-s1">ctx</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">response</span> <span class="pl-c1">=</span> <span class="pl-en">cloneDeep</span><span class="pl-kos">(</span><span class="pl-s1">responses</span><span class="pl-kos">.</span><span class="pl-c1">customName</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
          <span class="pl-s1">response</span><span class="pl-kos">.</span><span class="pl-c1">days</span> <span class="pl-c1">=</span> <span class="pl-c1">5</span><span class="pl-kos">;</span>

          <span class="pl-k">return</span> <span class="pl-en">res</span><span class="pl-kos">(</span><span class="pl-s1">ctx</span><span class="pl-kos">.</span><span class="pl-en">status</span><span class="pl-kos">(</span><span class="pl-c1">200</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s1">ctx</span><span class="pl-kos">.</span><span class="pl-en">json</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-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<h2 dir="auto">Problem</h2>
<p dir="auto">We tried to achieve the same behavior in Playwright tests, but have not been successful yet.</p>
<h2 dir="auto">What we tried</h2>
<ol dir="auto">
<li>Use build-in modification of API responses (then realized that this build-in feature might not work for msw)</li>
</ol>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    await page.route(`*/api/${api.statistics}`, async (route) =&gt; {
      const response = await route.fetch();
      const json = await response.json();
      json.days = 5;

      await route.fulfill({response, json});
    });"><pre class="notranslate">    <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">route</span><span class="pl-kos">(</span><span class="pl-s">`*/api/<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">api</span><span class="pl-kos">.</span><span class="pl-c1">statistics</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-s1">route</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">response</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">route</span><span class="pl-kos">.</span><span class="pl-en">fetch</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">json</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">response</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-s1">json</span><span class="pl-kos">.</span><span class="pl-c1">days</span> <span class="pl-c1">=</span> <span class="pl-c1">5</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-kos">{</span>response<span class="pl-kos">,</span> json<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>
<ol start="2" dir="auto">
<li>Add option <code class="notranslate">serviceWorkers: allow</code> in config</li>
<li>Try using <a href="https://github.com/microsoft/playwright/issues/15684" data-hovercard-type="issue" data-hovercard-url="/microsoft/playwright/issues/15684/hovercard">Experimental Service Worker Network Events</a> (unsuccessful)</li>
<li>Try <a href="https://www.npmjs.com/package/playwright-msw" rel="nofollow">msw-playwright package</a>, but the requests do not seem to get intercepted. The browser returns the original response that is defined in our msw environment (<code class="notranslate">handlers.ts</code>).</li>
</ol>
<p dir="auto">What could be the cause of the problem? What's the best way to intercept API requests in Playwright tests using MSW? Thanks in advance for your help!</p>