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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui5-test-runner",
3
- "version": "5.5.1",
3
+ "version": "5.6.0",
4
4
  "description": "Standalone test runner for UI5",
5
5
  "main": "index.js",
6
6
  "bin": {
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 = (batchItems, job, folderPath) => {
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 = (batchItems, job, configurationFilePath) => {
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 ({ job, id, label, args }) => {
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 (option.variadic) {
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.errors
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
- const batchItems = []
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(batchItems, job, path)
160
+ folder(job, path)
150
161
  } else if (pathStat.isFile() && extname(path) === '.json') {
151
- configurationFile(batchItems, job, path)
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(batchItems, job, path)
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(batchItems, job, path)
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://localhost:${job.port}'
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
@@ -17,7 +17,11 @@ async function end (job) {
17
17
  {
18
18
  cwd: job.cwd,
19
19
  stdio: [0, 'pipe', 'pipe', 'ipc'],
20
- windowsHide: true
20
+ windowsHide: true,
21
+ env: {
22
+ ...process.env,
23
+ ...job.env
24
+ }
21
25
  }
22
26
  )
23
27
 
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(join(__dirname, 'defaults/text-report.js'), [job.reportDir, process.stdout.columns || ''], { stdio: 'pipe' })
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(generator, [job.reportDir], { stdio: 'pipe' })
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
- output.debug('start', `Replacing node with ${process.argv[0]}`)
20
- start = [process.argv[0], ...parameters].join(' ')
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')
package/src/timeout.js CHANGED
@@ -46,8 +46,8 @@ module.exports = {
46
46
  }
47
47
  })
48
48
  })
49
- job.failed = true
50
- job.timedOut = true
51
49
  }
50
+ job.failed = true
51
+ job.timedOut = true
52
52
  }
53
53
  }