|
1 | 1 | import type { WorkerGlobalState } from 'vitest'
|
2 | 2 | import { parse } from 'flatted'
|
3 | 3 | import { getBrowserState } from '../utils'
|
| 4 | +import type { BrowserRPC } from '../client' |
4 | 5 |
|
5 | 6 | const config = getBrowserState().config
|
| 7 | +const contextId = getBrowserState().contextId |
6 | 8 |
|
7 | 9 | const providedContext = parse(getBrowserState().providedContext)
|
8 | 10 |
|
@@ -44,3 +46,71 @@ const state: WorkerGlobalState = {
|
44 | 46 | globalThis.__vitest_browser__ = true
|
45 | 47 | // @ts-expect-error not typed global
|
46 | 48 | globalThis.__vitest_worker__ = state
|
| 49 | + |
| 50 | +getBrowserState().cdp = createCdp() |
| 51 | + |
| 52 | +function rpc() { |
| 53 | + return state.rpc as any as BrowserRPC |
| 54 | +} |
| 55 | + |
| 56 | +function createCdp() { |
| 57 | + const listenersMap = new WeakMap<Function, string>() |
| 58 | + |
| 59 | + function getId(listener: Function) { |
| 60 | + const id = listenersMap.get(listener) || crypto.randomUUID() |
| 61 | + listenersMap.set(listener, id) |
| 62 | + return id |
| 63 | + } |
| 64 | + |
| 65 | + const listeners: Record<string, Function[]> = {} |
| 66 | + |
| 67 | + const error = (err: unknown) => { |
| 68 | + window.dispatchEvent(new ErrorEvent('error', { error: err })) |
| 69 | + } |
| 70 | + |
| 71 | + const cdp = { |
| 72 | + send(method: string, params?: Record<string, any>) { |
| 73 | + return rpc().sendCdpEvent(contextId, method, params) |
| 74 | + }, |
| 75 | + on(event: string, listener: (payload: any) => void) { |
| 76 | + const listenerId = getId(listener) |
| 77 | + listeners[event] = listeners[event] || [] |
| 78 | + listeners[event].push(listener) |
| 79 | + rpc().trackCdpEvent(contextId, 'on', event, listenerId).catch(error) |
| 80 | + return cdp |
| 81 | + }, |
| 82 | + once(event: string, listener: (payload: any) => void) { |
| 83 | + const listenerId = getId(listener) |
| 84 | + const handler = (data: any) => { |
| 85 | + listener(data) |
| 86 | + cdp.off(event, listener) |
| 87 | + } |
| 88 | + listeners[event] = listeners[event] || [] |
| 89 | + listeners[event].push(handler) |
| 90 | + rpc().trackCdpEvent(contextId, 'once', event, listenerId).catch(error) |
| 91 | + return cdp |
| 92 | + }, |
| 93 | + off(event: string, listener: (payload: any) => void) { |
| 94 | + const listenerId = getId(listener) |
| 95 | + if (listeners[event]) { |
| 96 | + listeners[event] = listeners[event].filter(l => l !== listener) |
| 97 | + } |
| 98 | + rpc().trackCdpEvent(contextId, 'off', event, listenerId).catch(error) |
| 99 | + return cdp |
| 100 | + }, |
| 101 | + emit(event: string, payload: unknown) { |
| 102 | + if (listeners[event]) { |
| 103 | + listeners[event].forEach((l) => { |
| 104 | + try { |
| 105 | + l(payload) |
| 106 | + } |
| 107 | + catch (err) { |
| 108 | + error(err) |
| 109 | + } |
| 110 | + }) |
| 111 | + } |
| 112 | + }, |
| 113 | + } |
| 114 | + |
| 115 | + return cdp |
| 116 | +} |
0 commit comments