Skip to content

Commit

Permalink
chore: improve happyDOM integration
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Aug 17, 2023
1 parent 54866e1 commit 9f11b8c
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 13 deletions.
12 changes: 6 additions & 6 deletions packages/vitest/src/integrations/env/happy-dom.ts
Expand Up @@ -5,11 +5,11 @@ import { populateGlobal } from './utils'
export default <Environment>({
name: 'happy-dom',
transformMode: 'web',
async setupVM({ 'happy-dom': happyDom = {} }) {
async setupVM({ happyDOM = {} }) {
const { Window } = await importModule('happy-dom') as typeof import('happy-dom')
const win = new Window({
...happyDom,
url: happyDom.url || 'http://localhost:3000',
...happyDOM,
url: happyDOM.url || 'http://localhost:3000',
}) as any

// TODO: browser doesn't expose Buffer, but a lot of dependencies use it
Expand All @@ -29,13 +29,13 @@ export default <Environment>({
},
}
},
async setup(global, { 'happy-dom': happyDom = {} }) {
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)({
...happyDom,
url: happyDom.url || 'http://localhost:3000',
...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)
})
8 changes: 3 additions & 5 deletions test/core/test/happy-dom.test.ts
Expand Up @@ -2,7 +2,6 @@

/**
* @vitest-environment happy-dom
* @vitest-environment-options { "settings": { "disableCSSFileLoading": true }, "width": 1920 }
*/

/* eslint-disable vars-on-top */
Expand All @@ -13,16 +12,15 @@ declare global {
// eslint-disable-next-line no-var
var __property_dom: unknown
// eslint-disable-next-line no-var
var happyDOM: unknown
var happyDOM: any
}

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

it('accepts custom environment options', () => {
// default is false
expect((window.happyDOM as any).settings.disableCSSFileLoading).toBe(true)
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', () => {
Expand Down

0 comments on commit 9f11b8c

Please sign in to comment.