Skip to content

Commit

Permalink
fix(vitest): pass environmentOptions to happy-dom integration (#3972)
Browse files Browse the repository at this point in the history
Co-authored-by: Raul de Melo <melo.raulf@gmail.com>
  • Loading branch information
sheremet-va and raulfdm committed Aug 17, 2023
1 parent 0f8e60b commit 6a0cb64
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 6 deletions.
14 changes: 10 additions & 4 deletions packages/vitest/src/integrations/env/happy-dom.ts
Expand Up @@ -5,9 +5,12 @@ import { populateGlobal } from './utils'
export default <Environment>({
name: 'happy-dom',
transformMode: 'web',
async setupVM() {
async setupVM({ happyDOM = {} }) {
const { Window } = await importModule('happy-dom') as typeof import('happy-dom')
const win = new Window() as any
const win = new Window({
...happyDOM,
url: happyDOM.url || 'http://localhost:3000',
}) as any

// TODO: browser doesn't expose Buffer, but a lot of dependencies use it
win.Buffer = Buffer
Expand All @@ -26,11 +29,14 @@ export default <Environment>({
},
}
},
async setup(global) {
async setup(global, { happyDOM = {} }) {
// happy-dom v3 introduced a breaking change to Window, but
// provides GlobalWindow as a way to use previous behaviour
const { Window, GlobalWindow } = await importModule('happy-dom') as typeof import('happy-dom')
const win = new (GlobalWindow || Window)()
const win = new (GlobalWindow || Window)({
...happyDOM,
url: happyDOM.url || 'http://localhost:3000',
})

const { keys, originals } = populateGlobal(global, win, { bindFunctions: true })

Expand Down
4 changes: 3 additions & 1 deletion packages/vitest/src/types/config.ts
Expand Up @@ -8,6 +8,7 @@ import type { TestSequencerConstructor } from '../node/sequencers/types'
import type { ChaiConfig } from '../integrations/chai/config'
import type { CoverageOptions, ResolvedCoverageOptions } from './coverage'
import type { JSDOMOptions } from './jsdom-options'
import type { HappyDOMOptions } from './happy-dom-options'
import type { Reporter } from './reporter'
import type { SnapshotStateOptions } from './snapshot'
import type { Arrayable } from './general'
Expand All @@ -24,13 +25,14 @@ export type CSSModuleScopeStrategy = 'stable' | 'scoped' | 'non-scoped'

export type ApiConfig = Pick<CommonServerOptions, 'port' | 'strictPort' | 'host'>

export { JSDOMOptions }
export type { JSDOMOptions, HappyDOMOptions }

export interface EnvironmentOptions {
/**
* jsdom options.
*/
jsdom?: JSDOMOptions
happyDOM?: HappyDOMOptions
[x: string]: unknown
}

Expand Down
20 changes: 20 additions & 0 deletions packages/vitest/src/types/happy-dom-options.ts
@@ -0,0 +1,20 @@
/**
* Happy DOM options.
*/
export interface HappyDOMOptions {
width?: number
height?: number
url?: string
settings?: {
disableJavaScriptEvaluation?: boolean
disableJavaScriptFileLoading?: boolean
disableCSSFileLoading?: boolean
disableIframePageLoading?: boolean
disableComputedStyleRendering?: boolean
enableFileSystemHttpRequests?: boolean
device?: {
prefersColorScheme?: string
mediaType?: string
}
}
}
3 changes: 2 additions & 1 deletion packages/vitest/src/utils/test-helpers.ts
Expand Up @@ -46,13 +46,14 @@ export async function groupFilesByEnv(files: (readonly [WorkspaceProject, string
const transformMode = getTransformMode(project.config.testTransformMode, file)

const envOptions = JSON.parse(code.match(/@(?:vitest|jest)-environment-options\s+?(.+)/)?.[1] || 'null')
const envKey = env === 'happy-dom' ? 'happyDOM' : env
return {
file,
project,
environment: {
name: env as VitestEnvironment,
transformMode,
options: envOptions ? { [env]: envOptions } as EnvironmentOptions : null,
options: envOptions ? { [envKey]: envOptions } as EnvironmentOptions : null,
},
}
}))
Expand Down
22 changes: 22 additions & 0 deletions test/core/test/happy-dom-custom.test.ts
@@ -0,0 +1,22 @@
/**
* @vitest-environment happy-dom
* @vitest-environment-options { "url": "http://my-website:5435", "settings": { "disableCSSFileLoading": true } }
*/

/* eslint-disable vars-on-top */

import { expect, it } from 'vitest'

declare global {
// eslint-disable-next-line no-var
var happyDOM: any
}

it('custom URL is changed to my-website:5435', () => {
expect(location.href).toBe('http://my-website:5435/')
})

it('accepts custom environment options', () => {
// default is false
expect(window.happyDOM.settings.disableCSSFileLoading).toBe(true)
})
10 changes: 10 additions & 0 deletions test/core/test/happy-dom.test.ts
Expand Up @@ -11,8 +11,18 @@ import { expect, it, vi } from 'vitest'
declare global {
// eslint-disable-next-line no-var
var __property_dom: unknown
// eslint-disable-next-line no-var
var happyDOM: any
}

it('defaults URL to localhost:3000', () => {
expect(location.href).toBe('http://localhost:3000/')
})

it('disableCSSFileLoading is false by default because we didn\'t change options', () => {
expect(window.happyDOM.settings.disableCSSFileLoading).toBe(false)
})

it('defined on self/window are defined on global', () => {
expect(self).toBeDefined()
expect(window).toBeDefined()
Expand Down

0 comments on commit 6a0cb64

Please sign in to comment.