Skip to content

Commit f0d4b2b

Browse files
authored
fix: add BroadcastChannel (#19)
1 parent aa92f08 commit f0d4b2b

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<h1 align="center">jest-fixed-jsdom</h1>
22
<p align="center">A superset of the JSDOM environment for Jest that respects Node.js globals.</p>
33

4+
<!-- prettier-ignore-start -->
5+
> [!WARNING]
6+
> **This package is never meant as a solution to anything**. This is a workaround. Please consider testing browser code in the actual browser. You can do so both in [Vitest](https://vitest.dev/guide/browser/) and in [Playwright](https://playwright.dev/docs/test-components) at the moment.
7+
<!-- prettier-ignore-end -->
8+
49
## Motivation
510

611
When you use Jest with JSDOM you are getting a broken test environment. Some Node.js globals cease to exist (e.g. `Request`, `Response`, `TextEncoder`, `TextDecoder`, `ReadableStream`<sup><a href="https://github.com/mswjs/msw/issues/1916">1</a></sup>), while others stop behaving correctly (e.g. `Event`, `MessageEvent`<sup><a href="https://github.com/nodejs/undici/issues/2663">2</a></sup>, `structuredClone()`<sup><a href="https://github.com/mswjs/msw/issues/1931">3</a></sup>). That is caused by `jest-environment-jsdom` and JSDOM relying on polyfills to implement standard APIs that have been available globally both in the browser and in Node.js for years.
@@ -37,6 +42,7 @@ This project "fixes" the following global APIs, overriding whichever polyfills t
3742
- `structuredClone()`
3843
- `URL`
3944
- `URLSearchParams`
45+
- `BroadcastChannel`
4046

4147
## Getting started
4248

index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class FixedJSDOMEnvironment extends JSDOMEnvironment {
1919
this.global.structuredClone = structuredClone
2020
this.global.URL = URL
2121
this.global.URLSearchParams = URLSearchParams
22+
23+
this.global.BroadcastChannel = BroadcastChannel
2224
}
2325
}
2426

index.test.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
const { URL: BuiltinURL } = require('node:url')
2+
const {
3+
BroadcastChannel: BuiltinBroadcastChannel,
4+
} = require('node:worker_threads')
25

36
test('exposes "Blob"', async () => {
47
expect(globalThis).toHaveProperty('Blob')
@@ -38,7 +41,9 @@ test('exposes "TextEncoderStream"', async () => {
3841
if (done) break
3942
chunks.push(...value)
4043
}
41-
expect(Buffer.from(chunks)).toEqual(Buffer.from(new Uint8Array([104, 101, 108, 108, 111])))
44+
expect(Buffer.from(chunks)).toEqual(
45+
Buffer.from(new Uint8Array([104, 101, 108, 108, 111])),
46+
)
4247
})
4348

4449
test('exposes "TextDecoderStream"', async () => {
@@ -139,6 +144,22 @@ test('exposes "URLSearchParams" and makes it mockable', () => {
139144
.mockImplementation((key) => key === 'mocked_flag')
140145

141146
expect(globalThis).toHaveProperty('URLSearchParams')
142-
expect(new URL('http://localhost?other_non_mocked_flag').searchParams.has('other_non_mocked_flag')).toBe(false)
143-
expect(new URL('http://localhost?other_non_mocked_flag').searchParams.has('mocked_flag')).toBe(true)
147+
expect(
148+
new URL('http://localhost?other_non_mocked_flag').searchParams.has(
149+
'other_non_mocked_flag',
150+
),
151+
).toBe(false)
152+
expect(
153+
new URL('http://localhost?other_non_mocked_flag').searchParams.has(
154+
'mocked_flag',
155+
),
156+
).toBe(true)
157+
})
158+
159+
test('exposes "BroadcastChannel"', () => {
160+
expect(globalThis).toHaveProperty('BroadcastChannel')
161+
162+
const channel = new BroadcastChannel('foo')
163+
expect(channel).toBeInstanceOf(BuiltinBroadcastChannel)
164+
channel.unref()
144165
})

0 commit comments

Comments
 (0)