mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
15.99k stars 522 forks source link

"TypeError: Failed to parse URL from [object Request]" with Vitest and Happy DOM #2191

Closed wonu closed 2 months ago

wonu commented 5 months ago

Prerequisites

Environment check

Node.js version

v18.20.3

Reproduction repository

https://stackblitz.com/edit/vitest-dev-vitest-d3shef

Reproduction steps

  1. Setup
    1. https://vitest.new
    2. install msw, happy-dom, jsdom
    3. remove unnecessary files
    4. add test files
  2. npm install && npm run test

Current behavior

With MSW enabled, passing a string as a parameter of fetch():

fetch('https://example.com')

TypeError: Failed to parse URL from [object Request] error occurs with happy-dom, but not with node or jsdom.

Expected behavior

fetch() should be able to receive a string regardless of MSW.

While it's a bit vague to call it an MSW issue, I would appreciate it if you could provide a workaround if there is one.

vtrofin commented 4 months ago

Hi there, i've been encountering the same error today with the same setup: vitest and happyDom. You might want to check this guide https://mswjs.io/docs/runbook#step-1-verify-setup

In my case I had a relative url, so I was missing the https:// part. After adding https the requests work fine.

kettanaito commented 2 months ago

Hi, @wonu. Thanks for reporting this.

This is an issue with happy-dom. It appears it doesn't support Request as an input to fetch(). You can reproduce this without MSW:

// @vitest-environment happy-dom

await fetch(new Request('https://example.com'))
TypeError: Failed to parse URL from [object Request]
    at node:internal/deps/undici/undici:12618:11 {
  [cause]: TypeError: Invalid URL
      at new NodeError (node:internal/errors:405:5)
      at new URL (node:internal/url:676:13)
      at new URL (/node_modules/.pnpm/happy-dom@15.7.4/node_modules/happy-dom/lib/url/URL.js:11:9)
      at new Request (node:internal/deps/undici/undici:6108:25)
      at fetch (node:internal/deps/undici/undici:10396:25)
      at Object.fetch (node:internal/deps/undici/undici:12617:10)
      at fetch (node:internal/process/pre_execution:281:25)

It passes the first argument of fetch directly to the URL constructor (using legacy URLs btw node:url), and since that argument is an object, not a URL, it comes down to this:

// node_modules/.pnpm/happy-dom@15.7.4/node_modules/happy-dom/lib/url/URL.js
new URL('[object Request')

The issue has been raised in the happy-dom repo already: https://github.com/capricorn86/happy-dom/issues/1433. I recommend you follow it there. Thanks.