ui5-test-runner 5.5.0 → 5.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui5-test-runner",
3
- "version": "5.5.0",
3
+ "version": "5.5.2",
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)
@@ -104,6 +107,8 @@ const task = async ({ job, id, label, args }) => {
104
107
  childProcess.on('close', async code => {
105
108
  await stdout.close()
106
109
  await stderr.close()
110
+ batchItem.statusCode = code
111
+ batchItem.end = new Date()
107
112
  if (code !== 0) {
108
113
  reject(code)
109
114
  } else {
@@ -116,7 +121,7 @@ const task = async ({ job, id, label, args }) => {
116
121
  .then(() => {
117
122
  output.log('✔️ ', progress.label)
118
123
  }, (reason) => {
119
- ++job.errors
124
+ ++job.failed
120
125
  output.log('❌', progress.label, reason)
121
126
  })
122
127
  .finally(() => {
@@ -135,7 +140,9 @@ async function batch (job) {
135
140
  * --report-dir is always passed to aggregate reports under one root folder
136
141
  */
137
142
  const output = getOutput(job)
138
- const batchItems = []
143
+ job.start = new Date()
144
+ job.failed = 0
145
+ job.batchItems = []
139
146
  for (const batch of job.batch) {
140
147
  output.debug('batch', `processing: ${batch}`)
141
148
  // check if path
@@ -146,9 +153,9 @@ async function batch (job) {
146
153
  }
147
154
  const pathStat = await stat(path)
148
155
  if (pathStat.isDirectory()) {
149
- folder(batchItems, job, path)
156
+ folder(job, path)
150
157
  } else if (pathStat.isFile() && extname(path) === '.json') {
151
- configurationFile(batchItems, job, path)
158
+ configurationFile(job, path)
152
159
  } else {
153
160
  output.batchFailed(batch, 'only folders and JSON configuration files are supported')
154
161
  }
@@ -171,24 +178,33 @@ async function batch (job) {
171
178
  const pathStat = await stat(path)
172
179
  if (pathStat.isDirectory()) {
173
180
  if (re.test(path) || re.test(path.replaceAll('\\', '/'))) {
174
- folder(batchItems, job, path)
181
+ folder(job, path)
175
182
  continue
176
183
  }
177
184
  await scan(path)
178
185
  } else if (pathStat.isFile() && (re.test(path) || re.test(path.replaceAll('\\', '/')))) {
179
- configurationFile(batchItems, job, path)
186
+ configurationFile(job, path)
180
187
  }
181
188
  }
182
189
  }
183
190
  await scan(job.cwd)
184
191
  }
185
- if (batchItems.length) {
192
+ if (job.batchItems.length) {
186
193
  job.status = 'Running batch items...'
187
- await parallelize(task, batchItems, job.parallel)
188
- // TODO: end command ?
194
+ await parallelize(task.bind(job), job.batchItems, job.parallel)
189
195
  } else {
190
196
  output.batchFailed(job.batch, 'no match')
191
197
  }
198
+
199
+ job.end = new Date()
200
+ job.failed = !!job.failed
201
+ if (job.failed) {
202
+ process.exitCode = -1
203
+ }
204
+ await save(job)
205
+ if (job.endScript) {
206
+ await end(job)
207
+ }
192
208
  output.stop()
193
209
  return 0
194
210
  }
@@ -101,7 +101,7 @@ async function capabilities (job) {
101
101
 
102
102
  const task = async (test) => {
103
103
  const { promise, resolve } = allocPromise()
104
- const { label, url, scripts, endpoint = () => { } } = test
104
+ const { label, url, args, scripts, endpoint = () => { } } = test
105
105
 
106
106
  const listenerIndex = listeners.length
107
107
  let pageUrl
@@ -159,6 +159,10 @@ async function capabilities (job) {
159
159
  }
160
160
  }
161
161
 
162
+ if (args) {
163
+ // TODO replace or concat ?
164
+ }
165
+
162
166
  start(job, pageUrl, scripts)
163
167
  .catch(reason => done(reason))
164
168
  .then(() => {
@@ -0,0 +1,39 @@
1
+ 'use strict'
2
+
3
+ const assert = require('assert')
4
+
5
+ module.exports = [{
6
+ label: 'UI5 focus handling',
7
+ for: capabilities => !capabilities.modules.includes('jsdom'), // does not work on JSDOM
8
+ url: 'ui5/focus.html',
9
+ endpoint: ({ body }) => {
10
+ assert.strictEqual(body['is-focus-set'], true)
11
+ }
12
+ }, {
13
+ label: 'UI5 language handling (EN)',
14
+ for: () => false, // capabilities => capabilities.modules.includes('puppeteer'),
15
+ url: 'ui5/language.html',
16
+ args: ['--language en'],
17
+ endpoint: ({ body }) => {
18
+ assert.strictEqual(body.language, 'en')
19
+ assert.strictEqual(body.message, 'No matching items found.')
20
+ }
21
+ }, {
22
+ label: 'UI5 language handling (DE)',
23
+ for: () => false, // capabilities => capabilities.modules.includes('puppeteer'),
24
+ url: 'ui5/language.html',
25
+ args: ['--language de'],
26
+ endpoint: ({ body }) => {
27
+ assert.strictEqual(body.language, 'de')
28
+ assert.strictEqual(body.message, 'Keine passenden Elemente gefunden.')
29
+ }
30
+ }, {
31
+ label: 'UI5 language handling (FR)',
32
+ for: () => false, // capabilities => capabilities.modules.includes('puppeteer'),
33
+ url: 'ui5/language.html',
34
+ args: ['--language fr'],
35
+ endpoint: ({ body }) => {
36
+ assert.strictEqual(body.language, 'fr')
37
+ assert.strictEqual(body.message, 'Aucun élément concordant trouvé.')
38
+ }
39
+ }]
@@ -0,0 +1,50 @@
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 id="myXml" type="text/xmldata">
16
+ <mvc:View
17
+ xmlns:mvc="sap.ui.core.mvc"
18
+ xmlns="sap.m"
19
+ controllerName="myController"
20
+ displayBlock="true"
21
+ height="100%"
22
+ >
23
+ <MessagePage showHeader="false" icon="sap-icon://filter"/>
24
+ </mvc:View>
25
+ </script>
26
+ <script>
27
+ sap.ui.require([
28
+ "sap/ui/core/mvc/Controller",
29
+ "sap/ui/core/mvc/XMLView"
30
+ ], function (Controller, XMLView, Dialog, Button) {
31
+ Controller.extend("myController", {
32
+ onAfterRendering: function () {
33
+ // Notify the test framework
34
+ const xhr = new XMLHttpRequest();
35
+ xhr.open('POST', '/_/log');
36
+ xhr.send(JSON.stringify({
37
+ language: navigator.language,
38
+ message: document.querySelector('.sapMMessagePageMainText').innerText
39
+ }));
40
+ }
41
+ });
42
+
43
+ XMLView.create({definition: jQuery('#myXml').html()}).then(function (oView) {
44
+ oView.placeAt(document.querySelector('body'));
45
+ });
46
+ });
47
+ </script>
48
+ </head>
49
+ <body class='sapUiBody'></body>
50
+ </html>
@@ -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/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')
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 ⚠️`)
@@ -91,7 +91,7 @@ async function done (job, urlWithHash, report) {
91
91
  const { promise, resolve } = allocPromise()
92
92
  page[$doneResolve] = resolve
93
93
  page[$doneTimeout] = setTimeout(async () => {
94
- if (job.browserCapabilities.screenshot) {
94
+ if (job.browserCapabilities.screenshot && job.screenshot) {
95
95
  try {
96
96
  await screenshot(job, url, 'done')
97
97
  } catch (error) {
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
  }
@@ -1,12 +0,0 @@
1
- 'use strict'
2
-
3
- const assert = require('assert')
4
-
5
- module.exports = [{
6
- label: 'UI5 focus handling',
7
- for: capabilities => !capabilities.modules.includes('jsdom'), // does not work on JSDOM
8
- url: 'ui5-focus/index.html',
9
- endpoint: ({ body }) => {
10
- assert.strictEqual(body['is-focus-set'], true)
11
- }
12
- }]