happy-dom icon indicating copy to clipboard operation
happy-dom copied to clipboard

TypeError: Expected signal to be an instanceof AbortSignal

Open frankandrobot opened this issue 2 years ago • 6 comments

Summary: happy-dom/jest-environment does not work with MSW and rtk-query

Environment:

  • @happy-dom/jest-environment: 3.1.1
  • @testing-library/react: 12.1.0
  • @reduxjs/toolkit: 1.7.1
  • msw: 0.38.1
  • react: 16.14.0
  • react-redux: 7.2.6
  • whatwg-fetch: 3.6.2

Sample repo: https://gitlab.com/robotandkid/the-sandbox/-/tree/mre/jest-happy-dom/happy-dom-test

Steps to repo:

  • Add an rtk-query endpoint and a component that consumes this endpoint
  • Add a working test using react-testing-library and MSW. (You will need to add a fetch polyfill to make tests run)
  • Switch to happy-dom/jest-environment
  • Result:
    An unhandled error occured processing a request for the endpoint "getPokemons".
    In the case of an unhandled error, no tags will be "provided" or "invalidated". TypeError: Expected signal to be an instanceof AbortSignal
        at new Request (/Users/uriel.avalos/Documents/the-sandbox/happy-dom-test/node_modules/node-fetch/lib/index.js:1244:10)
        at new Request (/Users/uriel.avalos/Documents/the-sandbox/happy-dom-test/node_modules/happy-dom/src/fetch/Request.ts:9:1)
        at /Users/uriel.avalos/Documents/the-sandbox/happy-dom-test/node_modules/@reduxjs/toolkit/src/query/fetchBaseQuery.ts:235:21
        at step (/Users/uriel.avalos/Documents/the-sandbox/happy-dom-test/node_modules/@reduxjs/toolkit/dist/query/rtk-query.cjs.development.js:23:23)
        at Object.next (/Users/uriel.avalos/Documents/the-sandbox/happy-dom-test/node_modules/@reduxjs/toolkit/dist/query/rtk-query.cjs.development.js:4:53)
        at fulfilled (/Users/uriel.avalos/Documents/the-sandbox/happy-dom-test/node_modules/@reduxjs/toolkit/dist/query/rtk-query.cjs.development.js:95:32)
        at processTicksAndRejections (internal/process/task_queues.js:95:5)

Analysis:

  • my guess is that the polyfill doesn't add itself to the happy-dom global.
  • Is there a way to manually do this?

frankandrobot avatar May 10 '22 15:05 frankandrobot

* It seems that a workaround is to upgrade node-fetch to 3.X. See https://github.com/node-fetch/node-fetch/issues/784 * however, that is a major refactor that would require changing happy-dom, rtk-query, plus whatever uses node-fetch under the hood * But happy-dom *does* work with vitest, so it may worth revisiting to see what vitest does that makes it work.

Update:

  • after getting some help on reactiflux, I realized that the issue is that jest/happy-dom needs an AbortSignal polyfill.
  • It is now working!
  • working branch: https://gitlab.com/robotandkid/the-sandbox/-/tree/mre/jest-happy-dom#4b0b56e847eeffd04f9aacd5a3b51d9c52bce421

frankandrobot avatar Jun 03 '22 18:06 frankandrobot

@frankandrobot I am not sure we are ready to close this one. Maybe we should add the polyfill to Happy DOM? 🙂

capricorn86 avatar Jun 16 '22 11:06 capricorn86

yea you're right @capricorn86 . Technically I just found a workaround but it would be nice if fetch "just works" . There are three things that we need to do:

  1. polyfill XMLHttpRequest
  2. polyfill AbortController
  3. this.global.document.defaultView.location.assign("http://localhost"); (allow relative URLs to work)

Note: in our code base, we actually ended up using the classes JSDOM provides :-) (The reason is because we originally thought we needed way more polyfills. ) Most likely the public polyfill packages should work 🤞

Also, I can actually totally help out on this one. :-)

frankandrobot avatar Jun 16 '22 22:06 frankandrobot

@frankandrobot What did you do to make this work for you? I'm getting the exact same error. I'm running on happy-dom@6 so it might've been working <6?

hornta avatar Jun 30 '22 23:06 hornta

In the above comments, there's a link to a test repo with absolute URLs.

If you want relative relative URLs, that's a different story. I tried repoing the fix in a test repo with just node-fetch and no dice.

In our repo, we use whatgfetch and then we import all of the above mentioned polyfills from jsdom! I'll see if i can get that working in the test repo 🙂

On Jun 30, 2022 6:23 PM, hornta @.***> wrote:

@frankandrobothttps://github.com/frankandrobot What did you do to make this work for you? I'm getting the exact same error. I'm running on @.*** so it might've been working <6?

— Reply to this email directly, view it on GitHubhttps://github.com/capricorn86/happy-dom/issues/470#issuecomment-1171766445, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAGAGMI25E2JKAAEKGVGCGTVRYT7FANCNFSM5VSCJX3Q. You are receiving this because you were mentioned.Message ID: @.***>

frankandrobot avatar Jun 30 '22 23:06 frankandrobot

It still fails for me even though we don't use relative urls and I think I set it up exactly as you've. I hope this will get fixed in this package since there are no other good working solution.

The error I'm getting now is:

An unhandled error occured processing a request for the endpoint "getDataLayerStatus".
In the case of an unhandled error, no tags will be "provided" or "invalidated". TypeError: Request is not a constructor

How it's mocked:

import _fetch from "node-fetch";
import {
  AbortController,
  abortableFetch,
} from "abortcontroller-polyfill/dist/cjs-ponyfill";

const { fetch, Request } = abortableFetch(_fetch);

global.fetch = fetch;
global.Request = Request;
// @ts-ignore
global.AbortController = AbortController;

hornta avatar Jul 01 '22 07:07 hornta

This has finally been fixed.

You can read about the release here: https://github.com/capricorn86/happy-dom/releases/tag/v9.0.0

capricorn86 avatar Apr 01 '23 16:04 capricorn86