/
e2e.js
executable file
·173 lines (148 loc) · 5.34 KB
/
e2e.js
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env node
'use strict'
const jest = require('jest')
const { spawnSync } = require('./lib/spawn-sync')
const fs = require('fs-extra')
const path = require('path')
const Paths = require('./lib/paths')
const { createHash } = require('crypto')
const logger = require('./lib/logger')
const { createBundle, readPackageDigest } = require('./lib/bundle')
const npm = require('./lib/npm')
const configFile = path.join(Paths.e2eRootDir, 'jest.config.js')
let parentArgs = process.argv.slice(2)
if (parentArgs.includes('--coverage')) {
logger.warn(
'Coverages cannot be activated for e2e tests (but can in each e2e test).'
)
parentArgs = parentArgs.filter(a => a !== '--coverage')
}
if (!parentArgs.includes('--runInBand')) parentArgs.push('--runInBand')
const prepareOnly = parentArgs.includes('--prepareOnly')
function getDirectories(rootDir) {
return fs.readdirSync(rootDir).filter(function(file) {
return fs.statSync(path.join(rootDir, file)).isDirectory()
})
}
function sha1(...data) {
const hash = createHash('sha1')
data.forEach(item => hash.update(item))
return hash.digest('hex').toString()
}
function log(...msg) {
logger.log('[e2e]', ...msg)
}
function setupE2e() {
// kept on top so that the build is triggered beforehand (pack => prepublish => clean-build => build)
const bundle = createBundle(log)
log(
'bundle created:',
path.relative(Paths.rootDir, bundle),
'; computing digest'
)
// get the hash of the bundle (to know if we should install it again or not)
const bundleHash = readPackageDigest()
log('ts-jest digest:', bundleHash)
// ensure directory exists before copying over
fs.mkdirpSync(Paths.e2eWorkTemplatesDir)
// link locally so we could find it easily
if (!process.env.CI && !fs.existsSync(Paths.e2eWotkDirLink)) {
fs.symlinkSync(Paths.e2eWorkDir, Paths.e2eWotkDirLink, 'dir')
log(
'symbolic link to the work directory created at: ',
Paths.e2eWotkDirLink
)
}
// install with `npm ci` in each template, this is the fastest but needs a package lock file,
// that is why we end with the npm install of our bundle
getDirectories(Paths.e2eTemplatesDir).forEach(name => {
log('checking template ', name)
const sourceDir = path.join(Paths.e2eTemplatesDir, name)
const dir = path.join(Paths.e2eWorkTemplatesDir, name)
const nodeModulesDir = path.join(dir, 'node_modules')
const pkgLockFile = path.join(sourceDir, 'package-lock.json')
const e2eFile = path.join(nodeModulesDir, '.ts-jest-e2e.json')
// log installed versions
const logPackageVersions = () => {
log(` [template: ${name}]`, 'installed direct dependencies:')
let deps = npm.directDepsPkg(dir)
Object.keys(deps)
.sort()
.forEach(name => {
log(
' -',
`${name}${' '.repeat(20 - name.length)}`,
deps[name].version
)
})
deps = null
}
// remove all files expect node_modules
if (fs.existsSync(dir)) {
log(` [template: ${name}]`, 'removing old files')
fs.readdirSync(dir).forEach(file => {
if (file !== 'node_modules') {
fs.unlinkSync(path.join(dir, file))
}
})
} else {
fs.mkdirpSync(dir)
}
// copy files from template
log(` [template: ${name}]`, 'copying files from template source')
fs.copySync(sourceDir, dir)
// no package-lock.json => this template doesn't provide any package-set
if (!fs.existsSync(pkgLockFile)) {
log(` [template: ${name}]`, 'not a package-set template, nothing to do')
return
}
const pkgLockHash = sha1(fs.readFileSync(pkgLockFile))
const e2eData = fs.existsSync(e2eFile) ? fs.readJsonSync(e2eFile) : {}
let bundleOk = e2eData.bundleHash === bundleHash
let packagesOk = e2eData.packageLockHash === pkgLockHash
if (fs.existsSync(nodeModulesDir)) {
log(` [template: ${name}]`, 'bundle: ', bundleOk ? 'OK' : 'CHANGED')
log(` [template: ${name}]`, 'packages: ', packagesOk ? 'OK' : 'CHANGED')
if (bundleOk && packagesOk) {
log(
` [template: ${name}]`,
'bundle and packages unchanged, nothing to do'
)
logPackageVersions()
return
}
}
if (!packagesOk) {
// faster to remove them first
log(` [template: ${name}]`, 'removing `node_modules` directory')
fs.removeSync(path.join(dir, 'node_modules'))
if (npm.can.ci()) {
log(` [template: ${name}]`, 'installing packages using "npm ci"')
spawnSync('npm', ['ci'], { cwd: dir })
} else {
log(` [template: ${name}]`, 'installing packages using "npm install"')
spawnSync('npm', ['i'], { cwd: dir })
}
bundleOk = false
}
if (!bundleOk) {
log(` [template: ${name}]`, 'installing bundle')
spawnSync('npm', ['i', '-D', bundle], { cwd: dir })
}
logPackageVersions()
// write our data
e2eData.bundleHash = bundleHash
e2eData.packageLockHash = pkgLockHash
log(` [template: ${name}]`, 'writing manifest')
fs.outputJsonSync(e2eFile, e2eData, { space: 2 })
})
}
// ============================================================================
setupE2e()
log('templates are ready')
if (!prepareOnly) {
log('clearing Jest cache')
spawnSync('jest', ['--clearCache'])
log('running tests')
jest.run(['--config', configFile, ...parentArgs])
}