diff --git a/Gruntfile.js b/Gruntfile.js index b7a0bea0..40c3e787 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -580,6 +580,12 @@ module.exports = function(grunt) { ] } } + }, + 'run-test': { + options: { + headless: true + }, + default: 'test/runner.html' } }); }; diff --git a/build/tasks/grunt-run-test.js b/build/tasks/grunt-run-test.js new file mode 100644 index 00000000..d2794abd --- /dev/null +++ b/build/tasks/grunt-run-test.js @@ -0,0 +1,50 @@ +module.exports = function(grunt) { + grunt.registerMultiTask('run-test', 'Runs KeeWeb browser-tests', function() { + const done = this.async(); + const opt = this.options(); + const file = this.files[0].src[0]; + + const path = require('path'); + const puppeteer = require('puppeteer'); + + (async function() { + grunt.log.writeln('Running tests...'); + + const fullPath = 'file://' + path.resolve(file); + + const browser = await puppeteer.launch({ + headless: opt.headless + }); + const page = await browser.newPage(); + await page.goto(fullPath); + + async function check() { + const result = await page.evaluate(() => { + const { output, done } = window; + window.output = []; + return { output, done }; + }); + for (const out of result.output) { + if (!out.args.length) { + continue; + } + // eslint-disable-next-line no-console + console[out.method](...out.args); + } + if (result.done) { + const { failures } = result.done; + if (failures) { + grunt.warn(`Failed ${failures} test${failures > 1 ? 's' : ''}.`); + } else { + grunt.log.writeln('All tests passed'); + done(); + } + } else { + setTimeout(check, 100); + } + } + + check(); + })(); + }); +}; diff --git a/grunt.entrypoints.js b/grunt.entrypoints.js index eb89b9c6..4546fe08 100644 --- a/grunt.entrypoints.js +++ b/grunt.entrypoints.js @@ -1,6 +1,7 @@ module.exports = function(grunt) { // prettier-ignore grunt.registerTask('default', 'Default: build web app', [ + 'test', 'build-web-app' ]); @@ -17,6 +18,7 @@ module.exports = function(grunt) { // prettier-ignore grunt.registerTask('desktop', 'Build web and desktop apps for all platforms', [ + 'test', 'default', 'build-desktop' ]); @@ -29,6 +31,7 @@ module.exports = function(grunt) { // prettier-ignore grunt.registerTask('test', 'Build and run tests', [ - 'build-test' + 'build-test', + 'run-test' ]); }; diff --git a/package-lock.json b/package-lock.json index d58b09b9..b3c5c0e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1120,6 +1120,14 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, "aggregate-error": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.0.tgz", @@ -4170,6 +4178,19 @@ "is-symbol": "^1.0.2" } }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -7100,6 +7121,25 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, + "https-proxy-agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", + "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -10152,6 +10192,11 @@ "ipaddr.js": "1.9.0" } }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=" + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -10204,6 +10249,28 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, + "puppeteer": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", + "requires": { + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^2.2.1", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + }, + "dependencies": { + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + } + } + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", diff --git a/package.json b/package.json index 285fc651..e26b8fb0 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "pkcs15-smartcard-sign": "^1.0.0", "postcss-loader": "^3.0.0", "prettier": "^1.18.2", + "puppeteer": "^1.20.0", "raw-loader": "^3.1.0", "sass-loader": "^8.0.0", "stats-webpack-plugin": "0.7.0", diff --git a/test/runner.html b/test/runner.html new file mode 100644 index 00000000..4977c9b3 --- /dev/null +++ b/test/runner.html @@ -0,0 +1,33 @@ + + + + + KeeWeb Test Runner + + + + +
+ + + + + + + + + +