ui5-test-runner 3.3.0 → 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 +24 -3
- package/src/defaults/junit-xml-report.js +2 -0
- package/src/defaults/puppeteer.js +19 -3
- package/src/defaults/report/default.html +7 -1
- package/src/defaults/text-report.js +21 -6
- package/src/job.js +13 -8
- 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/src/tools.js +8 -1
- package/src/ui5.js +1 -1
- package/src/unhandled.js +1 -1
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 = {
|
|
@@ -151,6 +164,7 @@ module.exports = {
|
|
|
151
164
|
coverageGlobalScopeFunc: false
|
|
152
165
|
})
|
|
153
166
|
const instrument = promisify(instrumenter.instrument.bind(instrumenter))
|
|
167
|
+
const sources = {}
|
|
154
168
|
return [{
|
|
155
169
|
match: /(.*\.js)(\?.*)?$/,
|
|
156
170
|
custom: async (request, response, url) => {
|
|
@@ -161,8 +175,15 @@ module.exports = {
|
|
|
161
175
|
try {
|
|
162
176
|
await access(sourcePath, constants.R_OK)
|
|
163
177
|
} catch (e) {
|
|
164
|
-
|
|
165
|
-
|
|
178
|
+
try {
|
|
179
|
+
if (sources[url]) {
|
|
180
|
+
await sources[url]
|
|
181
|
+
} else {
|
|
182
|
+
sources[url] = await download(origin + url, sourcePath)
|
|
183
|
+
}
|
|
184
|
+
} catch (statusCode) {
|
|
185
|
+
return statusCode
|
|
186
|
+
}
|
|
166
187
|
}
|
|
167
188
|
const source = (await readFile(sourcePath)).toString()
|
|
168
189
|
const instrumentedSource = await instrument(source, sourcePath)
|
|
@@ -12,10 +12,26 @@ require('./browser')({
|
|
|
12
12
|
['-h, --viewport-height <height>', 'Viewport height', 1080],
|
|
13
13
|
['-l, --language <lang...>', 'Language(s)', ['en-US']],
|
|
14
14
|
['-u, --unsecure', 'Disable security features', false]
|
|
15
|
-
],
|
|
16
|
-
|
|
15
|
+
] // ,
|
|
16
|
+
// TODO restore when Node16 is no more supported
|
|
17
|
+
// capabilities: {
|
|
18
|
+
// modules: ['puppeteer'],
|
|
19
|
+
// screenshot: '.png',
|
|
20
|
+
// scripts: true,
|
|
21
|
+
// traces: ['console', 'network']
|
|
22
|
+
// }
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// TODO remove when Node16 is no more supported
|
|
26
|
+
async capabilities () {
|
|
27
|
+
const version = process.version.match(/^v(\d+\.\d+)/)[1]
|
|
28
|
+
let screenshot
|
|
29
|
+
if (!version.startsWith('16')) {
|
|
30
|
+
screenshot = '.png'
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
17
33
|
modules: ['puppeteer'],
|
|
18
|
-
screenshot
|
|
34
|
+
screenshot,
|
|
19
35
|
scripts: true,
|
|
20
36
|
traces: ['console', 'network']
|
|
21
37
|
}
|
|
@@ -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
|
|
|
@@ -106,7 +106,7 @@ function getCommand (cwd) {
|
|
|
106
106
|
.option('-bt, --browser-close-timeout <timeout>', '[💻🔗🧪] Maximum waiting time for browser close', timeout, 2000)
|
|
107
107
|
.option('-br, --browser-retry <count>', '[💻🔗🧪] Browser instantiation retries : if the command fails unexpectedly, it is re-executed (0 means no retry)', 1)
|
|
108
108
|
|
|
109
|
-
// Common to legacy and
|
|
109
|
+
// Common to legacy and url
|
|
110
110
|
.option('-pf, --page-filter <regexp>', '[💻🔗] Filter out pages not matching the regexp')
|
|
111
111
|
.option('-pp, --page-params <params>', '[💻🔗] Add parameters to page URL')
|
|
112
112
|
.option('-t, --global-timeout <timeout>', '[💻🔗] Limit the pages execution time, fail the page if it takes longer than the timeout (0 means no timeout)', timeout, 0)
|
|
@@ -119,13 +119,18 @@ 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
|
-
// Specific to legacy
|
|
131
|
+
// Specific to legacy (and might be used with url if pointing to local project)
|
|
128
132
|
.option('--ui5 <url>', '[💻] UI5 url', url, 'https://ui5.sap.com')
|
|
133
|
+
.option('--no-ui5', '[💻] Disable UI5 mapping (also disable libs)')
|
|
129
134
|
.option('--libs <lib...>', '[💻] Library mapping (<relative>=<path> or <path>)', arrayOf(lib))
|
|
130
135
|
.option('--mappings <mapping...>', '[💻] Custom mapping (<match>=<file|url>(<config>))', arrayOf(mapping))
|
|
131
136
|
.option('--cache <path>', '[💻] Cache UI5 resources locally in the given folder (empty to disable)')
|
|
@@ -135,8 +140,8 @@ function getCommand (cwd) {
|
|
|
135
140
|
|
|
136
141
|
// Specific to coverage in url mode (experimental)
|
|
137
142
|
.option('-cp, --coverage-proxy [flag]', `[🔗] ${EXPERIMENTAL_OPTION} use internal proxy to instrument remote files`, boolean, false)
|
|
138
|
-
.option('-cpi, --coverage-proxy-include <regexp>', `[🔗] ${EXPERIMENTAL_OPTION} urls to instrument for coverage`, regex, regex('
|
|
139
|
-
.option('-cpe, --coverage-proxy-exclude <regexp>', `[🔗] ${EXPERIMENTAL_OPTION} urls to ignore for coverage`, regex, regex('(test-)?resources/.*'))
|
|
143
|
+
.option('-cpi, --coverage-proxy-include <regexp>', `[🔗] ${EXPERIMENTAL_OPTION} urls to instrument for coverage`, regex, regex('.*'))
|
|
144
|
+
.option('-cpe, --coverage-proxy-exclude <regexp>', `[🔗] ${EXPERIMENTAL_OPTION} urls to ignore for coverage`, regex, regex('/((test-)?resources|tests?)/.*'))
|
|
140
145
|
|
|
141
146
|
.addOption(new Option('--debug-probe-only', DEBUG_OPTION, boolean).hideHelp())
|
|
142
147
|
.addOption(new Option('--debug-keep-browser-open', DEBUG_OPTION, boolean).hideHelp())
|
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
|
}
|
package/src/tools.js
CHANGED
|
@@ -6,6 +6,7 @@ const { createHash } = require('crypto')
|
|
|
6
6
|
const { createWriteStream } = require('fs')
|
|
7
7
|
const http = require('http')
|
|
8
8
|
const https = require('https')
|
|
9
|
+
const { unlink } = require('fs/promises')
|
|
9
10
|
|
|
10
11
|
const recursive = { recursive: true }
|
|
11
12
|
|
|
@@ -136,7 +137,13 @@ async function download (url, filename) {
|
|
|
136
137
|
await mkdir(dirname(filename), recursive)
|
|
137
138
|
const output = createWriteStream(filename)
|
|
138
139
|
const { promise, resolve, reject } = allocPromise()
|
|
139
|
-
const request = protocol.request(options, response => {
|
|
140
|
+
const request = protocol.request(options, async response => {
|
|
141
|
+
if (response.statusCode !== 200) {
|
|
142
|
+
reject(response.statusCode)
|
|
143
|
+
output.end()
|
|
144
|
+
await unlink(filename)
|
|
145
|
+
return
|
|
146
|
+
}
|
|
140
147
|
response.on('error', reject)
|
|
141
148
|
response.on('end', resolve)
|
|
142
149
|
response.pipe(output)
|
package/src/ui5.js
CHANGED
package/src/unhandled.js
CHANGED
|
@@ -23,7 +23,7 @@ module.exports = job => {
|
|
|
23
23
|
getOutput(job).unhandled()
|
|
24
24
|
outputUnhandled = false
|
|
25
25
|
}
|
|
26
|
-
writeFile(unhandled, `${extractPageUrl(headers)} ${status} ${method} ${url}\n`, {
|
|
26
|
+
writeFile(unhandled, `${extractPageUrl(headers) || headers.referer} ${status} ${method} ${url}\n`, {
|
|
27
27
|
flag: 'a'
|
|
28
28
|
}, noop)
|
|
29
29
|
return status
|