ui5-test-runner 5.1.0 → 5.3.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.1.0",
3
+ "version": "5.3.0",
4
4
  "description": "Standalone test runner for UI5",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -46,21 +46,21 @@
46
46
  "commander": "^12.1.0",
47
47
  "punybind": "^1.2.1",
48
48
  "punyexpr": "^1.0.4",
49
- "reserve": "2.0.1"
49
+ "reserve": "2.0.2"
50
50
  },
51
51
  "devDependencies": {
52
- "@openui5/types": "^1.124.0",
53
- "@ui5/cli": "^3.10.3",
52
+ "@openui5/types": "^1.125.0",
53
+ "@ui5/cli": "^3.11.0",
54
54
  "@ui5/middleware-code-coverage": "^1.1.1",
55
55
  "dotenv": "^16.4.5",
56
56
  "jest": "^29.7.0",
57
57
  "nock": "^13.5.4",
58
- "nyc": "^15.1.0",
58
+ "nyc": "^17.0.0",
59
59
  "rimraf": "^5.0.7",
60
60
  "standard": "^17.1.0",
61
- "start-server-and-test": "^2.0.3",
62
- "typescript": "^5.4.5",
63
- "ui5-tooling-transpile": "^3.4.2"
61
+ "start-server-and-test": "^2.0.4",
62
+ "typescript": "^5.5.2",
63
+ "ui5-tooling-transpile": "^3.4.5"
64
64
  },
65
65
  "optionalDependencies": {
66
66
  "fsevents": "^2.3.3"
package/src/coverage.js CHANGED
@@ -310,13 +310,27 @@ module.exports = {
310
310
  await setupNyc(job)
311
311
  // Assuming all files are coming from the same server
312
312
  const { origin } = new URL(job.url[0])
313
- const { createInstrumenter } = require(join(await nycInstallationPath, 'node_modules/istanbul-lib-instrument'))
314
- const instrumenter = createInstrumenter({
315
- produceSourceMap: true,
316
- coverageGlobalScope: 'window.top',
317
- coverageGlobalScopeFunc: false
318
- })
319
- const instrument = promisify(instrumenter.instrument.bind(instrumenter))
313
+ let instrument
314
+ try {
315
+ const { createInstrumenter } = require(join(await nycInstallationPath, 'node_modules/istanbul-lib-instrument'))
316
+ const instrumenter = createInstrumenter({
317
+ produceSourceMap: true,
318
+ coverageGlobalScope: 'window.top',
319
+ coverageGlobalScopeFunc: false
320
+ })
321
+ instrument = promisify(instrumenter.instrument.bind(instrumenter))
322
+ } catch (e) {
323
+ // Recent version of nyc offers a different interface
324
+ const createInstrumenter = require(join(await nycInstallationPath, 'lib/instrumenters/istanbul.js'))
325
+ const instrumenter = createInstrumenter({
326
+ produceSourceMap: true
327
+ })
328
+ instrument = async function (code, sourcePath) {
329
+ return instrumenter.instrumentSync(code, sourcePath, { registerMap: () => {} })
330
+ // TODO use regular expression !
331
+ .replace(globalContextSearch, globalContextReplace)
332
+ }
333
+ }
320
334
  const sources = {}
321
335
  return [{
322
336
  match: /(.*\.js)(\?.*)?$/,
@@ -1,6 +1,6 @@
1
1
  const { readFile, writeFile } = require('fs/promises')
2
2
  const { join } = require('path')
3
- const { Command } = require('commander')
3
+ const { Command, InvalidArgumentError } = require('commander')
4
4
  const { buildCsvWriter } = require('../csv-writer')
5
5
  const { any, boolean, integer } = require('../options')
6
6
 
@@ -20,19 +20,58 @@ module.exports = ({
20
20
  .name(`ui5-test-runner/@/${metadata.name}`)
21
21
  .description(`Browser instantiation command for ${metadata.name}`)
22
22
  .helpOption(false)
23
- metadata.options.forEach(([label, description, parser, defaultValue]) => {
24
- if (defaultValue === undefined && typeof parser !== 'function') {
25
- defaultValue = parser
26
- if (typeof defaultValue === 'number') {
27
- parser = integer
28
- } else if (typeof defaultValue === 'boolean') {
29
- parser = boolean
30
- } else {
31
- parser = any
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
+ ]]
32
40
  }
33
- }
34
- command.option(label, description, parser, defaultValue)
35
- })
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)', ['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
+ })
36
75
 
37
76
  const append = () => { }
38
77
  let consoleWriter = { ready: Promise.resolve(), append }
@@ -95,6 +134,12 @@ module.exports = ({
95
134
  }
96
135
  })
97
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
+
98
143
  if (process.argv.length !== 3) {
99
144
  command.outputHelp()
100
145
  return exit(0)
@@ -105,6 +150,31 @@ module.exports = ({
105
150
  command.parse(settings.args, { from: 'user' })
106
151
  options = command.opts()
107
152
 
153
+ options.chromeArgs = function () {
154
+ const args = [
155
+ '--start-maximized',
156
+ '--no-sandbox',
157
+ '--disable-gpu',
158
+ '--disable-extensions',
159
+ '--log-level=3',
160
+ `--window-size=${options.viewportWidth},${options.viewportHeight}`,
161
+ `--lang=${options.language.join(',')}`
162
+ ]
163
+ if (!options.visible) {
164
+ args.push('--headless=new')
165
+ }
166
+ if (options.unsecure) {
167
+ args.push(
168
+ '--ignore-certificate-errors',
169
+ '--disable-web-security',
170
+ '--disable-features=IsolateOrigins',
171
+ '--disable-features=BlockInsecurePrivateNetworkRequests',
172
+ '--disable-site-isolation-trials'
173
+ )
174
+ }
175
+ return args.concat(command.args)
176
+ }
177
+
108
178
  if (typeof settings.capabilities === 'string') {
109
179
  let capabilities
110
180
  if (computeCapabilities !== undefined) {
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const { InvalidArgumentError } = require('commander')
4
3
  const { join } = require('path')
5
4
  const { exec } = require('child_process')
6
5
 
@@ -8,26 +7,15 @@ let browser
8
7
  let context
9
8
  let page
10
9
 
11
- function browserSelector (value, defaultValue) {
12
- if (value === undefined) {
13
- return 'chromium'
14
- }
15
- if (!['chromium', 'firefox', 'webkit'].includes(value)) {
16
- throw new InvalidArgumentError('Browser name')
17
- }
18
- return value
19
- }
20
-
21
10
  require('./browser')({
22
11
  metadata: {
23
12
  name: 'playwright',
24
13
  options: [
25
- ['-b, --browser <name>', 'Browser driver', browserSelector, 'chromium'],
26
- ['--visible [flag]', 'Show the browser', false],
27
- ['-w, --viewport-width <width>', 'Viewport width', 1280],
28
- ['-h, --viewport-height <height>', 'Viewport height', 720],
29
- ['-l, --language <lang>', 'Language', 'en-US'],
30
- ['-u, --unsecure', 'Disable security features', false],
14
+ ['browser', 'chromium', 'firefox', 'webkit'],
15
+ 'visible',
16
+ 'viewport',
17
+ 'language',
18
+ 'unsecure',
31
19
  ['-v, --video', 'Record video', false],
32
20
  ['-n, --har', 'Record network activity with har file', false]
33
21
  ]
@@ -111,7 +99,7 @@ require('./browser')({
111
99
  width: options.viewportWidth,
112
100
  height: options.viewportHeight
113
101
  },
114
- locale: options.language,
102
+ locale: options.language[0],
115
103
  bypassCSP: options.unsecure,
116
104
  ignoreHTTPSErrors: options.unsecure,
117
105
  recordVideo,
@@ -7,13 +7,12 @@ require('./browser')({
7
7
  metadata: {
8
8
  name: 'puppeteer',
9
9
  options: [
10
- ['--visible [flag]', 'Show the browser', false],
10
+ 'visible',
11
11
  ['--firefox [flag]', 'Use firefox instead of chrome', false],
12
- ['--binary <binary>', 'Binary path'],
13
- ['-w, --viewport-width <width>', 'Viewport width', 1920],
14
- ['-h, --viewport-height <height>', 'Viewport height', 1080],
15
- ['-l, --language <lang...>', 'Language(s)', ['en-US']],
16
- ['-u, --unsecure', 'Disable security features', false],
12
+ 'binary',
13
+ 'viewport',
14
+ 'language',
15
+ 'unsecure',
17
16
  ['--basic-auth-username <username>', 'Username for basic authentication', ''],
18
17
  ['--basic-auth-password <password>', 'Password for basic authentication', '']
19
18
  ]
@@ -55,27 +54,12 @@ require('./browser')({
55
54
  }) {
56
55
  const puppeteer = require(modules.puppeteer)
57
56
 
58
- const args = [
59
- '--start-maximized',
60
- '--no-sandbox',
61
- '--disable-gpu',
62
- '--disable-extensions',
63
- `--window-size=${options.viewportWidth},${options.viewportHeight}`,
64
- `--lang=${options.language.join(',')}`
65
- ]
66
-
67
- if (options.unsecure) {
68
- args.push(
69
- '--disable-web-security',
70
- '--disable-features=IsolateOrigins',
71
- '--disable-features=BlockInsecurePrivateNetworkRequests',
72
- '--disable-site-isolation-trials'
73
- )
74
- }
75
-
57
+ let args = []
76
58
  let product
77
59
  if (options.firefox) {
78
60
  product = 'firefox'
61
+ } else {
62
+ args = options.chromeArgs()
79
63
  }
80
64
 
81
65
  browser = await puppeteer.launch({
@@ -1,22 +1,11 @@
1
1
  'use strict'
2
2
 
3
- const { InvalidArgumentError } = require('commander')
4
3
  const { url } = require('../options')
5
4
  const { writeFile } = require('fs/promises')
6
5
 
7
6
  let logging
8
7
  let driver
9
8
 
10
- function browser (value) {
11
- if (value === undefined) {
12
- return 'chrome'
13
- }
14
- if (!['chrome', 'firefox', 'edge'].includes(value)) {
15
- throw new InvalidArgumentError('Browser name')
16
- }
17
- return value
18
- }
19
-
20
9
  async function buildDriver (settings, options) {
21
10
  const seleniumWebdriver = require(settings.modules['selenium-webdriver'])
22
11
 
@@ -38,10 +27,10 @@ require('./browser')({
38
27
  metadata: {
39
28
  name: 'selenium-webdriver',
40
29
  options: [
41
- ['-b, --browser <name>', 'Browser driver', browser, 'chrome'],
42
- ['--visible [flag]', 'Show the browser', false],
30
+ ['browser', 'chrome', 'firefox', 'edge'],
31
+ 'visible',
43
32
  ['-s, --server <server>', 'Selenium server URL', url],
44
- ['--binary <binary>', 'Binary path']
33
+ 'binary'
45
34
  ]
46
35
  },
47
36
 
@@ -1,26 +1,17 @@
1
1
  'use strict'
2
2
 
3
- const { InvalidArgumentError } = require('commander')
4
-
5
3
  let browserio
6
4
 
7
- function browser (value) {
8
- if (value === undefined) {
9
- return 'chrome'
10
- }
11
- if (!['chrome', 'firefox'].includes(value)) {
12
- throw new InvalidArgumentError('Browser name')
13
- }
14
- return value
15
- }
16
-
17
5
  require('./browser')({
18
6
  metadata: {
19
7
  name: 'webdriverio',
20
8
  options: [
21
- ['--visible [flag]', 'Show the browser', false],
22
- ['-b, --browser <name>', 'Browser driver', browser, 'chrome'],
23
- ['--binary <binary>', 'Binary path']
9
+ 'visible',
10
+ ['browser', 'chrome', 'firefox'],
11
+ 'binary',
12
+ 'viewport',
13
+ 'language',
14
+ 'unsecure'
24
15
  ]
25
16
  },
26
17
 
@@ -57,7 +48,7 @@ require('./browser')({
57
48
  const [browserOptions, args] = {
58
49
  chrome: [
59
50
  'goog:chromeOptions',
60
- options.visible ? [] : ['--headless=new', '--log-level=3', '--disable-gpu']
51
+ options.chromeArgs()
61
52
  ],
62
53
  firefox: [
63
54
  'moz:firefoxOptions',
@@ -9,14 +9,17 @@
9
9
  const base = window['ui5-test-runner/base-host'] || ''
10
10
 
11
11
  let lastPost = Promise.resolve()
12
- let UI5Object
12
+
13
+ function isUI5Object (obj) {
14
+ return typeof obj === 'object' &&
15
+ obj !== null &&
16
+ typeof obj.getId === 'function' &&
17
+ typeof obj.getMetadata === 'function'
18
+ }
13
19
 
14
20
  function stringify (data) {
15
21
  const objects = []
16
22
  const referenced = []
17
- if (!UI5Object && window.sap && window.sap.ui && window.sap.ui.base) {
18
- UI5Object = window.sap.ui.base.Object
19
- }
20
23
  const ui5Summary = obj => {
21
24
  const id = obj.getId && obj.getId()
22
25
  const className = obj.getMetadata && obj.getMetadata() && obj.getMetadata().getName()
@@ -27,7 +30,7 @@
27
30
  }
28
31
  const simple = JSON.stringify(data, function (key, value) {
29
32
  if (typeof value === 'object' && value) {
30
- if (UI5Object && value instanceof UI5Object) {
33
+ if (isUI5Object(value)) {
31
34
  return ui5Summary(value)
32
35
  }
33
36
  const id = objects.indexOf(value)
@@ -45,7 +48,7 @@
45
48
  const stringified = []
46
49
  return JSON.stringify(data, function (key, value) {
47
50
  if (typeof value === 'object' && value) {
48
- if (UI5Object && value instanceof UI5Object) {
51
+ if (isUI5Object(value)) {
49
52
  return ui5Summary(value)
50
53
  }
51
54
  const id = objects.indexOf(value)
@@ -29,7 +29,9 @@
29
29
  set: function (value) {
30
30
  QUnit = value
31
31
  Object.keys(callbacks).forEach(property => {
32
- QUnit[property](callbacks[property])
32
+ if (typeof QUnit[property] === 'function') {
33
+ QUnit[property](callbacks[property])
34
+ }
33
35
  })
34
36
  }
35
37
  })
@@ -33,20 +33,22 @@
33
33
  QUnit = value
34
34
 
35
35
  const { test } = QUnit
36
- QUnit.test = (label) => test(label, (assert) => assert.ok(true, label))
36
+ if (typeof test === 'function') {
37
+ QUnit.test = (label) => test(label, (assert) => assert.ok(true, label))
37
38
 
38
- let timeoutId
39
- QUnit.moduleDone(function () {
40
- if (timeoutId) {
41
- clearTimeout(timeoutId)
42
- }
43
- timeoutId = setTimeout(notify, 10)
44
- })
39
+ let timeoutId
40
+ QUnit.moduleDone(function () {
41
+ if (timeoutId) {
42
+ clearTimeout(timeoutId)
43
+ }
44
+ timeoutId = setTimeout(notify, 10)
45
+ })
45
46
 
46
- function notify () {
47
- const modules = QUnit.config.modules.map(({ moduleId }) => moduleId)
48
- const opa = !!window?.sap?.ui?.test?.Opa5
49
- post('addTestPages', { type: 'qunit', opa, modules, page: location.toString() })
47
+ function notify () {
48
+ const modules = QUnit.config.modules.map(({ moduleId }) => moduleId)
49
+ const opa = !!window?.sap?.ui?.test?.Opa5
50
+ post('addTestPages', { type: 'qunit', opa, modules, page: location.toString() })
51
+ }
50
52
  }
51
53
  }
52
54
  })