Skip to content

Commit 37582c7

Browse files
committed
fix(vitest): strongly type vitest environment options
1 parent dd295d3 commit 37582c7

File tree

3 files changed

+40
-44
lines changed

3 files changed

+40
-44
lines changed

src/environments/vitest/env/jsdom.ts

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,28 @@
11
import { importModule } from 'local-pkg'
2-
import type { EnvironmentNuxt } from '../types'
2+
import type { DOMWindow, SupportedContentTypes } from 'jsdom'
3+
import defu from 'defu'
4+
import type { JSDOMOptions } from 'vitest'
5+
import type { EnvironmentNuxt, NuxtWindow } from '../types'
36

47
export default <EnvironmentNuxt> async function (global, { jsdom = {} }) {
5-
const { CookieJar, JSDOM, ResourceLoader, VirtualConsole }
6-
= (await importModule('jsdom')) as typeof import('jsdom')
7-
const {
8-
html = '<!DOCTYPE html>',
9-
userAgent,
10-
url = 'http://localhost:3000',
11-
contentType = 'text/html',
12-
pretendToBeVisual = true,
13-
includeNodeLocations = false,
14-
runScripts = 'dangerously',
15-
resources,
16-
console = false,
17-
cookieJar = false,
18-
...restOptions
19-
} = jsdom as any
20-
const window = new JSDOM(html, {
21-
pretendToBeVisual,
22-
resources:
23-
resources ?? (userAgent ? new ResourceLoader({ userAgent }) : undefined),
24-
runScripts,
25-
url,
26-
virtualConsole:
27-
console && global.console
28-
? new VirtualConsole().sendTo(global.console)
29-
: undefined,
30-
cookieJar: cookieJar ? new CookieJar() : undefined,
31-
includeNodeLocations,
32-
contentType,
33-
userAgent,
34-
...restOptions,
35-
}).window as any
8+
const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = (await importModule('jsdom')) as typeof import('jsdom')
9+
const jsdomOptions = defu(jsdom, {
10+
html: '<!DOCTYPE html>',
11+
url: 'http://localhost:3000',
12+
contentType: 'text/html' as const,
13+
pretendToBeVisual: true,
14+
includeNodeLocations: false,
15+
runScripts: 'dangerously',
16+
console: false,
17+
cookieJar: false,
18+
} satisfies JSDOMOptions) as JSDOMOptions & { contentType: SupportedContentTypes }
19+
20+
const window = new JSDOM(jsdomOptions.html, {
21+
...jsdomOptions,
22+
resources: jsdomOptions.resources ?? (jsdomOptions.userAgent ? new ResourceLoader({ userAgent: jsdomOptions.userAgent }) : undefined),
23+
virtualConsole: jsdomOptions.console && global.console ? new VirtualConsole().sendTo(global.console) : undefined,
24+
cookieJar: jsdomOptions.cookieJar ? new CookieJar() : undefined,
25+
}).window as DOMWindow & NuxtWindow
3626

3727
// Vue-router relies on scrollTo being available if run in a browser.
3828
// The scrollTo implementation from JSDOM throws a "Not Implemented" error

src/environments/vitest/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,17 @@ export default <Environment>{
7777

7878
const registry = new Set<string>()
7979

80-
win.fetch = (init: string, options?: any) => {
80+
win.fetch = (init, options) => {
8181
if (typeof init === 'string') {
8282
const base = init.split('?')[0]
8383
if (registry.has(base) || registry.has(init)) {
8484
init = '/_' + init
8585
}
8686
}
87-
return localFetch(init, options)
87+
return localFetch(init.toString(), {
88+
...options,
89+
headers: Array.isArray(options?.headers) ? new Headers(options?.headers) : options?.headers,
90+
})
8891
}
8992

9093
win.$fetch = createFetch({ fetch: win.fetch, Headers: win.Headers })

src/environments/vitest/types.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import type { App } from 'h3'
2+
import type { $Fetch } from 'nitropack'
3+
import type { JSDOMOptions, HappyDOMOptions } from 'vitest'
24

35
export type NuxtBuiltinEnvironment = 'happy-dom' | 'jsdom'
46
export interface NuxtWindow extends Window {
57
__app: App
68
__registry: Set<string>
79
__NUXT_VITEST_ENVIRONMENT__?: boolean
8-
__NUXT__: any
9-
$fetch: any
10-
fetch: any
11-
IntersectionObserver: any
12-
Headers: any
10+
__NUXT__: Record<string, unknown>
11+
$fetch: $Fetch
12+
fetch: ((input: RequestInfo | URL, init?: RequestInit | undefined) => Promise<Response>)
13+
IntersectionObserver: unknown
14+
Headers: typeof Headers
1315
}
14-
export type EnvironmentNuxt = (
15-
global: any,
16-
options: Record<string, any>
17-
) => Promise<{
16+
export interface EnvironmentNuxtOptions {
17+
jsdom?: JSDOMOptions
18+
happyDom?: HappyDOMOptions
19+
}
20+
export type EnvironmentNuxt = (global: typeof globalThis, options: EnvironmentNuxtOptions) => Promise<{
1821
window: NuxtWindow
19-
teardown(): void
22+
teardown (): void
2023
}>

0 commit comments

Comments
 (0)