Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vitest 1.0.2 with happy-dom and msw + axios results in TypeError: #1180

Closed
marioleed opened this issue Dec 11, 2023 · 2 comments · Fixed by #1194
Closed

Vitest 1.0.2 with happy-dom and msw + axios results in TypeError: #1180

marioleed opened this issue Dec 11, 2023 · 2 comments · Fixed by #1194
Labels
bug Something isn't working

Comments

@marioleed
Copy link

Describe the bug

Vitest 1.0.2 made a fix for happy-dom where it respects happy-dom's Request and Response. That unfortunately broke my tests: vitest-dev/vitest#4730.

Here's the error message:

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Rejection ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
TypeError: response.body.getReader is not a function
❯ XMLHttpRequestController.respondWith node_modules/.pnpm/https://github.com/mswjs+interceptors@0.25.13/node_modules/https://github.com/mswjs/interceptors/lib/node/chunk-V3QPQ45S.mjs:452:36
❯ xhrRequestController.onRequest node_modules/.pnpm/@mswjs+interceptors@0.25.13/node_modules/@mswjs/interceptors/lib/node/chunk-V3QPQ45S.mjs:727:39

This error originated in "tests/tests.test.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
The latest test that might've caused the error is "request is ok". It might mean one of the following:

The error was thrown, while Vitest was running this test.
This was the last recorded test before the error was thrown, if error originated after test finished its execution.
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

Maybe I'm using it wrong, but I'm not sure. I'd rather stick to happy-dom than use jsdom, but if this can't be fixed I guess I'll have to.

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://stackblitz.com/edit/vitejs-vite-wlzbz8?view=editor
  2. Run the tests with vitest run

Expected behavior
I expect not to get a TypeError and the call to the url via msw to be executed.

Additional context
The project is using latest version for msw, axios, happy-dom and vitest.

@marioleed marioleed added the bug Something isn't working label Dec 11, 2023
@diego-toro
Copy link
Contributor

Found this same issue. Been trying to have a workaround but no success so far. Got to downgrade vitest "0.34.6" in the meantime

@diego-toro
Copy link
Contributor

diego-toro commented Jan 8, 2024

I've been checking this issue, and it seems MSW relies on browser API https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream completely.

They may need to validate the response for the node version too. Something like this:

this.logger.info("mocked response has body, streaming...");
const responseBody = response.body;

const readNextResponseBodyChunk = async (reader) => {
  const { value, done } = await reader.read();
  if (done) {
    this.logger.info("response body stream done!");
    finalizeResponse();
    return;
  }
  if (value) {
    this.logger.info("read response body chunk:", value);
    this.responseBuffer = concatArrayBuffer(this.responseBuffer, value);
    this.trigger("progress", {
      loaded: this.responseBuffer.byteLength,
      total: totalResponseBodyLength
    });
  }
  readNextResponseBodyChunk(reader);
};

const readStreamReadable = async () => {
  for await (const value of responseBody) {
    this.logger.info("read response body chunk:", value);
    this.responseBuffer = concatArrayBuffer(this.responseBuffer, value);
    this.trigger("progress", {
      loaded: this.responseBuffer.byteLength,
      total: totalResponseBodyLength
    });
  }

  this.logger.info("response body stream done!");
  finalizeResponse();
}

// HERE! 👇 
if (responseBody instanceof ReadableStream) {
  const reader = response.body.getReader();
  readNextResponseBodyChunk(reader);
} else if (responseBody instanceof Stream.Readable) {
  readStreamReadable();
}

This is the file src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts:335 of @mswjs/interceptors package.

But TBH I think happy-dom should be closer to browser API rather than node. It seems some parts are based on node-fetch implementations.

I am trying to migrate the fetch to use ReadableStream. Still missing the tests. they are a lot 🤣 . Here is the link if someone wants to help. https://github.com/diego-toro/happy-dom-readablestream/tree/task/1180-migrate-to-readablestream

diego-toro added a commit to diego-toro/happy-dom-readablestream that referenced this issue Jan 9, 2024
capricorn86 added a commit to diego-toro/happy-dom-readablestream that referenced this issue Feb 23, 2024
…uest.body used by window.fetch(). The previous implementation used the Node.js Stream.Readable class, which is not fully spec compliant.
capricorn86 added a commit to diego-toro/happy-dom-readablestream that referenced this issue Feb 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants