I am getting a TypeError when running my tests:
TypeError: Cannot read properties of null (reading '_location')
at Window.get location [as location] (my_files\characterbuilder\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\browser\Window.js:375:79)
at FetchInterceptor.<anonymous> (my_files\characterbuilder\node_modules\@mswjs\interceptors\src\interceptors\fetch\index.ts:52:9)
at step (my_files\characterbuilder\node_modules\@mswjs\interceptors\lib\interceptors\fetch\index.js:59:23)
at Object.next (my_files\characterbuilder\node_modules\@mswjs\interceptors\lib\interceptors\fetch\index.js:40:53)
at fulfilled (my_files\characterbuilder\node_modules\@mswjs\interceptors\lib\interceptors\fetch\index.js:31:58)
at runNextTicks (node:internal/process/task_queues:60:5)
at processImmediate (node:internal/timers:447:9)
The relevant get location in the Window.js:
get location() {
return idlUtils.wrapperForImpl(idlUtils.implForWrapper(window._document)._location);
}
the relevant code in the mentioned index.js:
protected checkEnvironment() {
return (
typeof globalThis !== 'undefined' &&
typeof globalThis.fetch !== 'undefined'
)
}
protected setup() {
const pureFetch = globalThis.fetch
invariant(
!(pureFetch as any)[IS_PATCHED_MODULE],
'Failed to patch the "fetch" module: already patched.'
)
globalThis.fetch = async (input, init) => {
const request = new Request(input, init)
const url = typeof input === 'string' ? input : input.url
const method = request.method
this.log('[%s] %s', method, url)
const body = await request.clone().arrayBuffer()
const requestUrl = new URL(
url,
typeof location !== 'undefined' ? location.origin : undefined
)
const isomorphicRequest = new IsomorphicRequest(requestUrl, {
body,
method,
headers: new Headers(request.headers),
credentials: request.credentials,
})
const interactiveIsomorphicRequest = new InteractiveIsomorphicRequest(
isomorphicRequest
)
this.log('isomorphic request', interactiveIsomorphicRequest)
this.log(
'emitting the "request" event for %d listener(s)...',
this.emitter.listenerCount('request')
)
this.emitter.emit('request', interactiveIsomorphicRequest)
this.log('awaiting for the mocked response...')
const [middlewareException, mockedResponse] = await until(async () => {
await this.emitter.untilIdle('request', ({ args: [request] }) => {
return request.id === interactiveIsomorphicRequest.id
})
this.log('all request listeners have been resolved!')
const [mockedResponse] =
await interactiveIsomorphicRequest.respondWith.invoked()
this.log('event.respondWith called with:', mockedResponse)
return mockedResponse
})
if (middlewareException) {
console.error(`${request.method} ${request.url} net::ERR_FAILED`)
const error = Object.assign(new TypeError('Failed to fetch'), {
cause: middlewareException,
})
return Promise.reject(error)
}
if (mockedResponse) {
this.log('received mocked response:', mockedResponse)
const isomorphicResponse = toIsoResponse(mockedResponse)
this.log('derived isomorphic response:', isomorphicResponse)
this.emitter.emit(
'response',
interactiveIsomorphicRequest,
isomorphicResponse
)
const response = new Response(mockedResponse.body, {
...isomorphicResponse,
// `Response.headers` cannot be instantiated with the `Headers` polyfill.
// Apparently, it halts if the `Headers` class contains unknown properties
// (i.e. the internal `Headers.map`).
headers: flattenHeadersObject(mockedResponse.headers || {}),
})
// Set the "response.url" property to equal the intercepted request URL.
Object.defineProperty(response, 'url', {
writable: false,
enumerable: true,
configurable: false,
value: interactiveIsomorphicRequest.url.href,
})
return response
}
this.log('no mocked response received!')
return pureFetch(request).then(async (response) => {
const cloneResponse = response.clone()
this.log('original fetch performed', cloneResponse)
this.emitter.emit(
'response',
interactiveIsomorphicRequest,
await normalizeFetchResponse(cloneResponse)
)
return response
})
}
I haven't changed anything in either of these files since starting my react app. If necessary I also have a link to the entire repository. The linked dev branch is the branch that I am encountering the issue on. The application code is in App.js and the tests are in App.test.js. The mock server is in setupServer.js.
I am trying to run the tests automatically in GitHub before merging dev into master, and while all tests pass, I am still getting an error code 1 as return value:
Run npm test
> [email protected] test
> react-scripts test
PASS src/App.test.js
App component
✓ renders race dropdown (140 ms)
✓ selects a race and renders subrace dropdown (141 ms)
✓ renders class dropdown (28 ms)
✓ selects a class and renders subclass dropdown (104 ms)
✓ rolls stats and displays rolled values (136 ms)
✓ selects class and checks if proficiencies are displayed correctly (72 ms)
✓ selects class and the max amount of proficiencies, then checks if selecting more proficiencies is allowed (74 ms)
✓ checks if proficiency checkboxes all start disabled when no class has been selected (36 ms)
Test Suites: 1 passed, 1 total
Tests: 8 passed, 8 total
Snapshots: 0 total
Time: 2.628 s
Ran all test suites.
/home/runner/work/characterbuilder/characterbuilder/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/browser/Window.js:375
return idlUtils.wrapperForImpl(idlUtils.implForWrapper(window._document)._location);
^
TypeError: Cannot read properties of null (reading '_location')
at Window.get location [as location] (/home/runner/work/characterbuilder/characterbuilder/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/browser/Window.js:375:79)
at FetchInterceptor.<anonymous> (/home/runner/work/characterbuilder/characterbuilder/node_modules/@mswjs/interceptors/src/interceptors/fetch/index.ts:52:9)
at step (/home/runner/work/characterbuilder/characterbuilder/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:59:23)
at Object.next (/home/runner/work/characterbuilder/characterbuilder/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:40:53)
at fulfilled (/home/runner/work/characterbuilder/characterbuilder/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:31:58)
at runNextTicks (node:internal/process/task_queues:60:5)
at processImmediate (node:internal/timers:447:9)
Node.js v18.16.0
Error: Process completed with exit code 1.
The github workflow/ action file looks as follows:
name: Continuous Integration
on:
push:
branches:
- dev
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install dependencies
run: npm ci
- name: Install
run: npm install
- name: run tests
run: npm test
I have tried multiple solutions that I found on the internet. I have added window.URL.createObjectURL = function () {};
and jest.spyOn(window, "close").mockImplementation(jest.fn());
to the setupTests.js and I have also read of people on the internet saying that it was because of a fireEvent in one of the tests, so I have also tried it with only a single test that doesn't really test anything to see if that would cause the tests to complete successfully.