creevey
Version:
Cross-browser screenshot testing tool for Storybook with fancy UI Runner
149 lines (122 loc) • 5.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.shouldSkip = shouldSkip;
exports.shutdownWorkers = shutdownWorkers;
exports.getCreeveyCache = getCreeveyCache;
exports.runSequence = runSequence;
exports.testsToImages = testsToImages;
exports.removeProps = removeProps;
exports.downloadBinary = exports.isInsideDocker = exports.extensions = exports.LOCALHOST_REGEXP = exports.isShuttingDown = void 0;
var _fs = require("fs");
var _cluster = _interopRequireDefault(require("cluster"));
var _types = require("../types");
var _messages = require("./messages");
var _findCacheDir = _interopRequireDefault(require("find-cache-dir"));
var _https = require("https");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const isShuttingDown = {
current: false
};
exports.isShuttingDown = isShuttingDown;
const LOCALHOST_REGEXP = /(localhost|127\.0\.0\.1)/i;
exports.LOCALHOST_REGEXP = LOCALHOST_REGEXP;
const extensions = ['.js', '.jsx', '.ts', '.tsx'];
exports.extensions = extensions;
function matchBy(pattern, value) {
return typeof pattern == 'string' && pattern == value || Array.isArray(pattern) && pattern.includes(value) || pattern instanceof RegExp && pattern.test(value) || !(0, _types.isDefined)(pattern);
}
function shouldSkip(browser, meta, skipOptions, test) {
if (typeof skipOptions != 'object') {
return skipOptions;
}
if (Array.isArray(skipOptions)) {
return skipOptions.map(skipOption => shouldSkip(browser, meta, skipOption, test)).find(Boolean) || false;
}
const {
in: browsers,
kinds,
stories,
tests,
reason = true
} = skipOptions;
const {
kind,
story
} = meta;
const skipByBrowser = matchBy(browsers, browser);
const skipByKind = matchBy(kinds, kind);
const skipByStory = matchBy(stories, story);
const skipByTest = !(0, _types.isDefined)(test) || matchBy(tests, test);
return skipByBrowser && skipByKind && skipByStory && skipByTest && reason;
}
async function shutdownWorkers() {
isShuttingDown.current = true;
await Promise.all(Object.values(_cluster.default.workers).filter(_types.isDefined).filter(worker => worker.isConnected()).map(worker => new Promise(resolve => {
const timeout = setTimeout(() => worker.kill(), 10000);
worker.on('exit', () => {
clearTimeout(timeout);
resolve();
});
(0, _messages.sendShutdownMessage)(worker);
})));
(0, _messages.emitShutdownMessage)();
}
function getCreeveyCache() {
return (0, _findCacheDir.default)({
name: 'creevey',
cwd: __dirname
});
}
async function runSequence(seq, predicate) {
for (const fn of seq) {
if (predicate()) await fn();
}
}
function testsToImages(tests) {
return new Set([].concat(...tests.filter(_types.isDefined).map(({
browser,
testName,
storyPath,
results
}) => {
var _results$slice$0$imag, _results$slice$;
return Object.keys((_results$slice$0$imag = results === null || results === void 0 ? void 0 : (_results$slice$ = results.slice(-1)[0]) === null || _results$slice$ === void 0 ? void 0 : _results$slice$.images) !== null && _results$slice$0$imag !== void 0 ? _results$slice$0$imag : {}).map(image => `${[...storyPath, testName, browser, browser == image ? undefined : image].filter(_types.isDefined).join('/')}.png`);
})));
} // https://tuhrig.de/how-to-know-you-are-inside-a-docker-container/
const isInsideDocker = (0, _fs.existsSync)('/proc/1/cgroup') && /docker/.test((0, _fs.readFileSync)('/proc/1/cgroup', 'utf8'));
exports.isInsideDocker = isInsideDocker;
const downloadBinary = (downloadUrl, destination) => new Promise((resolve, reject) => (0, _https.get)(downloadUrl, response => {
var _response$statusCode2;
if (response.statusCode == 302) {
var _response$statusCode;
const {
location
} = response.headers;
if (!location) return reject(new Error(`Couldn't download selenoid. Status code: ${(_response$statusCode = response.statusCode) !== null && _response$statusCode !== void 0 ? _response$statusCode : 'UNKNOWN'}`));
return resolve(downloadBinary(location, destination));
}
if (response.statusCode != 200) return reject(new Error(`Couldn't download selenoid. Status code: ${(_response$statusCode2 = response.statusCode) !== null && _response$statusCode2 !== void 0 ? _response$statusCode2 : 'UNKNOWN'}`));
const fileStream = (0, _fs.createWriteStream)(destination);
response.pipe(fileStream);
fileStream.on('finish', () => {
fileStream.close();
resolve();
});
fileStream.on('error', error => {
(0, _fs.unlink)(destination, _types.noop);
reject(error);
});
}));
exports.downloadBinary = downloadBinary;
function removeProps(obj, propPath) {
const [prop, ...restPath] = propPath;
if (restPath.length > 0) {
if (typeof prop == 'string') obj[prop] && removeProps(obj[prop], restPath);
if ((0, _types.isFunction)(prop)) Object.keys(obj).filter(prop).forEach(key => obj[key] && removeProps(obj[key], restPath));
} else {
if (typeof prop == 'string') delete obj[prop];
if ((0, _types.isFunction)(prop)) Object.keys(obj).filter(prop).forEach(key => delete obj[key]);
}
}