spectron
Version:
Easily test your Electron apps using ChromeDriver and WebdriverIO.
140 lines (115 loc) • 3.44 kB
JavaScript
const ChildProcess = require('child_process');
const path = require('path');
const { default: got } = require('got');
const split = require('split');
function ChromeDriver(
host,
port,
nodePath,
startTimeout,
workingDirectory,
chromeDriverLogPath
) {
this.host = host;
this.port = port;
this.nodePath = nodePath;
this.startTimeout = startTimeout;
this.workingDirectory = workingDirectory;
this.chromeDriverLogPath = chromeDriverLogPath;
this.path = require.resolve('electron-chromedriver/chromedriver');
this.urlBase = '/';
this.statusUrl =
'http://' + this.host + ':' + this.port + this.urlBase + 'status';
this.logLines = [];
}
ChromeDriver.prototype.start = function () {
if (this.process) throw new Error('ChromeDriver already started');
const args = [this.path, '--port=' + this.port, '--url-base=' + this.urlBase];
if (this.chromeDriverLogPath) {
args.push('--verbose');
args.push('--log-path=' + this.chromeDriverLogPath);
}
const options = {
cwd: this.workingDirectory,
env: this.getEnvironment()
};
this.process = ChildProcess.spawn(this.nodePath, args, options);
const self = this;
this.exitHandler = function () {
self.stop();
};
global.process.on('exit', this.exitHandler);
this.setupLogs();
return this.waitUntilRunning();
};
ChromeDriver.prototype.waitUntilRunning = function () {
const self = this;
return new Promise(function (resolve, reject) {
const startTime = Date.now();
const checkIfRunning = function () {
self.isRunning(function (running) {
if (!self.process) {
return reject(Error('ChromeDriver has been stopped'));
}
if (running) {
return resolve();
}
const elapsedTime = Date.now() - startTime;
if (elapsedTime > self.startTimeout) {
return reject(
Error(
'ChromeDriver did not start within ' + self.startTimeout + 'ms'
)
);
}
global.setTimeout(checkIfRunning, 100);
});
};
checkIfRunning();
});
};
ChromeDriver.prototype.setupLogs = function () {
const linesToIgnore = 2; // First two lines are ChromeDriver specific
let lineCount = 0;
this.logLines = [];
const self = this;
this.process.stdout.pipe(split()).on('data', function (line) {
if (lineCount < linesToIgnore) {
lineCount++;
return;
}
self.logLines.push(line);
});
};
ChromeDriver.prototype.getEnvironment = function () {
const env = {};
Object.keys(process.env).forEach(function (key) {
env[key] = process.env[key];
});
if (process.platform === 'win32') {
env.SPECTRON_NODE_PATH = process.execPath;
env.SPECTRON_LAUNCHER_PATH = path.join(__dirname, 'launcher.js');
}
return env;
};
ChromeDriver.prototype.stop = function () {
if (this.exitHandler) global.process.removeListener('exit', this.exitHandler);
this.exitHandler = null;
if (this.process) this.process.kill();
this.process = null;
this.clearLogs();
};
ChromeDriver.prototype.isRunning = function (callback) {
const cb = false;
got(this.statusUrl)
.json()
.then(({ value }) => callback(value && value.ready))
.catch(() => callback(cb));
};
ChromeDriver.prototype.getLogs = function () {
return this.logLines.slice();
};
ChromeDriver.prototype.clearLogs = function () {
this.logLines = [];
};
module.exports = ChromeDriver;