ui5-test-runner 3.3.1 → 3.3.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 +1 -1
- package/src/browsers.js +2 -1
- package/src/coverage.js +14 -1
- package/src/defaults/report/default.html +7 -1
- package/src/defaults/text-report.js +21 -6
- package/src/job.js +8 -4
- package/src/options.js +8 -0
- package/src/options.spec.js +17 -1
- package/src/report.js +1 -1
- package/src/simulate.spec.js +57 -1
- package/src/tests.js +1 -0
- package/src/timeout.js +33 -0
package/package.json
CHANGED
package/src/browsers.js
CHANGED
|
@@ -4,7 +4,7 @@ const { fork } = require('child_process')
|
|
|
4
4
|
const { join } = require('path')
|
|
5
5
|
const { writeFile, readFile, open, stat, unlink } = require('fs/promises')
|
|
6
6
|
const { recreateDir, filename, allocPromise } = require('./tools')
|
|
7
|
-
const { getPageTimeout } = require('./timeout')
|
|
7
|
+
const { getPageTimeout, pageTimedOut } = require('./timeout')
|
|
8
8
|
const { getOutput } = require('./output')
|
|
9
9
|
const { resolvePackage } = require('./npm')
|
|
10
10
|
const { UTRError } = require('./error')
|
|
@@ -174,6 +174,7 @@ async function run (job, pageBrowser) {
|
|
|
174
174
|
if (timeout) {
|
|
175
175
|
pageBrowser.timeoutId = setTimeout(() => {
|
|
176
176
|
output.browserTimeout(url, dir)
|
|
177
|
+
pageTimedOut(job, url)
|
|
177
178
|
stop(job, url)
|
|
178
179
|
}, timeout)
|
|
179
180
|
}
|
package/src/coverage.js
CHANGED
|
@@ -110,7 +110,20 @@ async function generateCoverageReport (job) {
|
|
|
110
110
|
await writeFile(coverageFilename, JSON.stringify(coverageData))
|
|
111
111
|
}
|
|
112
112
|
const reporters = job.coverageReporters.map(reporter => `--reporter=${reporter}`)
|
|
113
|
-
|
|
113
|
+
if (!job.coverageReporters.includes('text')) {
|
|
114
|
+
reporters.push('--reporter=text')
|
|
115
|
+
}
|
|
116
|
+
const checks = []
|
|
117
|
+
if (job.coverageCheckBranches || job.coverageCheckFunctions || job.coverageCheckLines || job.coverageCheckStatements) {
|
|
118
|
+
checks.push(
|
|
119
|
+
`--branches=${job.coverageCheckBranches}`,
|
|
120
|
+
`--functions=${job.coverageCheckFunctions}`,
|
|
121
|
+
`--lines=${job.coverageCheckLines}`,
|
|
122
|
+
`--statements=${job.coverageCheckStatements}`,
|
|
123
|
+
'--check-coverage'
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
await nyc(job, 'report', ...reporters, ...checks, '--temp-dir', coverageMergedDir, '--report-dir', job.coverageReportDir, '--nycrc-path', job[$nycSettingsPath])
|
|
114
127
|
}
|
|
115
128
|
|
|
116
129
|
module.exports = {
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
<h1>{{ status || 'Test report' }}</h1>
|
|
13
13
|
<div {{if}}="end === undefined" class="elapsed">In progress since {{ elapsed(start) }}</div>
|
|
14
14
|
<div {{else}} class="elapsed">Duration : {{ elapsed(start, end) }} <a href="#" id="download">📦</a></div>
|
|
15
|
+
<div {{if}}="timedOut">
|
|
16
|
+
⏲️ Timed out
|
|
17
|
+
</div>
|
|
15
18
|
<table style="visibility: {{ testPageUrls.length > 0 ? 'visible' : 'hidden' }};">
|
|
16
19
|
<tr>
|
|
17
20
|
<th> </th>
|
|
@@ -30,7 +33,7 @@
|
|
|
30
33
|
<td>
|
|
31
34
|
<span {{if}}="!qunitPages[url]">-</span>
|
|
32
35
|
<span {{elseif}}="qunitPages[url].isOpa" title="OPA test">🥼</span>
|
|
33
|
-
<span {{
|
|
36
|
+
<span {{elseif}}="qunitPages[url].start" title="Unit test">🧪</span>
|
|
34
37
|
</td>
|
|
35
38
|
<td>
|
|
36
39
|
<span {{if}}="!qunitPages[url]">-</span>
|
|
@@ -56,6 +59,9 @@
|
|
|
56
59
|
<a href="#">⏴ back to report</a>
|
|
57
60
|
<div {{if}}="qunitPage.end === undefined" class="elapsed">In progress since {{ elapsed(qunitPage.start) }}</div>
|
|
58
61
|
<div {{else}} class="elapsed">Duration : {{ elapsed(qunitPage.start, qunitPage.end) }}</div>
|
|
62
|
+
<div {{if}}="timedOut">
|
|
63
|
+
⏲️ Timed out
|
|
64
|
+
</div>
|
|
59
65
|
<div {{for}}="module of qunitPage.modules">
|
|
60
66
|
<h2>{{ module.name }}</h2>
|
|
61
67
|
<div {{for}}="test of module.tests">
|
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { join, isAbsolute } = require('path')
|
|
4
|
-
const [, , reportDir] = process.argv
|
|
4
|
+
const [, , reportDir, expectedWidth] = process.argv
|
|
5
5
|
const { pad } = require('../tools')
|
|
6
6
|
|
|
7
|
-
const p = pad(process.stdout.columns || 80)
|
|
7
|
+
const p = pad(process.stdout.columns || parseInt(expectedWidth || '80', 10))
|
|
8
8
|
const log = console.log.bind(console)
|
|
9
9
|
|
|
10
10
|
function collectErrors (page) {
|
|
11
11
|
const errors = []
|
|
12
12
|
page.modules.forEach(module => {
|
|
13
|
-
module.tests.
|
|
14
|
-
if (test.report
|
|
13
|
+
module.tests.every(test => {
|
|
14
|
+
if (!test.report) {
|
|
15
|
+
if (!test.skip) {
|
|
16
|
+
test.logs ??= []
|
|
17
|
+
test.logs.push({
|
|
18
|
+
message: '(no report found)'
|
|
19
|
+
})
|
|
20
|
+
errors.push({ module: module.name, ...test })
|
|
21
|
+
return false
|
|
22
|
+
}
|
|
23
|
+
} else if (test.report.failed) {
|
|
15
24
|
errors.push({ module: module.name, ...test })
|
|
16
25
|
}
|
|
26
|
+
return true
|
|
17
27
|
})
|
|
18
28
|
})
|
|
19
29
|
return errors
|
|
@@ -28,8 +38,11 @@ async function main () {
|
|
|
28
38
|
}
|
|
29
39
|
const job = require(jobPath)
|
|
30
40
|
const failedUrls = []
|
|
31
|
-
|
|
41
|
+
let rendered = 0
|
|
32
42
|
function render (url) {
|
|
43
|
+
if (++rendered === 1) {
|
|
44
|
+
log(p`┌─${pad.x('─')}───────────────────┐`)
|
|
45
|
+
}
|
|
33
46
|
const page = job.qunitPages && job.qunitPages[url]
|
|
34
47
|
if (!page || !page.report) {
|
|
35
48
|
log(p`│${pad.lt(url)} 🧨 │`)
|
|
@@ -49,7 +62,9 @@ async function main () {
|
|
|
49
62
|
render(url)
|
|
50
63
|
}
|
|
51
64
|
})
|
|
52
|
-
|
|
65
|
+
if (rendered > 0) {
|
|
66
|
+
log(p`└─${pad.x('─')}────────────────────┘`)
|
|
67
|
+
}
|
|
53
68
|
failedUrls.forEach(url => {
|
|
54
69
|
log()
|
|
55
70
|
log(p`[${pad.lt(url)}]`)
|
package/src/job.js
CHANGED
|
@@ -7,7 +7,7 @@ const { name, description, version } = require(join(__dirname, '../package.json'
|
|
|
7
7
|
const { getOutput } = require('./output')
|
|
8
8
|
const { $valueSources } = require('./symbols')
|
|
9
9
|
const { buildAndCheckMode } = require('./job-mode')
|
|
10
|
-
const { boolean, integer, timeout, url, arrayOf, regex } = require('./options')
|
|
10
|
+
const { boolean, integer, timeout, url, arrayOf, regex, percent } = require('./options')
|
|
11
11
|
|
|
12
12
|
const $status = Symbol('status')
|
|
13
13
|
|
|
@@ -119,9 +119,13 @@ function getCommand (cwd) {
|
|
|
119
119
|
.option('--coverage [flag]', '[💻🔗] Enable or disable code coverage', boolean)
|
|
120
120
|
.option('--no-coverage', '[💻🔗] Disable code coverage')
|
|
121
121
|
.option('-cs, --coverage-settings <path>', '[💻🔗] Path to a custom nyc.json file providing settings for instrumentation (relative to cwd or use $/ for provided ones)', '$/nyc.json')
|
|
122
|
-
.option('-
|
|
123
|
-
.option('-
|
|
124
|
-
.option('-cr, --coverage-reporters <reporter...>', '[💻🔗] List of nyc reporters to use', ['lcov', 'cobertura'])
|
|
122
|
+
.option('-ctd, --coverage-temp-dir <path>', '[💻🔗] Directory to output raw coverage information to (relative to cwd)', '.nyc_output')
|
|
123
|
+
.option('-crd, --coverage-report-dir <path>', '[💻🔗] Directory to store the coverage report files (relative to cwd)', 'coverage')
|
|
124
|
+
.option('-cr, --coverage-reporters <reporter...>', '[💻🔗] List of nyc reporters to use (text is always used)', ['lcov', 'cobertura'])
|
|
125
|
+
.option('-ccb, --coverage-check-branches <percent>', '[💻🔗] What % of branches must be covered', percent, 0)
|
|
126
|
+
.option('-ccf, --coverage-check-functions <percent>', '[💻🔗] What % of functions must be covered', percent, 0)
|
|
127
|
+
.option('-ccl, --coverage-check-lines <percent>', '[💻🔗] What % of lines must be covered', percent, 0)
|
|
128
|
+
.option('-ccs, --coverage-check-statements <percent>', '[💻🔗] What % of statements must be covered', percent, 0)
|
|
125
129
|
.option('-s, --serve-only [flag]', '[💻🔗] Serve only', boolean, false)
|
|
126
130
|
|
|
127
131
|
// Specific to legacy (and might be used with url if pointing to local project)
|
package/src/options.js
CHANGED
package/src/options.spec.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { any, boolean, integer, timeout, url, arrayOf } = require('./options')
|
|
1
|
+
const { any, boolean, integer, timeout, url, arrayOf, percent } = require('./options')
|
|
2
2
|
const { InvalidArgumentError } = require('commander')
|
|
3
3
|
|
|
4
4
|
function checkType ({ method, validValues, invalidValues }) {
|
|
@@ -115,6 +115,22 @@ describe('src/options', () => {
|
|
|
115
115
|
]
|
|
116
116
|
})
|
|
117
117
|
|
|
118
|
+
checkType({
|
|
119
|
+
method: percent,
|
|
120
|
+
validValues: {
|
|
121
|
+
0: 0,
|
|
122
|
+
1: 1,
|
|
123
|
+
10: 10,
|
|
124
|
+
100: 100
|
|
125
|
+
},
|
|
126
|
+
invalidValues: [
|
|
127
|
+
'',
|
|
128
|
+
'-1',
|
|
129
|
+
'abc',
|
|
130
|
+
'101'
|
|
131
|
+
]
|
|
132
|
+
})
|
|
133
|
+
|
|
118
134
|
describe('arrayOf', () => {
|
|
119
135
|
it('builds a type validator that aggregates validated values in an array', () => {
|
|
120
136
|
const validator = arrayOf(integer)
|
package/src/report.js
CHANGED
|
@@ -22,7 +22,7 @@ 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], { stdio: 'pipe' })
|
|
25
|
+
const childProcess = fork(join(__dirname, 'defaults/text-report.js'), [job.reportDir, process.stdout.columns || ''], { stdio: 'pipe' })
|
|
26
26
|
getOutput(job).monitor(childProcess, true)
|
|
27
27
|
childProcess.on('close', resolve)
|
|
28
28
|
return promise
|
package/src/simulate.spec.js
CHANGED
|
@@ -301,7 +301,7 @@ describe('simulate', () => {
|
|
|
301
301
|
|
|
302
302
|
describe('global timeout', () => {
|
|
303
303
|
beforeAll(async () => {
|
|
304
|
-
await setup('timeout', {
|
|
304
|
+
await setup('global-timeout', {
|
|
305
305
|
parallel: 1,
|
|
306
306
|
globalTimeout: 10000
|
|
307
307
|
})
|
|
@@ -325,6 +325,62 @@ describe('simulate', () => {
|
|
|
325
325
|
|
|
326
326
|
it('failed', () => {
|
|
327
327
|
expect(job.failed).toStrictEqual(true)
|
|
328
|
+
expect(job.timedOut).toStrictEqual(true)
|
|
329
|
+
})
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
describe('page timeout', () => {
|
|
333
|
+
beforeAll(async () => {
|
|
334
|
+
await setup('page-timeout', {
|
|
335
|
+
parallel: 1,
|
|
336
|
+
pageTimeout: 250
|
|
337
|
+
})
|
|
338
|
+
pages = {
|
|
339
|
+
'testsuite.qunit.html': async referer => {
|
|
340
|
+
await post('/_/addTestPages', referer, [
|
|
341
|
+
'/page1.html'
|
|
342
|
+
])
|
|
343
|
+
},
|
|
344
|
+
'page1.html': async headers => {
|
|
345
|
+
await post('/_/QUnit/begin', headers, {
|
|
346
|
+
totalTests: 3,
|
|
347
|
+
modules: [{
|
|
348
|
+
name: '0',
|
|
349
|
+
tests: [{
|
|
350
|
+
name: '1',
|
|
351
|
+
testId: '1'
|
|
352
|
+
}, {
|
|
353
|
+
name: '2',
|
|
354
|
+
testId: '2'
|
|
355
|
+
}, {
|
|
356
|
+
name: '3',
|
|
357
|
+
testId: '3'
|
|
358
|
+
}]
|
|
359
|
+
}]
|
|
360
|
+
})
|
|
361
|
+
await post('/_/QUnit/testStart', headers, { module: '0', name: '1', testId: '1' })
|
|
362
|
+
await post('/_/QUnit/testDone', headers, { testId: '1', failed: 0, passed: 1 })
|
|
363
|
+
await post('/_/QUnit/testStart', headers, { module: '0', name: '2', testId: '2' })
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
await safeExecute()
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
it('failed', () => {
|
|
370
|
+
expect(job.failed).toStrictEqual(true)
|
|
371
|
+
expect(job.timedOut).toStrictEqual(true)
|
|
372
|
+
const page = job.qunitPages['http://localhost:0/page1.html']
|
|
373
|
+
expect(page.failed).toStrictEqual(2)
|
|
374
|
+
expect(page.end).not.toBeUndefined()
|
|
375
|
+
expect(page.timedOut).toStrictEqual(true)
|
|
376
|
+
const { tests } = page.modules[0]
|
|
377
|
+
expect(tests[1].report.failed).toStrictEqual(1)
|
|
378
|
+
expect(tests[1].report.passed).toStrictEqual(0)
|
|
379
|
+
expect(tests[1].end).not.toBeUndefined()
|
|
380
|
+
expect(tests[2].report.failed).toStrictEqual(1)
|
|
381
|
+
expect(tests[2].report.passed).toStrictEqual(0)
|
|
382
|
+
expect(tests[2].start).toBeUndefined()
|
|
383
|
+
expect(tests[2].end).toBeUndefined()
|
|
328
384
|
})
|
|
329
385
|
})
|
|
330
386
|
|
package/src/tests.js
CHANGED
package/src/timeout.js
CHANGED
|
@@ -16,5 +16,38 @@ module.exports = {
|
|
|
16
16
|
return new Date() - job.start > job.globalTimeout
|
|
17
17
|
}
|
|
18
18
|
return false
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
pageTimedOut (job, url) {
|
|
22
|
+
const page = job.qunitPages && job.qunitPages[url]
|
|
23
|
+
if (page) {
|
|
24
|
+
const now = new Date()
|
|
25
|
+
page.end = now
|
|
26
|
+
page.timedOut = true
|
|
27
|
+
page.modules.forEach(module => {
|
|
28
|
+
module.tests.forEach(test => {
|
|
29
|
+
if (!test.report) {
|
|
30
|
+
++page.failed
|
|
31
|
+
if (test.start && !test.end) {
|
|
32
|
+
test.end = now
|
|
33
|
+
}
|
|
34
|
+
test.logs ??= []
|
|
35
|
+
test.logs.push({
|
|
36
|
+
result: false,
|
|
37
|
+
message: 'Page timed out'
|
|
38
|
+
})
|
|
39
|
+
test.report = {
|
|
40
|
+
skipped: false,
|
|
41
|
+
todo: false,
|
|
42
|
+
failed: 1,
|
|
43
|
+
passed: 0,
|
|
44
|
+
total: 1
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
})
|
|
49
|
+
job.failed = true
|
|
50
|
+
job.timedOut = true
|
|
51
|
+
}
|
|
19
52
|
}
|
|
20
53
|
}
|