Improve yarn test-electron
experience
This commit is contained in:
parent
f9095d372a
commit
89fc7d2c0c
1 changed files with 94 additions and 80 deletions
174
Gruntfile.js
174
Gruntfile.js
|
@ -8,6 +8,7 @@ const mkdirp = require('mkdirp');
|
||||||
const spectron = require('spectron');
|
const spectron = require('spectron');
|
||||||
const asar = require('asar');
|
const asar = require('asar');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const sass = require('node-sass');
|
const sass = require('node-sass');
|
||||||
const packageJson = require('./package.json');
|
const packageJson = require('./package.json');
|
||||||
|
@ -15,6 +16,21 @@ const packageJson = require('./package.json');
|
||||||
/* eslint-disable more/no-then, no-console */
|
/* eslint-disable more/no-then, no-console */
|
||||||
|
|
||||||
module.exports = grunt => {
|
module.exports = grunt => {
|
||||||
|
async function promiseToAsyncGruntTask(promise, gruntDone) {
|
||||||
|
let succeeded = false;
|
||||||
|
try {
|
||||||
|
await promise;
|
||||||
|
succeeded = true;
|
||||||
|
} catch (err) {
|
||||||
|
grunt.log.error(err);
|
||||||
|
}
|
||||||
|
if (succeeded) {
|
||||||
|
gruntDone();
|
||||||
|
} else {
|
||||||
|
gruntDone(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const bower = grunt.file.readJSON('bower.json');
|
const bower = grunt.file.readJSON('bower.json');
|
||||||
const components = [];
|
const components = [];
|
||||||
// eslint-disable-next-line guard-for-in, no-restricted-syntax
|
// eslint-disable-next-line guard-for-in, no-restricted-syntax
|
||||||
|
@ -171,15 +187,14 @@ module.exports = grunt => {
|
||||||
mkdirp.sync('release');
|
mkdirp.sync('release');
|
||||||
});
|
});
|
||||||
|
|
||||||
function runTests(environment, cb) {
|
async function runTests(environment) {
|
||||||
let failure;
|
|
||||||
const { Application } = spectron;
|
const { Application } = spectron;
|
||||||
const electronBinary =
|
const electronBinary =
|
||||||
process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
||||||
|
|
||||||
const path = join(__dirname, 'node_modules', '.bin', electronBinary);
|
const path = join(__dirname, 'node_modules', '.bin', electronBinary);
|
||||||
const args = [join(__dirname, 'main.js')];
|
const args = [join(__dirname, 'main.js')];
|
||||||
console.log('Starting path', path, 'with args', args);
|
grunt.log.writeln('Starting path', path, 'with args', args);
|
||||||
const app = new Application({
|
const app = new Application({
|
||||||
path,
|
path,
|
||||||
args,
|
args,
|
||||||
|
@ -194,78 +209,81 @@ module.exports = grunt => {
|
||||||
return window.mochaResults;
|
return window.mochaResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
app
|
async function logForFailure() {
|
||||||
.start()
|
const temporaryDirectory = join(
|
||||||
.then(() => {
|
os.tmpdir(),
|
||||||
console.log('App started. Now waiting for test results...');
|
`Signal-Desktop-tests--${Date.now()}-${Math.random()
|
||||||
return app.client.waitUntil(
|
.toString()
|
||||||
() =>
|
.slice(2)}`
|
||||||
app.client
|
);
|
||||||
.execute(getMochaResults)
|
const renderProcessLogPath = join(
|
||||||
.then(data => Boolean(data.value)),
|
temporaryDirectory,
|
||||||
25000,
|
'render-process.log'
|
||||||
'Expected to find window.mochaResults set!'
|
);
|
||||||
);
|
const mainProcessLogPath = join(temporaryDirectory, 'main-process.log');
|
||||||
})
|
|
||||||
.then(() => app.client.execute(getMochaResults))
|
|
||||||
.then(data => {
|
|
||||||
const results = data.value;
|
|
||||||
if (!results) {
|
|
||||||
failure = () => grunt.fail.fatal("Couldn't extract test results.");
|
|
||||||
return app.client.log('browser');
|
|
||||||
}
|
|
||||||
if (results.failures > 0) {
|
|
||||||
console.error(results.reports);
|
|
||||||
failure = () =>
|
|
||||||
grunt.fail.fatal(`Found ${results.failures} failing unit tests.`);
|
|
||||||
return app.client.log('browser');
|
|
||||||
}
|
|
||||||
grunt.log.ok(`${results.passes} tests passed.`);
|
|
||||||
return null;
|
|
||||||
})
|
|
||||||
.then(logs => {
|
|
||||||
if (logs) {
|
|
||||||
console.error();
|
|
||||||
console.error('Because tests failed, printing browser logs:');
|
|
||||||
console.error(logs);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
failure = () =>
|
|
||||||
grunt.fail.fatal(
|
|
||||||
`Something went wrong: ${error.message} ${error.stack}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// We need to use the failure variable and this early stop to clean up before
|
|
||||||
// shutting down. Grunt's fail methods are the only way to set the return value,
|
|
||||||
// but they shut the process down immediately!
|
|
||||||
if (failure) {
|
|
||||||
console.log();
|
|
||||||
console.log('Main process logs:');
|
|
||||||
return app.client.getMainProcessLogs().then(logs => {
|
|
||||||
logs.forEach(log => {
|
|
||||||
console.log(log);
|
|
||||||
});
|
|
||||||
|
|
||||||
return app.stop();
|
await fs.promises.mkdir(temporaryDirectory, { recursive: true });
|
||||||
});
|
|
||||||
}
|
await Promise.all([
|
||||||
return app.stop();
|
(async () => {
|
||||||
})
|
const logs = await app.client.getRenderProcessLogs();
|
||||||
.then(() => {
|
await fs.promises.writeFile(
|
||||||
if (failure) {
|
renderProcessLogPath,
|
||||||
failure();
|
logs.map(log => JSON.stringify(log)).join('\n')
|
||||||
}
|
);
|
||||||
cb();
|
})(),
|
||||||
})
|
(async () => {
|
||||||
.catch(error => {
|
const logs = await app.client.getMainProcessLogs();
|
||||||
console.error('Second-level error:', error.message, error.stack);
|
await fs.promises.writeFile(mainProcessLogPath, logs.join('\n'));
|
||||||
if (failure) {
|
})(),
|
||||||
failure();
|
]);
|
||||||
}
|
|
||||||
cb();
|
console.error();
|
||||||
});
|
grunt.log.error(
|
||||||
|
`Renderer process logs written to ${renderProcessLogPath}`
|
||||||
|
);
|
||||||
|
grunt.log.error(`Renderer process logs written to ${mainProcessLogPath}`);
|
||||||
|
grunt.log.error(
|
||||||
|
`For easier debugging, try NODE_ENV='${environment}' yarn start`
|
||||||
|
);
|
||||||
|
console.error();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await app.start();
|
||||||
|
|
||||||
|
grunt.log.writeln('App started. Now waiting for test results...');
|
||||||
|
await app.client.waitUntil(
|
||||||
|
() =>
|
||||||
|
app.client.execute(getMochaResults).then(data => Boolean(data.value)),
|
||||||
|
25000,
|
||||||
|
'Expected to find window.mochaResults set!'
|
||||||
|
);
|
||||||
|
|
||||||
|
const results = (await app.client.execute(getMochaResults)).value;
|
||||||
|
if (!results) {
|
||||||
|
await logForFailure();
|
||||||
|
throw new Error("Couldn't extract test results");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.failures > 0) {
|
||||||
|
const errorMessage = `Found ${results.failures} failing test${
|
||||||
|
results.failures === 1 ? '' : 's'
|
||||||
|
}.`;
|
||||||
|
grunt.log.error(errorMessage);
|
||||||
|
results.reports.forEach(report => {
|
||||||
|
grunt.log.error(JSON.stringify(report, null, 2));
|
||||||
|
});
|
||||||
|
await logForFailure();
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
grunt.log.ok(`${results.passes} tests passed.`);
|
||||||
|
} finally {
|
||||||
|
if (app.isRunning()) {
|
||||||
|
await app.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grunt.registerTask(
|
grunt.registerTask(
|
||||||
|
@ -273,9 +291,7 @@ module.exports = grunt => {
|
||||||
'Run unit tests w/Electron',
|
'Run unit tests w/Electron',
|
||||||
function thisNeeded() {
|
function thisNeeded() {
|
||||||
const environment = grunt.option('env') || 'test';
|
const environment = grunt.option('env') || 'test';
|
||||||
const done = this.async();
|
promiseToAsyncGruntTask(runTests(environment), this.async());
|
||||||
|
|
||||||
runTests(environment, done);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -284,9 +300,7 @@ module.exports = grunt => {
|
||||||
'Run libtextsecure unit tests w/Electron',
|
'Run libtextsecure unit tests w/Electron',
|
||||||
function thisNeeded() {
|
function thisNeeded() {
|
||||||
const environment = grunt.option('env') || 'test-lib';
|
const environment = grunt.option('env') || 'test-lib';
|
||||||
const done = this.async();
|
promiseToAsyncGruntTask(runTests(environment), this.async());
|
||||||
|
|
||||||
runTests(environment, done);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue