Skip to content

Commit

Permalink
fix(vitest): strongly type vitest environment options
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Apr 17, 2024
1 parent dd295d3 commit 37582c7
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 44 deletions.
54 changes: 22 additions & 32 deletions src/environments/vitest/env/jsdom.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,28 @@
import { importModule } from 'local-pkg'
import type { EnvironmentNuxt } from '../types'
import type { DOMWindow, SupportedContentTypes } from 'jsdom'
import defu from 'defu'
import type { JSDOMOptions } from 'vitest'
import type { EnvironmentNuxt, NuxtWindow } from '../types'

export default <EnvironmentNuxt> async function (global, { jsdom = {} }) {
const { CookieJar, JSDOM, ResourceLoader, VirtualConsole }
= (await importModule('jsdom')) as typeof import('jsdom')
const {
html = '<!DOCTYPE html>',
userAgent,
url = 'http://localhost:3000',
contentType = 'text/html',
pretendToBeVisual = true,
includeNodeLocations = false,
runScripts = 'dangerously',
resources,
console = false,
cookieJar = false,
...restOptions
} = jsdom as any
const window = new JSDOM(html, {
pretendToBeVisual,
resources:
resources ?? (userAgent ? new ResourceLoader({ userAgent }) : undefined),
runScripts,
url,
virtualConsole:
console && global.console
? new VirtualConsole().sendTo(global.console)
: undefined,
cookieJar: cookieJar ? new CookieJar() : undefined,
includeNodeLocations,
contentType,
userAgent,
...restOptions,
}).window as any
const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = (await importModule('jsdom')) as typeof import('jsdom')
const jsdomOptions = defu(jsdom, {
html: '<!DOCTYPE html>',
url: 'http://localhost:3000',
contentType: 'text/html' as const,
pretendToBeVisual: true,
includeNodeLocations: false,
runScripts: 'dangerously',
console: false,
cookieJar: false,
} satisfies JSDOMOptions) as JSDOMOptions & { contentType: SupportedContentTypes }

const window = new JSDOM(jsdomOptions.html, {
...jsdomOptions,
resources: jsdomOptions.resources ?? (jsdomOptions.userAgent ? new ResourceLoader({ userAgent: jsdomOptions.userAgent }) : undefined),
virtualConsole: jsdomOptions.console && global.console ? new VirtualConsole().sendTo(global.console) : undefined,
cookieJar: jsdomOptions.cookieJar ? new CookieJar() : undefined,
}).window as DOMWindow & NuxtWindow

// Vue-router relies on scrollTo being available if run in a browser.
// The scrollTo implementation from JSDOM throws a "Not Implemented" error
Expand Down
7 changes: 5 additions & 2 deletions src/environments/vitest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,17 @@ export default <Environment>{

const registry = new Set<string>()

win.fetch = (init: string, options?: any) => {
win.fetch = (init, options) => {
if (typeof init === 'string') {
const base = init.split('?')[0]
if (registry.has(base) || registry.has(init)) {
init = '/_' + init
}
}
return localFetch(init, options)
return localFetch(init.toString(), {
...options,
headers: Array.isArray(options?.headers) ? new Headers(options?.headers) : options?.headers,
})
}

win.$fetch = createFetch({ fetch: win.fetch, Headers: win.Headers })
Expand Down
23 changes: 13 additions & 10 deletions src/environments/vitest/types.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import type { App } from 'h3'
import type { $Fetch } from 'nitropack'
import type { JSDOMOptions, HappyDOMOptions } from 'vitest'

export type NuxtBuiltinEnvironment = 'happy-dom' | 'jsdom'
export interface NuxtWindow extends Window {
__app: App
__registry: Set<string>
__NUXT_VITEST_ENVIRONMENT__?: boolean
__NUXT__: any
$fetch: any
fetch: any
IntersectionObserver: any
Headers: any
__NUXT__: Record<string, unknown>
$fetch: $Fetch
fetch: ((input: RequestInfo | URL, init?: RequestInit | undefined) => Promise<Response>)
IntersectionObserver: unknown
Headers: typeof Headers
}
export type EnvironmentNuxt = (
global: any,
options: Record<string, any>
) => Promise<{
export interface EnvironmentNuxtOptions {
jsdom?: JSDOMOptions
happyDom?: HappyDOMOptions
}
export type EnvironmentNuxt = (global: typeof globalThis, options: EnvironmentNuxtOptions) => Promise<{
window: NuxtWindow
teardown(): void
teardown (): void
}>

0 comments on commit 37582c7

Please sign in to comment.