mswjs / msw

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

request.formData() fails with vitest and file #2166

Closed haakonph closed 3 months ago

haakonph commented 6 months ago

Prerequisites

Environment check

Node.js version

v22.2.0

Reproduction repository

https://github.com/haakonph/msw-examples

Reproduction steps

alter the example to use a request with a file: (as in the example repo)

 const formData = new FormData();
  const file = new File(['some file'], 'filnavn.xml');
  formData.append('fil', file)

in the with-vitest exmple, run npm i and run the 'fetches the user info' test

you need to add a file to the request to get it to fail if you run with npm v20.0.0 it works with jsdom but not without.

it works with jest-jsdom.

Current behavior

with vitest-jsdom it time out waiting to get the request with vitest without vitestjsdom you get a 500 response.

Expected behavior

get a 200 response as you get with examples/with-jest-jsdom example

kettanaito commented 6 months ago

Hi, @haakonph. Thanks for reporting this.

I will take a look once I have a minute but generally we have a stance that Jest issues are not addressed. If I am able to reproduce this in raw Node.js or with Vitest, then I will consider this a bug. If this is only reproducible for Jest/JSDOM, I will close this as wont-fix.

greysteil commented 6 months ago

@haakonph I ran into this today, too, but was able to solve it with the polyfill instructions. In case it helps, my jest.config.js looks like the below and everything is working as expected.

const nextJest = require('next/jest') // eslint-disable-line @typescript-eslint/no-var-requires

const createJestConfig = nextJest({ dir: './' })

const { TextDecoder, TextEncoder } = require('node:util')
const { fetch, Headers, FormData, Request, Response } = require('undici')

const customJestConfig = {
  // Indicates which files should be considered as tests
  testRegex: "(/src/__tests__/.*|(\\.|/)(test|spec))\\.(ts|tsx)?$",
  testPathIgnorePatterns: ["/src/__tests__/.*/mocks/", "/src/__tests__/config/*"],

  testEnvironment: "jest-environment-jsdom",
  testEnvironmentOptions: {
    // Opt-out from JSDOM using browser-style resolution for dependencies as JSDOM is not a browser
    customExportConditions: [""],
  },

  setupFilesAfterEnv: ["./src/__tests__/config/setupTests.ts"],
  globals: {
    fetch,
    Request,
    Response,
    Headers,
    FormData,
    ReadableStream,
    TextEncoder,
    TextDecoder,
  },
};

module.exports = createJestConfig(customJestConfig);
haakonph commented 5 months ago

@kettanaito Hi, sorry i was a bit to fast with my copy pasting.

The issue is with vitest and when the body contains a file. I oppdated the issue.

I am not able to reproduce it without vitest. So feel free to close the issue.

topaxi commented 5 months ago

We are also running into this issue with msw, we are also running in an environment that loads jsdom, so this might be an interplay between msw, jsdom and a newer undici version?

Any Node.js version after v20.12.2 breaks our tests that rely on request.formData().

As a workaround we are currently pinned to Node.js v20.12.2.

jukkahyv commented 5 months ago

Same problem here. Node v20.14.0, msw 2.3.1, vitest. Downgraded node to 20.12.2, and now it works again.

marcoscalia commented 4 months ago

I had the same problem Node v20.15.1, msw 2.3.2, vitest 2.0.4. Downgraded node to 20.12.2 for now to solve

adrianlemess commented 3 months ago

I also had the same issue, the request.formData() it was just ignored and didn't throw any error.

I downgrade to 20.12.2 and then it worked.

kettanaito commented 3 months ago

If the issue only happens on particular version of Node.js

Please downgrade to the Node.js version where such issue doesn't happen (v20.12.2 based on the comments). Please raise this issue with Undici (the fetch and FormData implementation in Node.js).

If the issue only happens in JSDOM

Then it's a bug in JSDOM. Either migrate to HappyDOM or run your tests in the actual browser, where FormData handling doesn't have any issues.

jukkahyv commented 2 months ago

To anyone interested: I still had issues with recent node versions (tried both v20.17.0 (LTS) and 22.9.0 (current)).

Here's how I fixed it for me: I had to add and import blob-polyfill in my test setup. After that it works!

I realized the root cause is lack of Blob support in jsdom, but it was really hard to get any error message. It was also confusing that this used to work with older Node versions. I guess Node/Undici changed something. I noticed this after a lengthy debugging session when I tried to read the raw request body, parsing the Blob manually. It's only then that I got the error "blob.text is not a function", which led me to this blob-polyfill library. Perhaps migrating to Happy DOM is also an option. I didn't try it.