diff --git a/test/electron/index.js b/test/electron/index.js new file mode 100644 index 00000000000..33adf0ac7b1 --- /dev/null +++ b/test/electron/index.js @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const { app, BrowserWindow, ipcMain } = require('electron'); +const { tmpdir } = require('os'); +const { join } = require('path'); + +const optimist = require('optimist') + .describe('grep', 'only run tests matching ').string('grep').alias('grep', 'g').string('g') + .describe('debug', 'open dev tools, keep window open').string('debug'); + +const { debug, grep } = optimist.argv; + +app.setPath('userData', join(tmpdir(), `vscode-tests-${Date.now()}`)); + +app.on('ready', () => { + + const win = new BrowserWindow({ + height: 600, + width: 800, + webPreferences: { webSecurity: false } + }); + + win.webContents.on('did-finish-load', () => { + win.show(); + if (debug) { + win.webContents.openDevTools('right'); + } + }); + + const query = grep + ? `?grep=${grep}` + : ''; + + win.loadURL(`file://${__dirname}/renderer.html${query}`); + + const _failures = []; + ipcMain.on('fail', (e, test) => { + _failures.push(test); + process.stdout.write('X'); + }); + ipcMain.on('pass', () => { + process.stdout.write('.'); + }); + + ipcMain.on('done', () => { + + console.log(`\nDone with ${_failures.length} failures.\n`); + + for (const fail of _failures) { + console.error(fail.title); + console.error(fail.stack); + console.error('\n'); + } + + if (!debug) { + app.exit(_failures.length > 0 ? 1 : 0); + } + }); +}); diff --git a/test/electron/renderer.html b/test/electron/renderer.html new file mode 100644 index 00000000000..c51d58f1bdc --- /dev/null +++ b/test/electron/renderer.html @@ -0,0 +1,19 @@ + + + + + VSCode Tests + + + + +
+ + + + + diff --git a/test/electron/renderer.js b/test/electron/renderer.js new file mode 100644 index 00000000000..cc34030d520 --- /dev/null +++ b/test/electron/renderer.js @@ -0,0 +1,98 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/*eslint-env mocha*/ + +const { ipcRenderer } = require('electron'); +const assert = require('assert'); +const glob = require('glob'); +const path = require('path'); +const loader = require('../../src/vs/loader'); +const cwd = path.join(__dirname, '../../out'); + +loader.require.config({ + baseUrl: cwd, + catchError: true, + nodeRequire: require, + nodeMain: __filename +}); + +function loadTestModules() { + return new Promise((resolve, reject) => { + glob('**/test/**/*.test.js', { cwd }, (err, files) => { + if (err) { + reject(err); + return; + } + const modules = files.map(file => file.replace(/\.js$/, '')); + resolve(modules); + }); + }).then(modules => { + return new Promise((resolve, reject) => { + loader.require(modules, resolve, reject); + }); + }); +} + +function loadTests() { + + const _unexpectedErrors = []; + const _loaderErrors = []; + + // collect loader errors + loader.require.config({ + onError(err) { + _loaderErrors.push(err); + console.error(err); + } + }); + + // collect unexpected errors + loader.require(['vs/base/common/errors'], function (errors) { + errors.setUnexpectedErrorHandler(function (err) { + try { + throw new Error('oops'); + } catch (e) { + _unexpectedErrors.push((err && err.message ? err.message : err) + '\n' + e.stack); + } + }); + }); + + return loadTestModules().then(() => { + suite('Unexpected Errors & Loader Errors', function () { + test('should not have unexpected errors', function () { + const errors = _unexpectedErrors.concat(_loaderErrors); + if (errors.length) { + errors.forEach(function (stack) { + console.error(''); + console.error(stack); + }); + assert.ok(false); + } + }); + }); + }); +} + +module.exports.runTests = function () { + + return loadTests().then(() => { + + const runner = mocha.run(() => { + ipcRenderer.send('done'); + }); + + runner.on('fail', function (test) { + ipcRenderer.send('fail', { + title: test.fullTitle(), + stack: test.err.stack + }); + }); + + runner.on('pass', function () { + ipcRenderer.send('pass'); + }); + }); +};