Я почти наверняка обойду это неправильно, поэтому сначала выполним требования высокого уровня.Выполнение синхронной задачи последовательности выполнения никогда не завершается
Я использую angular2-seed и хочу запустить тесты проталкивателя в режиме безглавых с помощью Xvfb. Я не хочу, чтобы сервер Xvfb работал постоянно (это сервер сборки), поэтому вместо этого я хотел бы раскрутить службу Xvfb, сделать это, и затем «изящно» закрыть Xvfb. В изоляции эти задачи работают нормально, однако я ударил стену, когда дело доходило до их добавления в настройку сборки gulp.
Вот задача в gulpfile:
gulp.task('e2e.headless', (done: any) =>
runSequence('start.xvfb',
'protractor',
'stop.xvfb',
done));
Задачи сами загружаются через файлы задачи индивидуальной машинописи, то есть:
import {runProtractor} from '../../utils';
export = runProtractor
А вот моя (последняя) утилита самих файлов.
protractor.ts
import * as util from 'gulp-util';
import {normalize, join} from 'path';
import {ChildProcess} from 'child_process';
function reportError(message: string) {
console.error(require('chalk').white.bgRed.bold(message));
process.exit(1);
}
function promiseFromChildProcess(child: ChildProcess) {
return new Promise(function (resolve:() => void, reject:() => void) {
child.on('close', (code: any) => {
util.log('Exited with code: ', code);
resolve();
});
child.stdout.on('data', (data: any) => {
util.log(`stdout: ${data}`);
});
child.stderr.on('data', (data: any) => {
util.log(`stderr: ${data}`);
reject();
});
});
}
export function runProtractor(): (done:() => void) => void {
return done => {
const root = normalize(join(__dirname, '..', '..', '..'));
const exec = require('child_process').exec;
// Our Xvfb instance is running on :99
// TODO: Pass this in instead of hard-coding
process.env.DISPLAY=':99';
util.log('cwd:', root);
let child = exec('protractor', { cwd: root, env: process.env},
function (error: Error, stdout: NodeBuffer, stderr: NodeBuffer) {
if (error !== null) {
reportError('Protractor error: ' + error + stderr);
}
});
promiseFromChildProcess(child).then(() => done());
};
}
xvfb_tools.ts
import * as util from 'gulp-util';
const exec = require('child_process').exec;
function reportError(message: string) {
console.error(require('chalk').white.bgRed.bold(message));
process.exit(1);
}
export function stopXvfb() {
return exec('pkill -c -n Xvfb',
function (error: NodeJS.ErrnoException, stdout: NodeBuffer, stderr: NodeBuffer) {
if (error !== null) {
reportError('Failed to kill Xvfb. Not really sure why...');
} else if (stdout.toString() === '0') {
reportError('No known Xvfb instance. Is it running?');
} else {
util.log('Xvfb terminated');
}
});
}
export function startXvfb() {
return exec('Xvfb :99 -ac -screen 0 1600x1200x24',
function (error: NodeJS.ErrnoException, stdout: NodeBuffer, stderr: NodeBuffer) {
if (error !== null && error.code !== null) {
reportError('Xvfb failed to start. Err: ' + error.code + ', ' + error + ', ' + stderr);
}
});
}
Я чувствую, что я, вероятно, вокруг домов в создании обещание от моего exec
child_process, однако ранние взаимодействия кода не выполнялись it, so ... Обратите внимание, что журнал отладки, который должен выводиться в runProtractor()
, отображающий корневую директорию, никогда не вызывается, поэтому я совершенно уверен, что здесь есть проблема с асинхронным воспроизведением. Вот вывод из задачи:
[00:47:49] Starting 'e2e.headless'...
[00:47:49] Starting 'start.xvfb'...
[00:47:49] Finished 'start.xvfb' after 12 ms
[00:47:49] Starting 'protractor'...
[00:47:49] Finished 'protractor' after 5.74 ms
[00:47:49] Starting 'stop.xvfb'...
[00:47:49] Finished 'stop.xvfb' after 11 ms
[00:47:49] Finished 'e2e.headless' after 38 ms
[00:47:49] Xvfb terminated
Может кто-нибудь меня прямо посадить/направить меня в правильном направлении?
это не то, что 'done' для в моей текущей задаче? – GMeister
Да, Выполнено? – Vish
Это не было, см. Мой ответ за то, почему - спасибо – GMeister