ui5-test-runner 5.13.1 → 6.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/Npm.js +80 -0
- package/dist/browsers/IBrowser.js +1 -0
- package/dist/browsers/factory.js +9 -0
- package/dist/browsers/puppeteer.js +158 -0
- package/dist/cli.js +20 -0
- package/dist/configuration/CommandLine.js +112 -0
- package/dist/configuration/Configuration.js +1 -0
- package/dist/configuration/ConfigurationValidator.js +79 -0
- package/dist/configuration/Option.js +1 -0
- package/dist/configuration/OptionValidationError.js +15 -0
- package/dist/configuration/indexedOptions.js +13 -0
- package/dist/configuration/options.js +191 -0
- package/dist/configuration/validators/OptionValidator.js +1 -0
- package/dist/configuration/validators/boolean.js +15 -0
- package/dist/configuration/validators/browser.js +11 -0
- package/dist/configuration/validators/fsEntry.js +70 -0
- package/dist/configuration/validators/index.js +20 -0
- package/dist/configuration/validators/integer.js +10 -0
- package/dist/configuration/validators/percent.js +17 -0
- package/dist/configuration/validators/regexp.js +20 -0
- package/dist/configuration/validators/string.js +7 -0
- package/dist/configuration/validators/timeout.js +24 -0
- package/dist/configuration/validators/url.js +8 -0
- package/dist/modes/ModeFunction.js +1 -0
- package/dist/modes/Modes.js +9 -0
- package/dist/modes/execute.js +27 -0
- package/dist/modes/help.js +3 -0
- package/dist/modes/log/ILogStorage.js +1 -0
- package/dist/modes/log/LogMetrics.js +9 -0
- package/dist/modes/log/LogReader.js +37 -0
- package/dist/modes/log/LogStorage.js +68 -0
- package/dist/modes/log/REserve.js +101 -0
- package/dist/modes/log/index.js +58 -0
- package/dist/modes/test/REserve.js +31 -0
- package/dist/modes/test/agent.js +8 -0
- package/dist/modes/test/browser.js +37 -0
- package/dist/modes/test/index.js +66 -0
- package/dist/modes/test/pageTask.js +145 -0
- package/dist/modes/test/report.js +3 -0
- package/dist/modes/test/server.js +109 -0
- package/dist/modes/version.js +11 -0
- package/dist/platform/Exit.js +139 -0
- package/dist/platform/FileSystem.js +13 -0
- package/dist/platform/Host.js +10 -0
- package/dist/platform/Http.js +38 -0
- package/dist/platform/Path.js +5 -0
- package/dist/platform/Process.js +133 -0
- package/dist/platform/Terminal.js +47 -0
- package/dist/platform/Thread.js +43 -0
- package/dist/platform/ZLib.js +7 -0
- package/dist/platform/assert.js +17 -0
- package/dist/platform/constants.js +5 -0
- package/dist/platform/environment.js +28 -0
- package/dist/platform/index.js +13 -0
- package/dist/platform/logger/ILogger.js +1 -0
- package/dist/platform/logger/allCompressed.js +54 -0
- package/dist/platform/logger/compress.js +277 -0
- package/dist/platform/logger/output/BaseLoggerOutput.js +158 -0
- package/dist/platform/logger/output/InteractiveLoggerOutput.js +102 -0
- package/dist/platform/logger/output/StaticLoggerOutput.js +32 -0
- package/dist/platform/logger/output/factory.js +10 -0
- package/dist/platform/logger/output.js +58 -0
- package/dist/platform/logger/proxy.js +6 -0
- package/dist/platform/logger/toInternalLogAttributes.js +22 -0
- package/dist/platform/logger/types.js +7 -0
- package/dist/platform/logger.js +138 -0
- package/dist/platform/mock.js +104 -0
- package/dist/platform/version.js +8 -0
- package/dist/platform/workerBootstrap.js +21 -0
- package/dist/reports/html.js +46 -0
- package/dist/types/AgentState.js +1 -0
- package/dist/types/CommonTestReportFormat.js +50 -0
- package/dist/types/IError.js +1 -0
- package/dist/types/IUserInterfaceController.js +1 -0
- package/dist/types/typeUtilities.js +1 -0
- package/dist/ui/agent.js +3 -0
- package/dist/ui/html-report.js +2 -0
- package/dist/ui/lib.js +1 -0
- package/dist/ui/log-viewer.js +2 -0
- package/dist/utils/node/Folder.js +28 -0
- package/dist/utils/node/FramedStreamReader.js +86 -0
- package/dist/utils/node/FramedStreamWriter.js +27 -0
- package/dist/utils/shared/ProgressBar.js +43 -0
- package/dist/utils/shared/TestReportBuilder.js +48 -0
- package/dist/utils/shared/memoize.js +19 -0
- package/dist/utils/shared/object.js +8 -0
- package/dist/utils/shared/parallelize.js +59 -0
- package/dist/utils/shared/string.js +23 -0
- package/dist/utils/shared/toIError.js +17 -0
- package/package.json +73 -50
- package/.releaserc +0 -5
- package/index.js +0 -175
- package/jest.config.json +0 -31
- package/src/add-test-pages.js +0 -67
- package/src/batch.js +0 -214
- package/src/browsers.js +0 -319
- package/src/capabilities/index.js +0 -204
- package/src/capabilities/tests/basic/iframe.html +0 -8
- package/src/capabilities/tests/basic/index.html +0 -12
- package/src/capabilities/tests/basic/index.js +0 -20
- package/src/capabilities/tests/basic/ui5.html +0 -24
- package/src/capabilities/tests/dynamic-include/index.js +0 -21
- package/src/capabilities/tests/dynamic-include/mix.html +0 -11
- package/src/capabilities/tests/dynamic-include/one.html +0 -11
- package/src/capabilities/tests/dynamic-include/post.js +0 -3
- package/src/capabilities/tests/dynamic-include/test.js +0 -1
- package/src/capabilities/tests/dynamic-include/two.html +0 -11
- package/src/capabilities/tests/index.js +0 -16
- package/src/capabilities/tests/local-storage/index.html +0 -16
- package/src/capabilities/tests/local-storage/index.js +0 -21
- package/src/capabilities/tests/screenshot/index.html +0 -23
- package/src/capabilities/tests/screenshot/index.js +0 -24
- package/src/capabilities/tests/scripts/coverage.html +0 -32
- package/src/capabilities/tests/scripts/iframe.html +0 -18
- package/src/capabilities/tests/scripts/index.js +0 -59
- package/src/capabilities/tests/scripts/qunit.html +0 -22
- package/src/capabilities/tests/scripts/testsuite.html +0 -10
- package/src/capabilities/tests/scripts/testsuite.js +0 -8
- package/src/capabilities/tests/timeout/index.html +0 -21
- package/src/capabilities/tests/timeout/index.js +0 -19
- package/src/capabilities/tests/traces/index.html +0 -18
- package/src/capabilities/tests/traces/index.js +0 -81
- package/src/capabilities/tests/ui5/focus.html +0 -89
- package/src/capabilities/tests/ui5/index.js +0 -39
- package/src/capabilities/tests/ui5/language.html +0 -50
- package/src/capabilities/tests/ui5/timezone.html +0 -27
- package/src/clean.js +0 -22
- package/src/cors.js +0 -21
- package/src/coverage.js +0 -384
- package/src/csv-reader.js +0 -36
- package/src/csv-writer.js +0 -55
- package/src/defaults/.nycrc.json +0 -4
- package/src/defaults/browser.js +0 -217
- package/src/defaults/happy-dom.js +0 -123
- package/src/defaults/jsdom/compatibility.js +0 -163
- package/src/defaults/jsdom/debug.js +0 -23
- package/src/defaults/jsdom/resource-loader.js +0 -44
- package/src/defaults/jsdom/sap.ui.test.matchers.visible.js +0 -39
- package/src/defaults/jsdom.js +0 -95
- package/src/defaults/json-report.js +0 -36
- package/src/defaults/junit-xml-report.js +0 -90
- package/src/defaults/playwright.js +0 -142
- package/src/defaults/puppeteer.js +0 -124
- package/src/defaults/report/common.js +0 -38
- package/src/defaults/report/decompress.js +0 -19
- package/src/defaults/report/default.html +0 -99
- package/src/defaults/report/main.js +0 -69
- package/src/defaults/report/progress.js +0 -60
- package/src/defaults/report/styles.css +0 -66
- package/src/defaults/report.js +0 -91
- package/src/defaults/scan-ui5.js +0 -26
- package/src/defaults/selenium-webdriver/chrome.js +0 -39
- package/src/defaults/selenium-webdriver/edge.js +0 -24
- package/src/defaults/selenium-webdriver/firefox.js +0 -30
- package/src/defaults/selenium-webdriver.js +0 -129
- package/src/defaults/text-report.js +0 -108
- package/src/defaults/webdriverio.js +0 -80
- package/src/end.js +0 -62
- package/src/endpoints.js +0 -219
- package/src/error.js +0 -54
- package/src/get-job-progress.js +0 -78
- package/src/handle.js +0 -43
- package/src/if.js +0 -10
- package/src/inject/jest2qunit.js +0 -289
- package/src/inject/opa-iframe-coverage.js +0 -22
- package/src/inject/post.js +0 -141
- package/src/inject/qunit-hooks.js +0 -107
- package/src/inject/qunit-redirect.js +0 -65
- package/src/inject/ui5-coverage.js +0 -33
- package/src/job-mode.js +0 -65
- package/src/job.js +0 -493
- package/src/npm.js +0 -136
- package/src/options.js +0 -95
- package/src/output.js +0 -739
- package/src/parallelize.js +0 -63
- package/src/qunit-hooks.js +0 -219
- package/src/report.js +0 -89
- package/src/reserve.js +0 -25
- package/src/start.js +0 -133
- package/src/symbols.js +0 -8
- package/src/tests.js +0 -183
- package/src/timeout.js +0 -53
- package/src/tools.js +0 -179
- package/src/ui5.js +0 -199
- package/src/unhandled.js +0 -32
package/src/coverage.js
DELETED
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { join, dirname, isAbsolute, relative, sep } = require('path')
|
|
4
|
-
const { fork } = require('child_process')
|
|
5
|
-
const { cleanDir, createDir, filename, download, allocPromise } = require('./tools')
|
|
6
|
-
const { readdir, readFile, stat, writeFile, access, constants } = require('fs').promises
|
|
7
|
-
const { Readable } = require('stream')
|
|
8
|
-
const { getOutput, newProgress } = require('./output')
|
|
9
|
-
const { resolvePackage } = require('./npm')
|
|
10
|
-
const { promisify } = require('util')
|
|
11
|
-
const { UTRError } = require('./error')
|
|
12
|
-
const { $remoteOnLegacy } = require('./symbols')
|
|
13
|
-
|
|
14
|
-
const $nycSettingsPath = Symbol('nycSettingsPath')
|
|
15
|
-
const $coverageFileIndex = Symbol('coverageFileIndex')
|
|
16
|
-
const $coverageRemote = Symbol('coverageRemote')
|
|
17
|
-
|
|
18
|
-
let nycInstallationPath
|
|
19
|
-
let nycScript
|
|
20
|
-
|
|
21
|
-
async function setupNyc (job) {
|
|
22
|
-
if (!nycInstallationPath) {
|
|
23
|
-
nycInstallationPath = resolvePackage(job, 'nyc')
|
|
24
|
-
}
|
|
25
|
-
nycScript = join(await nycInstallationPath, 'bin/nyc.js')
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function nyc (job, ...args) {
|
|
29
|
-
const output = getOutput(job)
|
|
30
|
-
output.nyc(...args)
|
|
31
|
-
const childProcess = fork(nycScript, args, { stdio: 'pipe' })
|
|
32
|
-
output.monitor(childProcess)
|
|
33
|
-
const { promise, resolve } = allocPromise()
|
|
34
|
-
childProcess.on('close', resolve)
|
|
35
|
-
return promise
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function safeNyc (job, ...args) {
|
|
39
|
-
const code = await nyc(job, ...args)
|
|
40
|
-
if (code !== 0) {
|
|
41
|
-
const [command] = args
|
|
42
|
-
throw UTRError.NYC_FAILED(`nyc ${command} failed with code ${code}`)
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const globalContextSearch = 'var global=new Function("return this")();'
|
|
47
|
-
const globalContextReplace = 'var global=window.top;'
|
|
48
|
-
|
|
49
|
-
const customFileSystem = {
|
|
50
|
-
stat: path => stat(path)
|
|
51
|
-
.then(stats => {
|
|
52
|
-
stats.size -= globalContextSearch.length + globalContextReplace.length
|
|
53
|
-
return stats
|
|
54
|
-
}),
|
|
55
|
-
readdir,
|
|
56
|
-
createReadStream: async (path) => {
|
|
57
|
-
const buffer = (await readFile(path))
|
|
58
|
-
.toString()
|
|
59
|
-
.replace(globalContextSearch, globalContextReplace)
|
|
60
|
-
return Readable.from(buffer)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async function instrument (job) {
|
|
65
|
-
await setupNyc(job)
|
|
66
|
-
job[$nycSettingsPath] = join(job.coverageTempDir, 'settings/.nycrc.json')
|
|
67
|
-
await cleanDir(job.coverageTempDir)
|
|
68
|
-
await createDir(join(job.coverageTempDir, 'settings'))
|
|
69
|
-
const settings = JSON.parse((await readFile(job.coverageSettings)).toString())
|
|
70
|
-
settings.cwd = job.webapp
|
|
71
|
-
if (!settings.exclude) {
|
|
72
|
-
settings.exclude = []
|
|
73
|
-
}
|
|
74
|
-
settings.exclude.push(join(job.coverageTempDir, '**'))
|
|
75
|
-
if (job.cache) {
|
|
76
|
-
settings.exclude.push(join(job.cache, '**'))
|
|
77
|
-
}
|
|
78
|
-
settings.exclude.push(join(job.reportDir, '**'))
|
|
79
|
-
settings.exclude.push(join(job.coverageReportDir, '**'))
|
|
80
|
-
await writeFile(job[$nycSettingsPath], JSON.stringify(settings))
|
|
81
|
-
job.nycSettings = settings
|
|
82
|
-
if (job.mode === 'url') {
|
|
83
|
-
if (!job[$remoteOnLegacy]) {
|
|
84
|
-
job[$coverageRemote] = true
|
|
85
|
-
getOutput(job).instrumentationSkipped()
|
|
86
|
-
return
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
job.status = 'Instrumenting'
|
|
90
|
-
await safeNyc(job, 'instrument', job.webapp, join(job.coverageTempDir, 'instrumented'), '--nycrc-path', job[$nycSettingsPath])
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function getUrlOrigin (job) {
|
|
94
|
-
const { origin } = new URL(job.url[0])
|
|
95
|
-
if (job.url.some(url => new URL(url).origin !== origin)) {
|
|
96
|
-
getOutput(job).assumingOneOrigin()
|
|
97
|
-
}
|
|
98
|
-
return origin
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
async function buildAllIndex (job) {
|
|
102
|
-
async function scanFs (path, onFolder, onFile) {
|
|
103
|
-
const items = await readdir(path)
|
|
104
|
-
await onFolder(items.length)
|
|
105
|
-
for (const item of items) {
|
|
106
|
-
const itemPath = join(path, item)
|
|
107
|
-
const itemStat = await stat(itemPath)
|
|
108
|
-
if (itemStat.isDirectory()) {
|
|
109
|
-
await scanFs(itemPath, onFolder, onFile)
|
|
110
|
-
} else {
|
|
111
|
-
await onFile(itemPath, (await readFile(itemPath)).toString())
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const output = getOutput(job)
|
|
117
|
-
output.debug('coverage', 'Build index for all files...')
|
|
118
|
-
const progress = newProgress(job, 'Build index for all files', 1, 0)
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
const index = []
|
|
122
|
-
let scan
|
|
123
|
-
let start
|
|
124
|
-
if (job.mode === 'legacy' || job[$remoteOnLegacy]) {
|
|
125
|
-
scan = scanFs
|
|
126
|
-
start = join(job.coverageTempDir, 'instrumented')
|
|
127
|
-
} else {
|
|
128
|
-
scan = require(job.coverageRemoteScanner)
|
|
129
|
-
start = getUrlOrigin(job)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
await scan(
|
|
133
|
-
start,
|
|
134
|
-
count => {
|
|
135
|
-
progress.total += count
|
|
136
|
-
++progress.count
|
|
137
|
-
},
|
|
138
|
-
async (file, source) => {
|
|
139
|
-
if (file.endsWith('.js') || file.endsWith('.ts')) {
|
|
140
|
-
output.debug('coverage', file)
|
|
141
|
-
try {
|
|
142
|
-
const coverageData = source
|
|
143
|
-
.match(/coverageData\s*=\s*({[^;]*});/)[1]
|
|
144
|
-
.replace(/([^"])(\w+):/g, (_, before, name) => `${before}"${name}":`)
|
|
145
|
-
const [, coveragePath] = coverageData.match(/"path"\s*:\s*"([^"]+)"/)
|
|
146
|
-
const UNDEFINED = '__undefined__'
|
|
147
|
-
const validatedCoverageData = JSON.stringify(
|
|
148
|
-
JSON.parse(coverageData.replace(/\bundefined\b/g, `"${UNDEFINED}"`)),
|
|
149
|
-
(key, value) => {
|
|
150
|
-
if (value === UNDEFINED) {
|
|
151
|
-
return undefined
|
|
152
|
-
}
|
|
153
|
-
return value
|
|
154
|
-
}
|
|
155
|
-
)
|
|
156
|
-
index.push(`"${coveragePath}": ${validatedCoverageData}`)
|
|
157
|
-
} catch (e) {
|
|
158
|
-
output.debug('coverage', `Error when extracting all coverage for ${file}`, e)
|
|
159
|
-
}
|
|
160
|
-
} else {
|
|
161
|
-
output.debug('coverage', `Ignore all coverage for ${file}`)
|
|
162
|
-
}
|
|
163
|
-
++progress.count
|
|
164
|
-
}
|
|
165
|
-
)
|
|
166
|
-
if (index.length === 0) {
|
|
167
|
-
output.noInfoForAllCoverage()
|
|
168
|
-
} else {
|
|
169
|
-
await writeFile(join(job.coverageTempDir, 'all-index.json'), `{${index.join(',')}}`)
|
|
170
|
-
}
|
|
171
|
-
} catch (e) {
|
|
172
|
-
output.genericError(e, e.url)
|
|
173
|
-
output.noInfoForAllCoverage()
|
|
174
|
-
} finally {
|
|
175
|
-
progress.done()
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async function getReadableSource (job, pathOrUrl) {
|
|
180
|
-
if (isAbsolute(pathOrUrl)) {
|
|
181
|
-
try {
|
|
182
|
-
await access(pathOrUrl, constants.R_OK)
|
|
183
|
-
return pathOrUrl
|
|
184
|
-
} catch (e) {}
|
|
185
|
-
}
|
|
186
|
-
try {
|
|
187
|
-
const filePath = join(job.webapp, pathOrUrl)
|
|
188
|
-
await access(filePath, constants.R_OK)
|
|
189
|
-
return filePath
|
|
190
|
-
} catch (e) {}
|
|
191
|
-
try {
|
|
192
|
-
const origin = getUrlOrigin(job)
|
|
193
|
-
if (!job.coverageSourceDir) {
|
|
194
|
-
job.coverageSourceDir = join(job.coverageTempDir, 'sources')
|
|
195
|
-
}
|
|
196
|
-
const filePath = join(job.coverageSourceDir, pathOrUrl)
|
|
197
|
-
await download(origin + pathOrUrl, filePath)
|
|
198
|
-
return filePath
|
|
199
|
-
} catch (e) {}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
async function checkAllSourcesAreAvailable (job, coverageFilename) {
|
|
203
|
-
const output = getOutput(job)
|
|
204
|
-
job.status = 'Checking remote source files'
|
|
205
|
-
output.debug('coverage', 'Checking remote source files...')
|
|
206
|
-
const coverageData = require(coverageFilename)
|
|
207
|
-
const filenames = Object.keys(coverageData)
|
|
208
|
-
let changes = false
|
|
209
|
-
let basePath
|
|
210
|
-
for (const filename of filenames) {
|
|
211
|
-
const fileData = coverageData[filename]
|
|
212
|
-
const filePath = await getReadableSource(job, fileData.path)
|
|
213
|
-
if (!filePath) {
|
|
214
|
-
// TODO this will compromise coverage report generation
|
|
215
|
-
continue
|
|
216
|
-
}
|
|
217
|
-
if (filePath && filePath !== fileData.path) {
|
|
218
|
-
fileData.path = filePath
|
|
219
|
-
changes = true
|
|
220
|
-
}
|
|
221
|
-
if (filename !== filePath) {
|
|
222
|
-
delete coverageData[filename]
|
|
223
|
-
coverageData[filePath] = fileData
|
|
224
|
-
changes = true
|
|
225
|
-
}
|
|
226
|
-
const fileFolder = dirname(filePath)
|
|
227
|
-
if (basePath === undefined) {
|
|
228
|
-
basePath = fileFolder
|
|
229
|
-
} else {
|
|
230
|
-
const diff = relative(basePath, fileFolder).split(sep)
|
|
231
|
-
while (diff.shift() === '..') {
|
|
232
|
-
basePath = dirname(basePath)
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
if (basePath !== job.nycSettings.cwd) {
|
|
237
|
-
job.nycSettings.cwd = basePath
|
|
238
|
-
await writeFile(job[$nycSettingsPath], JSON.stringify(job.nycSettings))
|
|
239
|
-
}
|
|
240
|
-
if (changes) {
|
|
241
|
-
await writeFile(coverageFilename, JSON.stringify(coverageData))
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
async function generateCoverageReport (job) {
|
|
246
|
-
job.status = 'Generating coverage report'
|
|
247
|
-
if (job.nycSettings.all) {
|
|
248
|
-
await buildAllIndex(job)
|
|
249
|
-
}
|
|
250
|
-
const output = getOutput(job)
|
|
251
|
-
output.debug('coverage', 'Generating coverage report...')
|
|
252
|
-
await cleanDir(job.coverageReportDir)
|
|
253
|
-
const coverageMergedDir = join(job.coverageTempDir, 'merged')
|
|
254
|
-
await createDir(coverageMergedDir)
|
|
255
|
-
const coverageFilename = join(coverageMergedDir, 'coverage.json')
|
|
256
|
-
await safeNyc(job, 'merge', job.coverageTempDir, coverageFilename)
|
|
257
|
-
if (job[$coverageRemote]) {
|
|
258
|
-
await checkAllSourcesAreAvailable(job, coverageFilename)
|
|
259
|
-
}
|
|
260
|
-
const reporters = job.coverageReporters.map(reporter => `--reporter=${reporter}`)
|
|
261
|
-
if (!job.coverageReporters.includes('text')) {
|
|
262
|
-
reporters.push('--reporter=text')
|
|
263
|
-
}
|
|
264
|
-
const checks = []
|
|
265
|
-
if (job.coverageCheckBranches || job.coverageCheckFunctions || job.coverageCheckLines || job.coverageCheckStatements) {
|
|
266
|
-
if (!job.coverageReporters.includes('lcov')) {
|
|
267
|
-
reporters.push('--reporter=lcov')
|
|
268
|
-
}
|
|
269
|
-
checks.push(
|
|
270
|
-
`--branches=${job.coverageCheckBranches}`,
|
|
271
|
-
`--functions=${job.coverageCheckFunctions}`,
|
|
272
|
-
`--lines=${job.coverageCheckLines}`,
|
|
273
|
-
`--statements=${job.coverageCheckStatements}`,
|
|
274
|
-
'--check-coverage'
|
|
275
|
-
)
|
|
276
|
-
}
|
|
277
|
-
const returnCode = await nyc(job, 'report', ...reporters, ...checks, '--temp-dir', coverageMergedDir, '--report-dir', job.coverageReportDir, '--nycrc-path', job[$nycSettingsPath])
|
|
278
|
-
if (checks.length) {
|
|
279
|
-
// The checks are not triggered if the coverage is empty
|
|
280
|
-
const lcov = await stat(join(job.coverageReportDir, 'lcov.info'))
|
|
281
|
-
if (lcov.size === 0) {
|
|
282
|
-
throw UTRError.NYC_FAILED('No coverage information extracted')
|
|
283
|
-
}
|
|
284
|
-
if (returnCode === 1) {
|
|
285
|
-
// Assuming coverage report shows the error
|
|
286
|
-
output.debug('coverage', `nyc report failed with code ${returnCode}`)
|
|
287
|
-
job.failed = true
|
|
288
|
-
}
|
|
289
|
-
} else if (returnCode !== 0) {
|
|
290
|
-
throw UTRError.NYC_FAILED(`nyc report failed with code ${returnCode}`)
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
module.exports = {
|
|
295
|
-
instrument: job => job.coverage && instrument(job),
|
|
296
|
-
async collect (job, url, coverageData) {
|
|
297
|
-
if (!job.coverage) {
|
|
298
|
-
return
|
|
299
|
-
}
|
|
300
|
-
job[$coverageFileIndex] = (job[$coverageFileIndex] || 0) + 1
|
|
301
|
-
const coverageFileName = join(job.coverageTempDir, `${filename(url)}_${job[$coverageFileIndex]}.json`)
|
|
302
|
-
getOutput(job).debug('coverage', `saved coverage in '${coverageFileName}'`)
|
|
303
|
-
await writeFile(coverageFileName, JSON.stringify(coverageData))
|
|
304
|
-
},
|
|
305
|
-
generateCoverageReport: job => job.coverage ? generateCoverageReport(job) : Promise.resolve(),
|
|
306
|
-
mappings: async job => {
|
|
307
|
-
if (!job.coverage) {
|
|
308
|
-
return []
|
|
309
|
-
}
|
|
310
|
-
const instrumentedBasePath = join(job.coverageTempDir, 'instrumented')
|
|
311
|
-
const instrumentedMapping = {
|
|
312
|
-
match: /(.*\.js)(\?.*)?$/,
|
|
313
|
-
cwd: instrumentedBasePath,
|
|
314
|
-
file: '$1'
|
|
315
|
-
}
|
|
316
|
-
if (job.mode === 'legacy' || job[$remoteOnLegacy]) {
|
|
317
|
-
return [{
|
|
318
|
-
...instrumentedMapping,
|
|
319
|
-
'custom-file-system': job.debugCoverageNoCustomFs ? undefined : customFileSystem
|
|
320
|
-
}]
|
|
321
|
-
}
|
|
322
|
-
if (job.mode === 'url' && job.coverageProxy) {
|
|
323
|
-
await setupNyc(job)
|
|
324
|
-
// Assuming all files are coming from the same server
|
|
325
|
-
const { origin } = new URL(job.url[0])
|
|
326
|
-
let instrument
|
|
327
|
-
try {
|
|
328
|
-
const { createInstrumenter } = require(join(await nycInstallationPath, 'node_modules/istanbul-lib-instrument'))
|
|
329
|
-
const instrumenter = createInstrumenter({
|
|
330
|
-
produceSourceMap: true,
|
|
331
|
-
coverageGlobalScope: 'window.top',
|
|
332
|
-
coverageGlobalScopeFunc: false
|
|
333
|
-
})
|
|
334
|
-
instrument = promisify(instrumenter.instrument.bind(instrumenter))
|
|
335
|
-
} catch (e) {
|
|
336
|
-
// Recent version of nyc offers a different interface
|
|
337
|
-
const createInstrumenter = require(join(await nycInstallationPath, 'lib/instrumenters/istanbul.js'))
|
|
338
|
-
const instrumenter = createInstrumenter({
|
|
339
|
-
produceSourceMap: true
|
|
340
|
-
})
|
|
341
|
-
instrument = async function (code, sourcePath) {
|
|
342
|
-
return instrumenter.instrumentSync(code, sourcePath, { registerMap: () => {} })
|
|
343
|
-
// TODO use regular expression !
|
|
344
|
-
.replace(globalContextSearch, globalContextReplace)
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
const sources = {}
|
|
348
|
-
return [{
|
|
349
|
-
match: /(.*\.js)(\?.*)?$/,
|
|
350
|
-
custom: async (request, response, url) => {
|
|
351
|
-
if (!url.match(job.coverageProxyInclude) || url.match(job.coverageProxyExclude)) {
|
|
352
|
-
getOutput(job).debug('coverage', 'coverage_proxy ignore', url)
|
|
353
|
-
return
|
|
354
|
-
}
|
|
355
|
-
const instrumentedSourcePath = join(instrumentedBasePath, url)
|
|
356
|
-
try {
|
|
357
|
-
await access(instrumentedSourcePath, constants.R_OK)
|
|
358
|
-
return
|
|
359
|
-
} catch (e) {}
|
|
360
|
-
if (!sources[url]) {
|
|
361
|
-
sources[url] = (async () => {
|
|
362
|
-
const sourcePath = await getReadableSource(job, url)
|
|
363
|
-
getOutput(job).debug('coverage', 'coverage_proxy instrument', url, sourcePath)
|
|
364
|
-
if (sourcePath) {
|
|
365
|
-
const source = (await readFile(sourcePath)).toString()
|
|
366
|
-
const instrumentedSource = await instrument(source, sourcePath)
|
|
367
|
-
await createDir(dirname(instrumentedSourcePath))
|
|
368
|
-
await writeFile(instrumentedSourcePath, instrumentedSource)
|
|
369
|
-
delete sources[url]
|
|
370
|
-
}
|
|
371
|
-
})()
|
|
372
|
-
}
|
|
373
|
-
await sources[url]
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
instrumentedMapping,
|
|
377
|
-
{
|
|
378
|
-
match: /(.*)$/,
|
|
379
|
-
url: `${origin}$1`
|
|
380
|
-
}]
|
|
381
|
-
}
|
|
382
|
-
return []
|
|
383
|
-
}
|
|
384
|
-
}
|
package/src/csv-reader.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { createReadStream } = require('fs')
|
|
4
|
-
const readline = require('readline')
|
|
5
|
-
|
|
6
|
-
const unescape = value => {
|
|
7
|
-
if (value.startsWith('"') && value.endsWith('"')) {
|
|
8
|
-
return JSON.parse(value)
|
|
9
|
-
}
|
|
10
|
-
return value
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async function * buildCsvReader (fileName) {
|
|
14
|
-
const fileStream = createReadStream(fileName)
|
|
15
|
-
const rl = readline.createInterface({
|
|
16
|
-
input: fileStream,
|
|
17
|
-
crlfDelay: Infinity
|
|
18
|
-
})
|
|
19
|
-
let headers
|
|
20
|
-
for await (const line of rl) {
|
|
21
|
-
const fields = line.split('\t')
|
|
22
|
-
if (headers === undefined) {
|
|
23
|
-
headers = fields
|
|
24
|
-
continue
|
|
25
|
-
}
|
|
26
|
-
const record = {}
|
|
27
|
-
headers.forEach((field, index) => {
|
|
28
|
-
record[field] = unescape(fields[index])
|
|
29
|
-
})
|
|
30
|
-
yield record
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
module.exports = {
|
|
35
|
-
buildCsvReader
|
|
36
|
-
}
|
package/src/csv-writer.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { writeFile } = require('fs/promises')
|
|
4
|
-
|
|
5
|
-
const append = (fileName, line) => writeFile(fileName, line + '\n', { flag: 'a+' })
|
|
6
|
-
const escape = value => {
|
|
7
|
-
if (value === undefined) {
|
|
8
|
-
return '❓'
|
|
9
|
-
}
|
|
10
|
-
const stringValue = value.toString()
|
|
11
|
-
if (stringValue.match(/\r|\n|\t|"/)) {
|
|
12
|
-
return JSON.stringify(stringValue)
|
|
13
|
-
}
|
|
14
|
-
return stringValue
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class CsvWriter {
|
|
18
|
-
#fileName
|
|
19
|
-
#ready
|
|
20
|
-
#fields
|
|
21
|
-
|
|
22
|
-
constructor (fileName) {
|
|
23
|
-
this.#fileName = fileName
|
|
24
|
-
this.#ready = Promise.resolve()
|
|
25
|
-
this.#fields = []
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get ready () {
|
|
29
|
-
return this.#ready
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
append (records) {
|
|
33
|
-
if (!Array.isArray(records)) {
|
|
34
|
-
records = [records]
|
|
35
|
-
}
|
|
36
|
-
if (this.#fields.length === 0) {
|
|
37
|
-
this.#fields = Object.keys(records[0]).filter(name => name !== 'timestamp')
|
|
38
|
-
this.#ready = this.#ready.then(() => append(this.#fileName, `timestamp\t${this.#fields.join('\t')}`))
|
|
39
|
-
}
|
|
40
|
-
const lines = records.map(record => {
|
|
41
|
-
const { timestamp = Date.now() } = record
|
|
42
|
-
return [
|
|
43
|
-
timestamp,
|
|
44
|
-
...this.#fields.map(name => escape(record[name]))
|
|
45
|
-
].join('\t')
|
|
46
|
-
}).join('\n')
|
|
47
|
-
this.#ready = this.#ready.then(() => append(this.#fileName, lines))
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
module.exports = {
|
|
52
|
-
buildCsvWriter (fileName) {
|
|
53
|
-
return new CsvWriter(fileName)
|
|
54
|
-
}
|
|
55
|
-
}
|
package/src/defaults/.nycrc.json
DELETED
package/src/defaults/browser.js
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
const { readFile, writeFile } = require('fs/promises')
|
|
2
|
-
const { join } = require('path')
|
|
3
|
-
const { Command, InvalidArgumentError } = require('commander')
|
|
4
|
-
const { buildCsvWriter } = require('../csv-writer')
|
|
5
|
-
const { any, arrayOf, boolean, integer, string } = require('../options')
|
|
6
|
-
|
|
7
|
-
const noop = () => { }
|
|
8
|
-
|
|
9
|
-
module.exports = ({
|
|
10
|
-
metadata,
|
|
11
|
-
flush = noop,
|
|
12
|
-
beforeExit = noop,
|
|
13
|
-
screenshot,
|
|
14
|
-
capabilities: computeCapabilities,
|
|
15
|
-
run,
|
|
16
|
-
error = noop
|
|
17
|
-
}) => {
|
|
18
|
-
const command = new Command()
|
|
19
|
-
command
|
|
20
|
-
.name(`ui5-test-runner/@/${metadata.name}`)
|
|
21
|
-
.description(`Browser instantiation command for ${metadata.name}`)
|
|
22
|
-
.helpOption(false)
|
|
23
|
-
metadata.options
|
|
24
|
-
.map(option => {
|
|
25
|
-
if (option[0] === 'browser') {
|
|
26
|
-
const [, ...browsers] = option
|
|
27
|
-
return [[
|
|
28
|
-
'-b, --browser <name>', 'Browser driver',
|
|
29
|
-
function (value) {
|
|
30
|
-
if (value === undefined) {
|
|
31
|
-
return browsers[0]
|
|
32
|
-
}
|
|
33
|
-
if (!browsers.includes(value)) {
|
|
34
|
-
throw new InvalidArgumentError('Browser name')
|
|
35
|
-
}
|
|
36
|
-
return value
|
|
37
|
-
},
|
|
38
|
-
browsers[0]
|
|
39
|
-
]]
|
|
40
|
-
}
|
|
41
|
-
if (option === 'binary') {
|
|
42
|
-
return [['--binary <binary>', 'Binary path']]
|
|
43
|
-
}
|
|
44
|
-
if (option === 'visible') {
|
|
45
|
-
return [['--visible [flag]', 'Show the browser', false]]
|
|
46
|
-
}
|
|
47
|
-
if (option === 'viewport') {
|
|
48
|
-
return [
|
|
49
|
-
['-w, --viewport-width <width>', 'Viewport width', 1920],
|
|
50
|
-
['-h, --viewport-height <height>', 'Viewport height', 1080]
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
if (option === 'language') {
|
|
54
|
-
return [['-l, --language <lang...>', 'Language(s) (see rfc5646)', arrayOf(string, true), ['en-US']]]
|
|
55
|
-
}
|
|
56
|
-
if (option === 'unsecure') {
|
|
57
|
-
return [['-u, --unsecure', 'Disable security features', false]]
|
|
58
|
-
}
|
|
59
|
-
return [option]
|
|
60
|
-
})
|
|
61
|
-
.flat()
|
|
62
|
-
.forEach(([label, description, parser, defaultValue]) => {
|
|
63
|
-
if (defaultValue === undefined && typeof parser !== 'function') {
|
|
64
|
-
defaultValue = parser
|
|
65
|
-
if (typeof defaultValue === 'number') {
|
|
66
|
-
parser = integer
|
|
67
|
-
} else if (typeof defaultValue === 'boolean') {
|
|
68
|
-
parser = boolean
|
|
69
|
-
} else {
|
|
70
|
-
parser = any
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
command.option(label, description, parser, defaultValue)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
const append = () => { }
|
|
77
|
-
let consoleWriter = { ready: Promise.resolve(), append }
|
|
78
|
-
let networkWriter = { ready: Promise.resolve(), append }
|
|
79
|
-
|
|
80
|
-
let stopping = false
|
|
81
|
-
let settings
|
|
82
|
-
let options
|
|
83
|
-
|
|
84
|
-
async function exit (code) {
|
|
85
|
-
if (stopping) {
|
|
86
|
-
return
|
|
87
|
-
}
|
|
88
|
-
stopping = true
|
|
89
|
-
if (settings && typeof settings.capabilities !== 'string' && settings.capabilities.traces.length) {
|
|
90
|
-
try {
|
|
91
|
-
await flush({
|
|
92
|
-
settings,
|
|
93
|
-
options,
|
|
94
|
-
consoleWriter,
|
|
95
|
-
networkWriter
|
|
96
|
-
})
|
|
97
|
-
} catch (e) {
|
|
98
|
-
console.error('[exit:flush]', e)
|
|
99
|
-
code = -3
|
|
100
|
-
}
|
|
101
|
-
await Promise.all([consoleWriter.ready, networkWriter.ready])
|
|
102
|
-
}
|
|
103
|
-
try {
|
|
104
|
-
await beforeExit({
|
|
105
|
-
settings,
|
|
106
|
-
options
|
|
107
|
-
})
|
|
108
|
-
} catch (e) {
|
|
109
|
-
console.error('[exit:beforeExit]', e)
|
|
110
|
-
// but ignore
|
|
111
|
-
}
|
|
112
|
-
process.exit(code)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
process.on('message', async message => {
|
|
116
|
-
const { command } = message
|
|
117
|
-
try {
|
|
118
|
-
if (command === 'stop') {
|
|
119
|
-
await exit(0)
|
|
120
|
-
} else if (command === 'screenshot') {
|
|
121
|
-
if (settings.capabilities.screenshot && screenshot && await screenshot({
|
|
122
|
-
settings,
|
|
123
|
-
options,
|
|
124
|
-
filename: message.filename
|
|
125
|
-
})) {
|
|
126
|
-
process.send(message)
|
|
127
|
-
} else {
|
|
128
|
-
throw new Error('screenshot command failed')
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
} catch (e) {
|
|
132
|
-
console.error(e)
|
|
133
|
-
exit(-2)
|
|
134
|
-
}
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
if (process.argv[2] === 'test') {
|
|
138
|
-
command.parse(process.argv.slice(3), { from: 'user' })
|
|
139
|
-
console.log(command.opts(), command.args)
|
|
140
|
-
return exit(0)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (process.argv.length !== 3) {
|
|
144
|
-
command.outputHelp()
|
|
145
|
-
return exit(0)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async function main () {
|
|
149
|
-
settings = JSON.parse((await readFile(process.argv[2])).toString())
|
|
150
|
-
command.parse(settings.args, { from: 'user' })
|
|
151
|
-
options = command.opts()
|
|
152
|
-
|
|
153
|
-
options.chromeArgs = function () {
|
|
154
|
-
const args = [
|
|
155
|
-
'true', // Not sure why but this changes the behavior of the browser
|
|
156
|
-
'--start-maximized',
|
|
157
|
-
'--no-sandbox',
|
|
158
|
-
'--disable-gpu',
|
|
159
|
-
'--disable-extensions',
|
|
160
|
-
'--log-level=3',
|
|
161
|
-
`--window-size=${options.viewportWidth},${options.viewportHeight}`
|
|
162
|
-
]
|
|
163
|
-
if (options.language) {
|
|
164
|
-
args.push(`--lang=${options.language.join(',')}`)
|
|
165
|
-
}
|
|
166
|
-
if (!options.visible) {
|
|
167
|
-
args.push('--headless=new')
|
|
168
|
-
}
|
|
169
|
-
if (options.unsecure) {
|
|
170
|
-
args.push(
|
|
171
|
-
'--ignore-certificate-errors',
|
|
172
|
-
'--disable-web-security',
|
|
173
|
-
'--disable-features=IsolateOrigins',
|
|
174
|
-
'--disable-features=BlockInsecurePrivateNetworkRequests',
|
|
175
|
-
'--disable-site-isolation-trials'
|
|
176
|
-
)
|
|
177
|
-
}
|
|
178
|
-
return args.concat(command.args)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (typeof settings.capabilities === 'string') {
|
|
182
|
-
let capabilities
|
|
183
|
-
if (computeCapabilities !== undefined) {
|
|
184
|
-
capabilities = await computeCapabilities({ settings, options })
|
|
185
|
-
} else {
|
|
186
|
-
capabilities = metadata.capabilities
|
|
187
|
-
}
|
|
188
|
-
await writeFile(settings.capabilities, JSON.stringify(capabilities, undefined, 2))
|
|
189
|
-
return exit(0)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
consoleWriter = buildCsvWriter(join(settings.dir, 'console.csv'))
|
|
193
|
-
networkWriter = buildCsvWriter(join(settings.dir, 'network.csv'))
|
|
194
|
-
|
|
195
|
-
await run({
|
|
196
|
-
settings,
|
|
197
|
-
options,
|
|
198
|
-
consoleWriter,
|
|
199
|
-
networkWriter,
|
|
200
|
-
exit
|
|
201
|
-
})
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
main()
|
|
205
|
-
.catch(async e => {
|
|
206
|
-
if (!stopping) {
|
|
207
|
-
await error({
|
|
208
|
-
settings,
|
|
209
|
-
options,
|
|
210
|
-
error: e,
|
|
211
|
-
exit
|
|
212
|
-
})
|
|
213
|
-
console.error(e)
|
|
214
|
-
}
|
|
215
|
-
exit(-1)
|
|
216
|
-
})
|
|
217
|
-
}
|