mirror of
https://github.com/vitest-dev/vitest.git
synced 2025-12-08 18:26:03 +00:00
116 lines
3.0 KiB
TypeScript
116 lines
3.0 KiB
TypeScript
import type { BrowserRPC } from '@vitest/browser/client'
|
|
import type { WorkerGlobalState } from 'vitest'
|
|
import { getBrowserState } from '../utils'
|
|
|
|
const config = getBrowserState().config
|
|
const sessionId = getBrowserState().sessionId
|
|
|
|
const state: WorkerGlobalState = {
|
|
ctx: {
|
|
pool: 'browser',
|
|
worker: './browser.js',
|
|
workerId: 1,
|
|
config,
|
|
projectName: config.name || '',
|
|
files: [],
|
|
environment: {
|
|
name: 'browser',
|
|
options: null,
|
|
},
|
|
// this is populated before tests run
|
|
providedContext: {},
|
|
invalidates: [],
|
|
},
|
|
onCancel: null as any,
|
|
config,
|
|
environment: {
|
|
name: 'browser',
|
|
transformMode: 'web',
|
|
setup() {
|
|
throw new Error('Not called in the browser')
|
|
},
|
|
},
|
|
onCleanup: fn => getBrowserState().cleanups.push(fn),
|
|
moduleCache: getBrowserState().moduleCache,
|
|
moduleExecutionInfo: new Map(),
|
|
rpc: null as any,
|
|
durations: {
|
|
environment: 0,
|
|
prepare: performance.now(),
|
|
},
|
|
providedContext: {},
|
|
}
|
|
|
|
// @ts-expect-error not typed global
|
|
globalThis.__vitest_browser__ = true
|
|
// @ts-expect-error not typed global
|
|
globalThis.__vitest_worker__ = state
|
|
|
|
getBrowserState().cdp = createCdp()
|
|
|
|
function rpc() {
|
|
return state.rpc as any as BrowserRPC
|
|
}
|
|
|
|
function createCdp() {
|
|
const listenersMap = new WeakMap<Function, string>()
|
|
|
|
function getId(listener: Function) {
|
|
const id = listenersMap.get(listener) || crypto.randomUUID()
|
|
listenersMap.set(listener, id)
|
|
return id
|
|
}
|
|
|
|
const listeners: Record<string, Function[]> = {}
|
|
|
|
const cdp = {
|
|
send(method: string, params?: Record<string, any>) {
|
|
return rpc().sendCdpEvent(sessionId, method, params)
|
|
},
|
|
on(event: string, listener: (payload: any) => void) {
|
|
const listenerId = getId(listener)
|
|
listeners[event] = listeners[event] || []
|
|
listeners[event].push(listener)
|
|
rpc().trackCdpEvent(sessionId, 'on', event, listenerId).catch(error)
|
|
return cdp
|
|
},
|
|
once(event: string, listener: (payload: any) => void) {
|
|
const listenerId = getId(listener)
|
|
const handler = (data: any) => {
|
|
listener(data)
|
|
cdp.off(event, listener)
|
|
}
|
|
listeners[event] = listeners[event] || []
|
|
listeners[event].push(handler)
|
|
rpc().trackCdpEvent(sessionId, 'once', event, listenerId).catch(error)
|
|
return cdp
|
|
},
|
|
off(event: string, listener: (payload: any) => void) {
|
|
const listenerId = getId(listener)
|
|
if (listeners[event]) {
|
|
listeners[event] = listeners[event].filter(l => l !== listener)
|
|
}
|
|
rpc().trackCdpEvent(sessionId, 'off', event, listenerId).catch(error)
|
|
return cdp
|
|
},
|
|
emit(event: string, payload: unknown) {
|
|
if (listeners[event]) {
|
|
listeners[event].forEach((l) => {
|
|
try {
|
|
l(payload)
|
|
}
|
|
catch (err) {
|
|
error(err)
|
|
}
|
|
})
|
|
}
|
|
},
|
|
}
|
|
|
|
return cdp
|
|
}
|
|
|
|
function error(err: unknown) {
|
|
window.dispatchEvent(new ErrorEvent('error', { error: err }))
|
|
}
|