creevey
Version:
Cross-browser screenshot testing tool for Storybook with fancy UI Runner
122 lines • 4.64 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.pullImages = pullImages;
exports.runImage = runImage;
exports.initDocker = initDocker;
const cluster_1 = __importDefault(require("cluster"));
const ora_1 = __importDefault(require("ora"));
const stream_1 = require("stream");
const dockerode_1 = __importDefault(require("dockerode"));
const types_js_1 = require("../types.js");
const messages_js_1 = require("./messages.js");
const utils_js_1 = require("./utils.js");
const logger_js_1 = require("./logger.js");
const docker = new dockerode_1.default();
class DevNull extends stream_1.Writable {
_write(_chunk, _encoding, callback) {
setImmediate(callback);
}
}
async function pullImages(images, { auth, platform } = {}) {
const args = {};
if (auth)
args.authconfig = auth;
if (platform)
args.platform = platform;
(0, logger_js_1.logger)().info('Pull docker images');
for (const image of images) {
await new Promise((resolve, reject) => {
const spinner = (0, ora_1.default)(`${image}: Pull start`).start();
docker.pull(image, args, (pullError, stream) => {
if (pullError || !stream) {
spinner.fail();
reject(pullError ?? new Error('Unknown error'));
return;
}
docker.modem.followProgress(stream, onFinished, onProgress);
function onFinished(error) {
if (error) {
spinner.fail();
reject(error);
return;
}
spinner.succeed(`${image}: Pull complete`);
resolve();
}
function onProgress(event) {
if (!/^[a-z0-9]{12}$/i.test(event.id))
return;
spinner.text = `${image}: [${event.id}] ${event.status} ${event.progress ? event.progress : ''}`;
}
});
});
}
}
async function runImage(image, args, options, debug) {
await Promise.all((await docker.listContainers({ all: true, filters: { ancestor: [image] } })).map(async (info) => {
const container = docker.getContainer(info.Id);
try {
await container.stop();
}
catch {
/* noop */
}
await container.remove();
}));
const hub = docker.run(image, args, debug ? process.stdout : new DevNull(), options, (error) => {
if (error)
throw error;
});
return new Promise((resolve) => {
hub.once('container', (container) => {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
(0, messages_js_1.subscribeOn)('shutdown', async () => {
try {
await container.stop();
await container.remove();
}
catch {
/* noop */
}
});
});
hub.once('start', (container) => void container.inspect().then((info) => {
resolve(info.NetworkSettings.Networks.bridge.IPAddress);
}));
});
}
async function initDocker(config, browser, startContainer) {
if (cluster_1.default.isPrimary) {
const host = await startContainer();
let gridUrl = 'http://localhost:4444/wd/hub';
gridUrl = utils_js_1.isInsideDocker ? gridUrl.replace(utils_js_1.LOCALHOST_REGEXP, host) : gridUrl;
cluster_1.default.on('message', (worker, message) => {
if (!(0, types_js_1.isDockerMessage)(message))
return;
const dockerMessage = message;
if (dockerMessage.type != 'start')
return;
(0, messages_js_1.sendDockerMessage)(worker, {
type: 'success',
payload: { gridUrl },
});
});
}
else {
if (browser && config.browsers[browser].gridUrl)
return Promise.resolve();
return new Promise((resolve) => {
(0, messages_js_1.subscribeOn)('docker', (message) => {
if (message.type == 'success') {
config.gridUrl = message.payload.gridUrl;
resolve();
}
});
(0, messages_js_1.emitDockerMessage)({ type: 'start' });
});
}
}
//# sourceMappingURL=docker.js.map