ui5-test-runner 5.5.1 โ 5.6.0
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/package.json +1 -1
- package/src/batch.js +37 -17
- package/src/browsers.js +6 -2
- package/src/capabilities/tests/ui5/timezone.html +27 -0
- package/src/end.js +5 -1
- package/src/job.js +18 -1
- package/src/output.js +1 -1
- package/src/report.js +22 -2
- package/src/start.js +6 -2
- package/src/timeout.js +2 -2
package/package.json
CHANGED
package/src/batch.js
CHANGED
|
@@ -7,6 +7,8 @@ const { parallelize } = require('./parallelize')
|
|
|
7
7
|
const { $statusProgressCount } = require('./symbols')
|
|
8
8
|
const { $valueSources } = require('./symbols')
|
|
9
9
|
const { getCommand, toLongName } = require('./job')
|
|
10
|
+
const { save } = require('./report')
|
|
11
|
+
const { end } = require('./end')
|
|
10
12
|
|
|
11
13
|
const batchParameters = getCommand('.').options
|
|
12
14
|
.filter(option => option.description.includes('๐ก'))
|
|
@@ -17,10 +19,9 @@ const batchParameters = getCommand('.').options
|
|
|
17
19
|
|
|
18
20
|
const root = join(__dirname, '..')
|
|
19
21
|
|
|
20
|
-
const folder = (
|
|
22
|
+
const folder = (job, folderPath) => {
|
|
21
23
|
getOutput(job).debug('batch', `adding folder: ${folderPath}`)
|
|
22
|
-
batchItems.push({
|
|
23
|
-
job,
|
|
24
|
+
job.batchItems.push({
|
|
24
25
|
path: folderPath,
|
|
25
26
|
id: filename(folderPath),
|
|
26
27
|
label: folderPath,
|
|
@@ -28,15 +29,14 @@ const folder = (batchItems, job, folderPath) => {
|
|
|
28
29
|
})
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
const configurationFile = (
|
|
32
|
+
const configurationFile = (job, configurationFilePath) => {
|
|
32
33
|
getOutput(job).debug('batch', `adding configuration file: ${configurationFilePath}`)
|
|
33
34
|
try {
|
|
34
35
|
const {
|
|
35
36
|
batchId: id = filename(configurationFilePath),
|
|
36
37
|
batchLabel: label = configurationFilePath
|
|
37
38
|
} = require(configurationFilePath)
|
|
38
|
-
batchItems.push({
|
|
39
|
-
job,
|
|
39
|
+
job.batchItems.push({
|
|
40
40
|
path: configurationFilePath,
|
|
41
41
|
id,
|
|
42
42
|
label,
|
|
@@ -47,7 +47,10 @@ const configurationFile = (batchItems, job, configurationFilePath) => {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
const task = async (
|
|
50
|
+
const task = async function (batchItem) {
|
|
51
|
+
const { id, label, args } = batchItem
|
|
52
|
+
batchItem.start = new Date()
|
|
53
|
+
const job = this
|
|
51
54
|
const output = getOutput(job)
|
|
52
55
|
const progress = newProgress(job)
|
|
53
56
|
const reportDir = join(job.reportDir, id)
|
|
@@ -73,7 +76,11 @@ const task = async ({ job, id, label, args }) => {
|
|
|
73
76
|
if (option) {
|
|
74
77
|
parameters.push(`--${longName}`)
|
|
75
78
|
if (!option.optional && !option.negate) {
|
|
76
|
-
if (
|
|
79
|
+
if (name === 'env') {
|
|
80
|
+
Object.keys(job.env).forEach(key => {
|
|
81
|
+
parameters.push(`${key}=${job.env[key]}`)
|
|
82
|
+
})
|
|
83
|
+
} else if (option.variadic) {
|
|
77
84
|
parameters.push(...job[name].map(value => value.toString()))
|
|
78
85
|
} else {
|
|
79
86
|
parameters.push(job[name].toString())
|
|
@@ -104,6 +111,8 @@ const task = async ({ job, id, label, args }) => {
|
|
|
104
111
|
childProcess.on('close', async code => {
|
|
105
112
|
await stdout.close()
|
|
106
113
|
await stderr.close()
|
|
114
|
+
batchItem.statusCode = code
|
|
115
|
+
batchItem.end = new Date()
|
|
107
116
|
if (code !== 0) {
|
|
108
117
|
reject(code)
|
|
109
118
|
} else {
|
|
@@ -116,7 +125,7 @@ const task = async ({ job, id, label, args }) => {
|
|
|
116
125
|
.then(() => {
|
|
117
126
|
output.log('โ๏ธ ', progress.label)
|
|
118
127
|
}, (reason) => {
|
|
119
|
-
++job.
|
|
128
|
+
++job.failed
|
|
120
129
|
output.log('โ', progress.label, reason)
|
|
121
130
|
})
|
|
122
131
|
.finally(() => {
|
|
@@ -135,7 +144,9 @@ async function batch (job) {
|
|
|
135
144
|
* --report-dir is always passed to aggregate reports under one root folder
|
|
136
145
|
*/
|
|
137
146
|
const output = getOutput(job)
|
|
138
|
-
|
|
147
|
+
job.start = new Date()
|
|
148
|
+
job.failed = 0
|
|
149
|
+
job.batchItems = []
|
|
139
150
|
for (const batch of job.batch) {
|
|
140
151
|
output.debug('batch', `processing: ${batch}`)
|
|
141
152
|
// check if path
|
|
@@ -146,9 +157,9 @@ async function batch (job) {
|
|
|
146
157
|
}
|
|
147
158
|
const pathStat = await stat(path)
|
|
148
159
|
if (pathStat.isDirectory()) {
|
|
149
|
-
folder(
|
|
160
|
+
folder(job, path)
|
|
150
161
|
} else if (pathStat.isFile() && extname(path) === '.json') {
|
|
151
|
-
configurationFile(
|
|
162
|
+
configurationFile(job, path)
|
|
152
163
|
} else {
|
|
153
164
|
output.batchFailed(batch, 'only folders and JSON configuration files are supported')
|
|
154
165
|
}
|
|
@@ -171,24 +182,33 @@ async function batch (job) {
|
|
|
171
182
|
const pathStat = await stat(path)
|
|
172
183
|
if (pathStat.isDirectory()) {
|
|
173
184
|
if (re.test(path) || re.test(path.replaceAll('\\', '/'))) {
|
|
174
|
-
folder(
|
|
185
|
+
folder(job, path)
|
|
175
186
|
continue
|
|
176
187
|
}
|
|
177
188
|
await scan(path)
|
|
178
189
|
} else if (pathStat.isFile() && (re.test(path) || re.test(path.replaceAll('\\', '/')))) {
|
|
179
|
-
configurationFile(
|
|
190
|
+
configurationFile(job, path)
|
|
180
191
|
}
|
|
181
192
|
}
|
|
182
193
|
}
|
|
183
194
|
await scan(job.cwd)
|
|
184
195
|
}
|
|
185
|
-
if (batchItems.length) {
|
|
196
|
+
if (job.batchItems.length) {
|
|
186
197
|
job.status = 'Running batch items...'
|
|
187
|
-
await parallelize(task, batchItems, job.parallel)
|
|
188
|
-
// TODO: end command ?
|
|
198
|
+
await parallelize(task.bind(job), job.batchItems, job.parallel)
|
|
189
199
|
} else {
|
|
190
200
|
output.batchFailed(job.batch, 'no match')
|
|
191
201
|
}
|
|
202
|
+
|
|
203
|
+
job.end = new Date()
|
|
204
|
+
job.failed = !!job.failed
|
|
205
|
+
if (job.failed) {
|
|
206
|
+
process.exitCode = -1
|
|
207
|
+
}
|
|
208
|
+
await save(job)
|
|
209
|
+
if (job.endScript) {
|
|
210
|
+
await end(job)
|
|
211
|
+
}
|
|
192
212
|
output.stop()
|
|
193
213
|
return 0
|
|
194
214
|
}
|
package/src/browsers.js
CHANGED
|
@@ -29,7 +29,11 @@ async function instantiate (job, config) {
|
|
|
29
29
|
const stdout = await open(stdoutFilename, 'w')
|
|
30
30
|
const stderr = await open(stderrFilename, 'w')
|
|
31
31
|
const childProcess = fork(job.browser, [browserConfigPath], {
|
|
32
|
-
stdio: [0, stdout, stderr, 'ipc']
|
|
32
|
+
stdio: [0, stdout, stderr, 'ipc'],
|
|
33
|
+
env: {
|
|
34
|
+
...process.env,
|
|
35
|
+
...job.env
|
|
36
|
+
}
|
|
33
37
|
})
|
|
34
38
|
const { promise, resolve } = allocPromise()
|
|
35
39
|
childProcess.on('close', async code => {
|
|
@@ -127,7 +131,7 @@ async function start (job, url, scripts = []) {
|
|
|
127
131
|
}
|
|
128
132
|
if (resolvedScripts.length) {
|
|
129
133
|
resolvedScripts.unshift(`(function () {
|
|
130
|
-
window['ui5-test-runner/base-host'] = 'http
|
|
134
|
+
window['ui5-test-runner/base-host'] = 'http://${job.callbackHost}:${job.port}'
|
|
131
135
|
}())`)
|
|
132
136
|
}
|
|
133
137
|
const progress = newProgress(job, url)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<script id='sap-ui-bootstrap'
|
|
7
|
+
src='https://ui5.sap.com/resources/sap-ui-core.js'
|
|
8
|
+
data-sap-ui-libs='sap.m'
|
|
9
|
+
data-sap-ui-theme='sap_horizon'
|
|
10
|
+
data-sap-ui-compatVersion='edge'>
|
|
11
|
+
</script>
|
|
12
|
+
<style>
|
|
13
|
+
html, body { height: 100%; }
|
|
14
|
+
</style>
|
|
15
|
+
<script>
|
|
16
|
+
sap.ui.require([
|
|
17
|
+
"sap/ui/core/date/UI5Date",
|
|
18
|
+
], function (UI5Date) {
|
|
19
|
+
console.log(UI5Date.getInstance(2025,2,15,23,2,0))
|
|
20
|
+
});
|
|
21
|
+
</script>
|
|
22
|
+
</head>
|
|
23
|
+
<body class='sapUiBody'>
|
|
24
|
+
<pre>TZ=UTC node . --webapp . --url http://localhost:0/src/capabilities/tests/ui5/timezone.html --debug-keep-browser-open -- --visible</pre>
|
|
25
|
+
and check the console
|
|
26
|
+
</body>
|
|
27
|
+
</html>
|
package/src/end.js
CHANGED
package/src/job.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { Command, Option, InvalidArgumentError } = require('commander')
|
|
4
4
|
const { statSync, accessSync, constants } = require('fs')
|
|
5
5
|
const { dirname, join, isAbsolute } = require('path')
|
|
6
|
-
const { name, description, version } = require(join(__dirname, '../package.json'))
|
|
6
|
+
const { name, description, version = 'dev' } = require(join(__dirname, '../package.json'))
|
|
7
7
|
const { getOutput } = require('./output')
|
|
8
8
|
const { $valueSources, $remoteOnLegacy } = require('./symbols')
|
|
9
9
|
const { buildAndCheckMode } = require('./job-mode')
|
|
@@ -79,6 +79,7 @@ function getCommand (cwd) {
|
|
|
79
79
|
|
|
80
80
|
const DEBUG_OPTION = '(๐ for debugging purpose)'
|
|
81
81
|
const EXPERIMENTAL_OPTION = '[โ ๏ธ experimental]'
|
|
82
|
+
const DANGEROURS_OPTION = '[๐ฃ use carefully]'
|
|
82
83
|
|
|
83
84
|
command
|
|
84
85
|
.name(name)
|
|
@@ -110,6 +111,8 @@ function getCommand (cwd) {
|
|
|
110
111
|
.option('-br, --browser-retry <count>', '[๐ป๐๐งช๐ก] Browser instantiation retries : if the command fails unexpectedly, it is re-executed (0 means no retry)', 1)
|
|
111
112
|
.option('-oi, --output-interval <interval>', '[๐ป๐๐งช๐ก] Interval for reporting progress on non interactive output (CI/CD) (0 means no output)', timeout, 30000)
|
|
112
113
|
.option('--offline [flag]', '[๐ป๐๐งช๐ก] Limit network usage (implies --no-npm-install)', boolean, false)
|
|
114
|
+
.option('--env <name=value...>', '[๐ป๐๐งช๐ก] Set environment variable', arrayOf(string))
|
|
115
|
+
.option('--callback-host <host>', `[๐ป๐๐งช๐ก] ${DANGEROURS_OPTION} Hostname for callbacks`, string, 'localhost')
|
|
113
116
|
|
|
114
117
|
// Common to legacy and url
|
|
115
118
|
.option('--webapp <path>', '[๐ป๐] Base folder of the web application (relative to cwd)', 'webapp')
|
|
@@ -299,6 +302,20 @@ function finalize (job) {
|
|
|
299
302
|
})
|
|
300
303
|
}
|
|
301
304
|
|
|
305
|
+
if (!job.env) {
|
|
306
|
+
job.env = {}
|
|
307
|
+
} else {
|
|
308
|
+
job.env = job.env.reduce((dictionary, env) => {
|
|
309
|
+
const equalPos = env.indexOf('=')
|
|
310
|
+
if (equalPos === -1) {
|
|
311
|
+
dictionary[env] = ''
|
|
312
|
+
} else {
|
|
313
|
+
dictionary[env.slice(0, equalPos)] = env.slice(equalPos + 1)
|
|
314
|
+
}
|
|
315
|
+
return dictionary
|
|
316
|
+
}, {})
|
|
317
|
+
}
|
|
318
|
+
|
|
302
319
|
if (job.watchFolder) {
|
|
303
320
|
job.watch = true
|
|
304
321
|
job.watchFolder = updateToAbsolute(job.watchFolder)
|
package/src/output.js
CHANGED
|
@@ -265,7 +265,7 @@ function build (job) {
|
|
|
265
265
|
lines: 0,
|
|
266
266
|
|
|
267
267
|
version: () => {
|
|
268
|
-
const { name, version } = require(join(__dirname, '../package.json'))
|
|
268
|
+
const { name, version = 'dev' } = require(join(__dirname, '../package.json'))
|
|
269
269
|
log(job, p80()`${name}@${version}`)
|
|
270
270
|
if (job.debugDevMode) {
|
|
271
271
|
log(job, p80()`โ ๏ธ Development mode โ ๏ธ`)
|
package/src/report.js
CHANGED
|
@@ -22,7 +22,17 @@ async function save (job) {
|
|
|
22
22
|
|
|
23
23
|
function generateTextReport (job) {
|
|
24
24
|
const { promise, resolve } = allocPromise()
|
|
25
|
-
const childProcess = fork(
|
|
25
|
+
const childProcess = fork(
|
|
26
|
+
join(__dirname, 'defaults/text-report.js'),
|
|
27
|
+
[job.reportDir, process.stdout.columns || ''],
|
|
28
|
+
{
|
|
29
|
+
stdio: 'pipe',
|
|
30
|
+
env: {
|
|
31
|
+
...process.env,
|
|
32
|
+
...job.env
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
)
|
|
26
36
|
getOutput(job).monitor(childProcess, true)
|
|
27
37
|
childProcess.on('close', resolve)
|
|
28
38
|
return promise
|
|
@@ -41,7 +51,17 @@ module.exports = {
|
|
|
41
51
|
await generateTextReport(job)
|
|
42
52
|
const promises = job.reportGenerator.map(generator => {
|
|
43
53
|
const { promise, resolve } = allocPromise()
|
|
44
|
-
const childProcess = fork(
|
|
54
|
+
const childProcess = fork(
|
|
55
|
+
generator,
|
|
56
|
+
[job.reportDir],
|
|
57
|
+
{
|
|
58
|
+
stdio: 'pipe',
|
|
59
|
+
env: {
|
|
60
|
+
...process.env,
|
|
61
|
+
...job.env
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
)
|
|
45
65
|
const buffers = output.monitor(childProcess, false)
|
|
46
66
|
childProcess.on('close', exitCode => {
|
|
47
67
|
if (exitCode !== 0) {
|
package/src/start.js
CHANGED
|
@@ -16,8 +16,12 @@ async function start (job) {
|
|
|
16
16
|
|
|
17
17
|
// check if node
|
|
18
18
|
if (command === 'node') {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
let [node] = process.argv
|
|
20
|
+
if (node.includes(' ')) {
|
|
21
|
+
node = `"${node}"`
|
|
22
|
+
}
|
|
23
|
+
output.debug('start', `Replacing node with ${node}`)
|
|
24
|
+
start = [node, ...parameters].join(' ')
|
|
21
25
|
} else {
|
|
22
26
|
// check if existing NPM script
|
|
23
27
|
const packagePath = join(job.cwd, 'package.json')
|