creevey
Version:
Cross-browser screenshot testing tool for Storybook with fancy UI Runner
170 lines (138 loc) • 5.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.startSelenoidStandalone = startSelenoidStandalone;
exports.startSelenoidContainer = startSelenoidContainer;
var _path = _interopRequireDefault(require("path"));
var _util = require("util");
var _fs = require("fs");
var _utils = require("../utils");
var _docker = require("../docker");
var _core = require("@octokit/core");
var _messages = require("../messages");
var _cluster = require("cluster");
var _shelljs = require("shelljs");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const mkdirAsync = (0, _util.promisify)(_fs.mkdir);
const writeFileAsync = (0, _util.promisify)(_fs.writeFile);
const copyFileAsync = (0, _util.promisify)(_fs.copyFile);
async function createSelenoidConfig(browsers, {
useDocker
}) {
const selenoidConfig = {};
const selenoidConfigDir = _path.default.join((0, _utils.getCreeveyCache)(), 'selenoid');
browsers.forEach(({
browserName,
version = 'latest',
dockerImage = `selenoid/${browserName}:${version}`,
webdriverCommand = []
}) => {
if (!selenoidConfig[browserName]) selenoidConfig[browserName] = {
default: version,
versions: {}
};
if (!useDocker && webdriverCommand.length == 0) throw new Error('Please specify "webdriverCommand" browser option with path to browser webdriver');
selenoidConfig[browserName].versions[version] = {
image: useDocker ? dockerImage : webdriverCommand,
port: '4444',
path: !useDocker || browserName == 'chrome' || browserName == 'opera' ? '/' : '/wd/hub'
};
});
await mkdirAsync(selenoidConfigDir, {
recursive: true
});
await writeFileAsync(_path.default.join(selenoidConfigDir, 'browsers.json'), JSON.stringify(selenoidConfig));
return selenoidConfigDir;
}
async function downloadSelenoidBinary(destination) {
var _assets$find;
const platformNameMapping = {
darwin: 'selenoid_darwin_amd64',
linux: 'selenoid_linux_amd64',
win32: 'selenoid_windows_amd64.exe'
};
const octokit = new _core.Octokit();
const response = await octokit.request('GET /repos/{owner}/{repo}/releases/latest', {
owner: 'aerokube',
repo: 'selenoid'
});
const {
assets
} = response.data;
const {
browser_download_url: downloadUrl,
size: binarySize
} = (_assets$find = assets.find(({
name
}) => platformNameMapping[process.platform] == name)) !== null && _assets$find !== void 0 ? _assets$find : {};
if ((0, _fs.existsSync)(destination) && (0, _fs.lstatSync)(destination).size == binarySize) return;
if (!downloadUrl) {
throw new Error(`Couldn't get download url for selenoid binary. Please download it manually from "https://github.com/aerokube/selenoid/releases/latest" and define "selenoidPath" option in the Creevey config`);
}
return (0, _utils.downloadBinary)(downloadUrl, destination);
}
async function startSelenoidStandalone(config, debug) {
config.gridUrl = 'http://localhost:4444/wd/hub';
if (_cluster.isWorker) return;
const browsers = Object.values(config.browsers).filter(browser => !browser.gridUrl);
const selenoidConfigDir = await createSelenoidConfig(browsers, {
useDocker: false
});
const binaryPath = _path.default.join(selenoidConfigDir, process.platform == 'win32' ? 'selenoid.exe' : 'selenoid');
if (config.selenoidPath) {
await copyFileAsync(_path.default.resolve(config.selenoidPath), binaryPath);
} else {
await downloadSelenoidBinary(binaryPath);
} // TODO Download browser webdrivers
try {
if (process.platform != 'win32') (0, _shelljs.chmod)('+x', binaryPath);
} catch (_) {
/* noop */
}
const selenoidProcess = (0, _shelljs.exec)(`${binaryPath} -conf ./browsers.json -disable-docker`, {
async: true,
cwd: selenoidConfigDir
});
if (debug) {
var _selenoidProcess$stdo, _selenoidProcess$stde;
(_selenoidProcess$stdo = selenoidProcess.stdout) === null || _selenoidProcess$stdo === void 0 ? void 0 : _selenoidProcess$stdo.pipe(process.stdout);
(_selenoidProcess$stde = selenoidProcess.stderr) === null || _selenoidProcess$stde === void 0 ? void 0 : _selenoidProcess$stde.pipe(process.stderr);
}
(0, _messages.subscribeOn)('shutdown', () => selenoidProcess.kill());
}
async function startSelenoidContainer(config, debug) {
const browsers = Object.values(config.browsers).filter(browser => !browser.gridUrl);
const images = [];
let limit = 0;
browsers.forEach(({
browserName,
version = 'latest',
limit: browserLimit = 1,
dockerImage = `selenoid/${browserName}:${version}`
}) => {
limit += browserLimit;
images.push(dockerImage);
});
const selenoidImage = config.dockerImage;
if (config.pullImages) {
await (0, _docker.pullImages)([selenoidImage]);
await (0, _docker.pullImages)(images, config.dockerAuth);
} // TODO Allow pass custom options
const selenoidOptions = {
ExposedPorts: {
'4444/tcp': {}
},
HostConfig: {
PortBindings: {
'4444/tcp': [{
HostPort: '4444'
}]
},
Binds: ['/var/run/docker.sock:/var/run/docker.sock', `${await createSelenoidConfig(browsers, {
useDocker: true
})}:/etc/selenoid/:ro`]
}
};
return (0, _docker.runImage)(selenoidImage, ['-limit', String(limit)], selenoidOptions, debug);
}