forked from cypress-io/cypress
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnode-jsdom-setup.ts
136 lines (106 loc) · 3.22 KB
/
node-jsdom-setup.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import mockRequire from 'mock-require'
import { JSDOM } from 'jsdom'
import * as ansiEscapes from 'ansi-escapes'
import enzyme from 'enzyme'
import EnzymeAdapter from 'enzyme-adapter-react-16'
import ChaiEnzyme from 'chai-enzyme'
declare global {
module NodeJS {
interface Global {
[key: string]: any
}
}
}
interface RegisterDeps {
enzyme: typeof enzyme
EnzymeAdapter: typeof EnzymeAdapter
chaiEnzyme: typeof ChaiEnzyme
requireOverride: (...args: any[]) => any
}
type TimeoutID = number
export const register = ({
enzyme,
EnzymeAdapter,
chaiEnzyme,
requireOverride,
}: RegisterDeps) => {
const jsdom = new JSDOM('<!doctype html><html><body></body></html>')
const { window } = jsdom
const chai = require('chai')
const sinonChai = require('sinon-chai')
// const chaiEnzyme = require('chai-enzyme')
// @ts-ignore
global.window = window
global.document = window.document;
// DOMWindow doesn't have Selection yet.
(window as any).Selection = { prototype: { isCollapsed: {} } }
// @ts-ignore
global.navigator = {
userAgent: 'node.js',
}
// @ts-ignore
global.requestAnimationFrame = window.requestAnimationFrame = function (callback: FrameRequestCallback) {
return setTimeout(callback, 0)
}
global.cancelAnimationFrame = window.cancelAnimationFrame = function (id: TimeoutID) {
clearTimeout(id)
}
Object.keys(window.document.defaultView as Record<string, any>).forEach((property) => {
if (
property === 'localStorage' ||
property === 'sessionStorage' ||
typeof global[property] !== 'undefined'
) return
global[property] = (window.document.defaultView as Record<string, any>)[property]
})
// enzyme, and therefore chai-enzyme, needs to be required after
// global.navigator is set up (https://github.com/airbnb/enzyme/issues/395)
enzyme.configure({ adapter: new EnzymeAdapter() })
chai.use(chaiEnzyme())
chai.use(sinonChai)
global.expect = chai.expect
const bresolve = require('browser-resolve')
const Module = require('module')
const overrideRequire = () => {
const _load = Module._load
Module._load = function (...args: any[]) {
let browserPkg = args
if (requireOverride) {
const mockedDependency = requireOverride(...args)
if (mockedDependency != null) {
return mockedDependency
}
}
// Follow browser-field spec for importing modules
// except chalk so we dont mess up mocha coloring
if (!['path'].includes(args[0]) && !(args[1] && args[1].id.includes('chalk'))) {
try {
browserPkg = [bresolve.sync.apply(this, args)]
} catch (e) {
null
}
}
// Stub out all webpack-specific imports
if (args[0].includes('!')) {
return {}
}
if (args[0].endsWith('.png')) {
return args[0]
}
if (args[0].endsWith('.scss')) {
return args[0]
}
const ret = _load.apply(this, browserPkg)
return ret
}
}
overrideRequire()
}
// eslint-disable-next-line
after(() => {
process.stdout.write(ansiEscapes.cursorShow)
})
export const returnMockRequire = (name: string, modExport: object = {}) => {
mockRequire(name, modExport)
return require(name)
}