diff --git a/README.md b/README.md
index 74c7fb7a..6627faf1 100644
--- a/README.md
+++ b/README.md
@@ -129,6 +129,7 @@ You may also use :
| libs | | Folder(s) containing dependent libraries *(relative to `cwd`)*.
Might be used multiple times, two syntaxes are supported :
- `-libs:path` adds `path` to the list of libraries, mapped directly under `/resources/`
- `-libs:rel/=path` adds the `path` to the list of libraries, mapped under `/resources/rel/`
|
| cache | `''` | Cache UI5 resources locally in the given folder *(empty to disable)* |
| webapp | `'webapp'` | base folder of the web application *(relative to `cwd`)* |
+| testsuite | `'test/testsuite.qunit.html'` | path / URL to the testsuite file *(relative to `webapp`)* |
| pageFilter | `''` | [regexp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) to select which pages to execute |
| pageParams | `''` | Parameters added to each page URL.
For instance : `'sap-ui-theme=sap_belize&sap-ui-debug=true'` |
| pageTimeout | `0` | Limit the page execution time (ms), fails the page if it takes longer than the timeout (`0` to disable the timeout) |
diff --git a/__mocks__/fs.js b/__mocks__/fs.js
new file mode 100644
index 00000000..7ef05150
--- /dev/null
+++ b/__mocks__/fs.js
@@ -0,0 +1,14 @@
+const fs = jest.requireActual('fs')
+
+module.exports = {
+ ...fs,
+ writeFile (path, content, options, callback) {
+ // This version is used only in unhandled
+ callback()
+ },
+ accessSync: path => {
+ if (path.includes('$NOT_EXISTING$')) {
+ throw new Error()
+ }
+ }
+}
diff --git a/__mocks__/setup.js b/__mocks__/setup.js
new file mode 100644
index 00000000..88b96295
--- /dev/null
+++ b/__mocks__/setup.js
@@ -0,0 +1,11 @@
+jest.mock('child_process')
+jest.mock('fs')
+
+const EventEmitter = require('events')
+const mockedOutput = new EventEmitter()
+
+const output = jest.requireActual('../src/output')
+Object.keys(output).forEach(name => {
+ mockedOutput[name] = function (...args) { this.emit(name, ...args) }
+})
+jest.mock('../src/output', () => mockedOutput)
diff --git a/__tests__/src/browser.js b/__tests__/src/browser.js
index cdc5abab..701db6b0 100644
--- a/__tests__/src/browser.js
+++ b/__tests__/src/browser.js
@@ -1,17 +1,3 @@
-jest.mock('child_process')
-jest.mock('../../src/output', () => {
- const EventEmitter = require('events')
- class Output extends EventEmitter {
- browserStart (...args) { this.emit('browserStart', ...args) }
- browserStopped (...args) { this.emit('browserStopped', ...args) }
- browserCapabilities (...args) { this.emit('browserCapabilities', ...args) }
- browserTimeout (...args) { this.emit('browserTimeout', ...args) }
- browserRetry (...args) { this.emit('browserRetry', ...args) }
- browserClosed (...args) { this.emit('browserClosed', ...args) }
- monitor (...args) { this.emit('monitor', ...args) }
- }
- return new Output()
-})
const output = require('../../src/output')
const { join } = require('path')
const { _hook: hook } = require('child_process')
diff --git a/__tests__/src/coverage.js b/__tests__/src/coverage.js
index 5fee56cb..9300b859 100644
--- a/__tests__/src/coverage.js
+++ b/__tests__/src/coverage.js
@@ -1,10 +1,3 @@
-jest.mock('child_process')
-jest.mock('../../src/output', () => {
- return {
- nyc: jest.fn(),
- monitor: jest.fn()
- }
-})
const { join } = require('path')
const jobFactory = require('../../src/job')
const { _hook: hook } = require('child_process')
diff --git a/__tests__/src/job.js b/__tests__/src/job.js
index 15418362..0f2bfbb4 100644
--- a/__tests__/src/job.js
+++ b/__tests__/src/job.js
@@ -1,8 +1,3 @@
-jest.mock('../../src/output', () => {
- return {
- unexpectedOptionValue: jest.fn()
- }
-})
const { dirname, join } = require('path')
const jobFactory = require('../../src/job')
const cwd = '/test/project'
@@ -124,6 +119,28 @@ describe('src/job', () => {
expect(job.ui5).toStrictEqual('https://ui5.sap.com')
})
+ describe('Path parameters validation', () => {
+ it('webapp', () => {
+ const cwd = join(__dirname, '../cwd')
+ expect(() => jobFactory.fromCmdLine(cwd, [0, 0, '-webapp:$NOT_EXISTING$'])).toThrow()
+ })
+
+ it('browser', () => {
+ const cwd = join(__dirname, '../cwd')
+ expect(() => jobFactory.fromCmdLine(cwd, [0, 0, '-browser:$NOT_EXISTING$/cmd.js'])).toThrow()
+ })
+
+ it('testsuite', () => {
+ const cwd = join(__dirname, '../cwd')
+ expect(() => jobFactory.fromCmdLine(cwd, [0, 0, '-testsuite:$NOT_EXISTING$/testsuite.html'])).toThrow()
+ })
+
+ it('lib', () => {
+ const cwd = join(__dirname, '../cwd')
+ expect(() => jobFactory.fromCmdLine(cwd, [0, 0, '-libs:c=$NOT_EXISTING$/c'])).toThrow()
+ })
+ })
+
afterAll(() => {
expect(log.mock.calls.length).toStrictEqual(0)
expect(warn.mock.calls.length).toStrictEqual(0)
diff --git a/__tests__/src/simulate.js b/__tests__/src/simulate.js
index e9c7d95b..a5fc8f53 100644
--- a/__tests__/src/simulate.js
+++ b/__tests__/src/simulate.js
@@ -1,20 +1,3 @@
-jest.mock('child_process')
-jest.mock('../../src/output', () => {
- return {
- nyc: jest.fn(),
- monitor: jest.fn(),
- browserStart: jest.fn(),
- browserStopped: jest.fn(),
- endpoint: jest.fn(),
- endpointError: jest.fn(),
- timeSpent: jest.fn(),
- globalTimeout: jest.fn(),
- failFast: jest.fn(),
- noTestPageFound: jest.fn(),
- failedToCacheUI5resource: jest.fn(),
- results: jest.fn()
- }
-})
const { join } = require('path')
const { mock } = require('reserve')
const jobFactory = require('../../src/job')
diff --git a/__tests__/src/unhandled.js b/__tests__/src/unhandled.js
index f1e75275..c17aac20 100644
--- a/__tests__/src/unhandled.js
+++ b/__tests__/src/unhandled.js
@@ -1,18 +1,4 @@
-jest.mock('../../src/output', () => {
- return {
- unhandled: jest.fn()
- }
-})
const output = require('../../src/output')
-jest.mock('fs', () => {
- return {
- writeFile: jest.fn(),
- promises: {
- stat: jest.fn(),
- mkdir: jest.fn()
- }
- }
-})
const jobFactory = require('../../src/job')
const mappingFactory = require('../../src/unhandled')
@@ -22,12 +8,23 @@ describe('src/unhandled', () => {
let error
let unhandled
+ let unhandledCall = 0
+
+ function incUnhandledCall () {
+ ++unhandledCall
+ }
+
beforeAll(() => {
log = jest.spyOn(console, 'log').mockImplementation()
warn = jest.spyOn(console, 'warn').mockImplementation()
error = jest.spyOn(console, 'error').mockImplementation()
+ output.on('unhandled', incUnhandledCall)
+ })
+
+ beforeEach(() => {
const job = jobFactory.fromCmdLine('/', [])
unhandled = mappingFactory(job)[0].custom
+ unhandledCall = 0
})
const expectedIgnores = [
@@ -39,7 +36,7 @@ describe('src/unhandled', () => {
expectedIgnores.forEach(url => {
it(`does not log known GET patterns (${url})`, () => {
expect(unhandled({ method: 'GET', url })).toStrictEqual(404)
- expect(output.unhandled.mock.calls.length).toStrictEqual(0)
+ expect(unhandledCall).toStrictEqual(0)
})
})
@@ -47,19 +44,32 @@ describe('src/unhandled', () => {
'any-mock-data-file.json',
'sourceFile.js'
]
- expectedWarnings.forEach((url, index) => {
+ expectedWarnings.forEach(url => {
it(`warns about 404 GET (${url})`, () => {
expect(unhandled({ method: 'GET', url, headers: { referer: 'http://localhost:3475/test.html' } })).toStrictEqual(404)
- expect(output.unhandled.mock.calls.length).toStrictEqual(1)
+ expect(unhandledCall).toStrictEqual(1)
+ })
+ })
+ it('Warns only once', () => {
+ expectedWarnings.forEach(url => {
+ expect(unhandled({ method: 'GET', url, headers: { referer: 'http://localhost:3475/test.html' } })).toStrictEqual(404)
})
+ expect(unhandledCall).toStrictEqual(1)
})
it('logs errors for any other verb', () => {
expect(unhandled({ method: 'POST', url: '/any_url', headers: { referer: 'http://localhost:3475/test.html' } })).toStrictEqual(500)
- expect(output.unhandled.mock.calls.length).toStrictEqual(1)
+ expect(unhandledCall).toStrictEqual(1)
+ })
+
+ it('logs errors only once', () => {
+ expect(unhandled({ method: 'POST', url: '/any_url', headers: { referer: 'http://localhost:3475/test.html' } })).toStrictEqual(500)
+ expect(unhandled({ method: 'POST', url: '/any_other_url', headers: { referer: 'http://localhost:3475/test.html' } })).toStrictEqual(500)
+ expect(unhandledCall).toStrictEqual(1)
})
afterAll(() => {
+ output.off('unhandled', incUnhandledCall)
expect(log.mock.calls.length).toStrictEqual(0)
expect(warn.mock.calls.length).toStrictEqual(0)
expect(error.mock.calls.length).toStrictEqual(0)
diff --git a/index.js b/index.js
index dfc37e3d..271f2c4c 100644
--- a/index.js
+++ b/index.js
@@ -69,4 +69,4 @@ async function main () {
})
}
-main()
+main().catch(reason => output.genericError(reason))
diff --git a/package-lock.json b/package-lock.json
index 4b84e68b..bb05a33a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,25 +1,25 @@
{
"name": "ui5-test-runner",
- "version": "1.1.2",
+ "version": "1.1.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ui5-test-runner",
- "version": "1.1.2",
+ "version": "1.1.3",
"license": "MIT",
"dependencies": {
- "mime": "^2.5.2",
+ "mime": "^3.0.0",
"nyc": "^15.1.0",
- "puppeteer": "^10.4.0",
- "reserve": "^1.11.7"
+ "puppeteer": "^11.0.0",
+ "reserve": "^1.12.1"
},
"bin": {
"ui5-test-runner": "index.js"
},
"devDependencies": {
"jest": "^27.3.1",
- "nock": "^13.1.4",
+ "nock": "^13.2.1",
"standard": "^16.0.4"
},
"engines": {
@@ -2036,9 +2036,9 @@
}
},
"node_modules/debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dependencies": {
"ms": "2.1.2"
},
@@ -6232,14 +6232,14 @@
}
},
"node_modules/mime": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
- "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
+ "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
"bin": {
"mime": "cli.js"
},
"engines": {
- "node": ">=4.0.0"
+ "node": ">=10.0.0"
}
},
"node_modules/mime-db": {
@@ -6288,16 +6288,10 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
- "node_modules/mkdirp": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
- "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
- "dependencies": {
- "minimist": "^1.2.5"
- },
- "bin": {
- "mkdirp": "bin/cmd.js"
- }
+ "node_modules/mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
"node_modules/ms": {
"version": "2.1.2",
@@ -6311,9 +6305,9 @@
"dev": true
},
"node_modules/nock": {
- "version": "13.1.4",
- "resolved": "https://registry.npmjs.org/nock/-/nock-13.1.4.tgz",
- "integrity": "sha512-hr5+mknLpIbTOXifB13lx9mAKF1zQPUCMh53Galx79ic5opvNOd55jiB0iGCp2xqh+hwnFbNE/ddBKHsJNQrbw==",
+ "version": "13.2.1",
+ "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.1.tgz",
+ "integrity": "sha512-CoHAabbqq/xZEknubuyQMjq6Lfi5b7RtK6SoNK6m40lebGp3yiMagWtIoYaw2s9sISD7wPuCfwFpivVHX/35RA==",
"dev": true,
"dependencies": {
"debug": "^4.1.0",
@@ -6326,13 +6320,35 @@
}
},
"node_modules/node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
+ "version": "2.6.5",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
+ "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
"engines": {
"node": "4.x || >=6.0.0"
}
},
+ "node_modules/node-fetch/node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
+ },
+ "node_modules/node-fetch/node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
+ },
+ "node_modules/node-fetch/node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -7017,7 +7033,6 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "dev": true,
"engines": {
"node": ">=0.4.0"
}
@@ -7085,34 +7100,46 @@
}
},
"node_modules/puppeteer": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-10.4.0.tgz",
- "integrity": "sha512-2cP8mBoqnu5gzAVpbZ0fRaobBWZM8GEUF4I1F6WbgHrKV/rz7SX8PG2wMymZgD0wo0UBlg2FBPNxlF/xlqW6+w==",
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-11.0.0.tgz",
+ "integrity": "sha512-6rPFqN1ABjn4shgOICGDBITTRV09EjXVqhDERBDKwCLz0UyBxeeBH6Ay0vQUJ84VACmlxwzOIzVEJXThcF3aNg==",
"hasInstallScript": true,
"dependencies": {
- "debug": "4.3.1",
+ "debug": "4.3.2",
"devtools-protocol": "0.0.901419",
"extract-zip": "2.0.1",
"https-proxy-agent": "5.0.0",
- "node-fetch": "2.6.1",
+ "node-fetch": "2.6.5",
"pkg-dir": "4.2.0",
- "progress": "2.0.1",
+ "progress": "2.0.3",
"proxy-from-env": "1.1.0",
"rimraf": "3.0.2",
- "tar-fs": "2.0.0",
- "unbzip2-stream": "1.3.3",
- "ws": "7.4.6"
+ "tar-fs": "2.1.1",
+ "unbzip2-stream": "1.4.3",
+ "ws": "8.2.3"
},
"engines": {
"node": ">=10.18.1"
}
},
- "node_modules/puppeteer/node_modules/progress": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz",
- "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==",
+ "node_modules/puppeteer/node_modules/ws": {
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
+ "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
"engines": {
- "node": ">=0.4.0"
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
}
},
"node_modules/react-is": {
@@ -7290,9 +7317,9 @@
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"node_modules/reserve": {
- "version": "1.11.7",
- "resolved": "https://registry.npmjs.org/reserve/-/reserve-1.11.7.tgz",
- "integrity": "sha512-SDzr6dR+fIIZ9eqxXQRhclb4mpOqqY4wMKeehYfplj1MeOCPsF/skzr8Eo/dmNZK8ijuF3PMMvYQJzoV9bfzNQ==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/reserve/-/reserve-1.12.1.tgz",
+ "integrity": "sha512-JxnVNNgWwV7FYPIKC2JgJbaVfuiJsFV90Z6fUK3KB86zvGH6cyEdIbScr4c8n0ZXxOmISnaTj4Yb3+M8tTFPZA==",
"bin": {
"reserve": "index.js"
},
@@ -7890,14 +7917,14 @@
"dev": true
},
"node_modules/tar-fs": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz",
- "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
"dependencies": {
"chownr": "^1.1.1",
- "mkdirp": "^0.5.1",
+ "mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
- "tar-stream": "^2.0.0"
+ "tar-stream": "^2.1.4"
}
},
"node_modules/tar-stream": {
@@ -8099,9 +8126,9 @@
}
},
"node_modules/unbzip2-stream": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz",
- "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==",
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+ "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
"dependencies": {
"buffer": "^5.2.1",
"through": "^2.3.8"
@@ -8353,6 +8380,7 @@
"version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
+ "dev": true,
"engines": {
"node": ">=8.3.0"
},
@@ -10033,9 +10061,9 @@
}
},
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": {
"ms": "2.1.2"
}
@@ -13121,9 +13149,9 @@
}
},
"mime": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
- "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg=="
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
+ "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="
},
"mime-db": {
"version": "1.50.0",
@@ -13159,13 +13187,10 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
- "mkdirp": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
- "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
- "requires": {
- "minimist": "^1.2.5"
- }
+ "mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
"ms": {
"version": "2.1.2",
@@ -13179,9 +13204,9 @@
"dev": true
},
"nock": {
- "version": "13.1.4",
- "resolved": "https://registry.npmjs.org/nock/-/nock-13.1.4.tgz",
- "integrity": "sha512-hr5+mknLpIbTOXifB13lx9mAKF1zQPUCMh53Galx79ic5opvNOd55jiB0iGCp2xqh+hwnFbNE/ddBKHsJNQrbw==",
+ "version": "13.2.1",
+ "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.1.tgz",
+ "integrity": "sha512-CoHAabbqq/xZEknubuyQMjq6Lfi5b7RtK6SoNK6m40lebGp3yiMagWtIoYaw2s9sISD7wPuCfwFpivVHX/35RA==",
"dev": true,
"requires": {
"debug": "^4.1.0",
@@ -13191,9 +13216,33 @@
}
},
"node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
+ "version": "2.6.5",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
+ "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
+ "requires": {
+ "whatwg-url": "^5.0.0"
+ },
+ "dependencies": {
+ "tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
+ },
+ "webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
+ },
+ "whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
+ "requires": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ }
+ }
},
"node-int64": {
"version": "0.4.0",
@@ -13709,8 +13758,7 @@
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "dev": true
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
},
"prompts": {
"version": "2.4.2",
@@ -13766,28 +13814,29 @@
"dev": true
},
"puppeteer": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-10.4.0.tgz",
- "integrity": "sha512-2cP8mBoqnu5gzAVpbZ0fRaobBWZM8GEUF4I1F6WbgHrKV/rz7SX8PG2wMymZgD0wo0UBlg2FBPNxlF/xlqW6+w==",
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-11.0.0.tgz",
+ "integrity": "sha512-6rPFqN1ABjn4shgOICGDBITTRV09EjXVqhDERBDKwCLz0UyBxeeBH6Ay0vQUJ84VACmlxwzOIzVEJXThcF3aNg==",
"requires": {
- "debug": "4.3.1",
+ "debug": "4.3.2",
"devtools-protocol": "0.0.901419",
"extract-zip": "2.0.1",
"https-proxy-agent": "5.0.0",
- "node-fetch": "2.6.1",
+ "node-fetch": "2.6.5",
"pkg-dir": "4.2.0",
- "progress": "2.0.1",
+ "progress": "2.0.3",
"proxy-from-env": "1.1.0",
"rimraf": "3.0.2",
- "tar-fs": "2.0.0",
- "unbzip2-stream": "1.3.3",
- "ws": "7.4.6"
+ "tar-fs": "2.1.1",
+ "unbzip2-stream": "1.4.3",
+ "ws": "8.2.3"
},
"dependencies": {
- "progress": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz",
- "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg=="
+ "ws": {
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
+ "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
+ "requires": {}
}
}
},
@@ -13920,9 +13969,9 @@
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"reserve": {
- "version": "1.11.7",
- "resolved": "https://registry.npmjs.org/reserve/-/reserve-1.11.7.tgz",
- "integrity": "sha512-SDzr6dR+fIIZ9eqxXQRhclb4mpOqqY4wMKeehYfplj1MeOCPsF/skzr8Eo/dmNZK8ijuF3PMMvYQJzoV9bfzNQ=="
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/reserve/-/reserve-1.12.1.tgz",
+ "integrity": "sha512-JxnVNNgWwV7FYPIKC2JgJbaVfuiJsFV90Z6fUK3KB86zvGH6cyEdIbScr4c8n0ZXxOmISnaTj4Yb3+M8tTFPZA=="
},
"resolve": {
"version": "1.20.0",
@@ -14360,14 +14409,14 @@
}
},
"tar-fs": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz",
- "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
"requires": {
"chownr": "^1.1.1",
- "mkdirp": "^0.5.1",
+ "mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
- "tar-stream": "^2.0.0"
+ "tar-stream": "^2.1.4"
}
},
"tar-stream": {
@@ -14529,9 +14578,9 @@
}
},
"unbzip2-stream": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz",
- "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==",
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+ "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
"requires": {
"buffer": "^5.2.1",
"through": "^2.3.8"
@@ -14741,6 +14790,7 @@
"version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
+ "dev": true,
"requires": {}
},
"xdg-basedir": {
diff --git a/package.json b/package.json
index 587d0af1..b04c32de 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ui5-test-runner",
- "version": "1.1.2",
+ "version": "1.1.3",
"description": "Standalone test runner for UI5",
"main": "index.js",
"files": [
@@ -39,14 +39,14 @@
},
"homepage": "https://github.com/ArnaudBuchholz/ui5-test-runner#readme",
"dependencies": {
- "mime": "^2.5.2",
+ "mime": "^3.0.0",
"nyc": "^15.1.0",
- "puppeteer": "^10.4.0",
- "reserve": "^1.11.7"
+ "puppeteer": "^11.0.0",
+ "reserve": "^1.12.1"
},
"devDependencies": {
"jest": "^27.3.1",
- "nock": "^13.1.4",
+ "nock": "^13.2.1",
"standard": "^16.0.4"
},
"standard": {
@@ -58,6 +58,9 @@
]
},
"jest": {
+ "setupFilesAfterEnv": [
+ "./__mocks__/setup.js"
+ ],
"collectCoverage": true,
"collectCoverageFrom": [
"src/*.js"
diff --git a/src/coverage.js b/src/coverage.js
index 0f44087e..32dd587b 100644
--- a/src/coverage.js
+++ b/src/coverage.js
@@ -44,6 +44,15 @@ async function instrument (job) {
await createDir(join(job.covTempDir, 'settings'))
const settings = JSON.parse((await readFile(job.covSettings)).toString())
settings.cwd = job.cwd
+ if (!settings.exclude) {
+ settings.exclude = []
+ }
+ settings.exclude.push(join(job.covTempDir, '**'))
+ if (job.cache) {
+ settings.exclude.push(join(job.cache, '**'))
+ }
+ settings.exclude.push(join(job.tstReportDir, '**'))
+ settings.exclude.push(join(job.covReportDir, '**'))
await writeFile(job.nycSettingsPath, JSON.stringify(settings))
await nyc('instrument', job.webapp, join(job.covTempDir, 'instrumented'), '--nycrc-path', job.nycSettingsPath)
}
diff --git a/src/endpoints.js b/src/endpoints.js
index 3e7311cb..3f5f47f0 100644
--- a/src/endpoints.js
+++ b/src/endpoints.js
@@ -130,7 +130,7 @@ module.exports = job => {
job.testPages[url] = page
})
}, {
- // Endpoint to receive QUnit.testDone
+ // Endpoint to receive QUnit.log
match: '^/_/QUnit/log',
custom: synchronousEndpoint(async (url, report) => {
const page = job.testPages[url]
diff --git a/src/job.js b/src/job.js
index 6cfa9b8c..b4478da5 100644
--- a/src/job.js
+++ b/src/job.js
@@ -1,5 +1,6 @@
'use strict'
+const { accessSync } = require('fs')
const { join, isAbsolute } = require('path')
const output = require('./output')
@@ -12,6 +13,7 @@ function allocate (cwd) {
libs: [],
cache: '',
webapp: 'webapp',
+ testsuite: 'test/testsuite.qunit.html',
pageFilter: '',
pageParams: '',
pageTimeout: 0,
@@ -37,6 +39,14 @@ function allocate (cwd) {
}
}
+function checkAccess (path, label) {
+ try {
+ accessSync(path)
+ } catch (error) {
+ throw new Error(`Unable to access ${label}, check your settings`)
+ }
+}
+
function finalize (job) {
Object.keys(job)
.filter(name => name.startsWith('!'))
@@ -57,9 +67,15 @@ function finalize (job) {
'webapp,browser,tstReportDir,covSettings,covTempDir,covReportDir'
.split(',')
.forEach(setting => updateToAbsolute(setting))
+ checkAccess(job.webapp, 'webapp folder')
+ checkAccess(job.browser, 'browser command')
+
+ const testsuitePath = toAbsolute(job.testsuite, job.webapp)
+ checkAccess(testsuitePath, 'testsuite')
job.libs.forEach(libMapping => {
libMapping.source = toAbsolute(libMapping.source)
+ checkAccess(libMapping.source, `lib mapping of ${libMapping.relative}`)
})
if (job.parallel <= 0) {
diff --git a/src/output.js b/src/output.js
index 2c00177d..b30ad093 100644
--- a/src/output.js
+++ b/src/output.js
@@ -188,7 +188,7 @@ module.exports = {
console.error(`Unable to cache '${path}' (status ${statusCode})`)
},
genericError (error) {
- console.error('An unexpected error occurred', error)
+ console.error('An unexpected error occurred :', error.message || error)
},
unhandled () {
console.warn('Some requests are not handled properly, check the unhandled.txt report for more info')
diff --git a/src/tests.js b/src/tests.js
index 1e9acbb4..f0b9217e 100644
--- a/src/tests.js
+++ b/src/tests.js
@@ -26,7 +26,7 @@ async function extractTestPages (job) {
await saveJob(job)
job.status = 'Extracting test pages'
job.testPageUrls = []
- await start(job, '/test/testsuite.qunit.html')
+ await start(job, '/' + job.testsuite)
if (job.testPageUrls.length === 0) {
output.noTestPageFound()
job.failed = true