UNPKG

creevey

Version:

Cross-browser screenshot testing tool for Storybook with fancy UI Runner

92 lines 4.93 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadTestsFromStories = loadTestsFromStories; exports.saveTestsJson = saveTestsJson; const path_1 = __importDefault(require("path")); const fs_1 = require("fs"); const crypto_1 = require("crypto"); const types_js_1 = require("../types.js"); const utils_js_1 = require("./utils.js"); function storyTestFabric(delay, testFn) { return async function storyTest() { if (delay) await new Promise((resolve) => setTimeout(resolve, delay)); await (testFn ? testFn.call(this) : this.screenshots.length > 0 ? this.expect(this.screenshots.reduce((screenshots, { imageName, screenshot }, index) => ({ ...screenshots, [imageName ?? `screenshot_${index}`]: screenshot, }), {})).to.matchImages() : this.expect(await this.takeScreenshot()).to.matchImage()); }; } function createCreeveyTest(browser, storyMeta, skipOptions, testName) { const { title, name, id: storyId } = storyMeta; const path = [title, name, testName, browser].filter(types_js_1.isDefined); const skip = skipOptions ? (0, utils_js_1.shouldSkip)(browser, { title, name }, skipOptions, testName) : false; const id = (0, crypto_1.createHash)('sha1').update(path.join('/')).digest('hex'); return { id, skip, browser, testName, storyPath: [...title.split('/').map((x) => x.trim()), name], storyId }; } function convertStories(browserName, stories) { const tests = {}; (Array.isArray(stories) ? stories : Object.values(stories)).forEach((storyMeta) => { // TODO Skip docsOnly stories for now if (storyMeta.parameters.docsOnly) return; const { delay: delayParam, tests: storyTests, skip } = (storyMeta.parameters.creevey ?? {}); const delay = typeof delayParam == 'number' ? delayParam : delayParam?.for.includes(browserName) ? delayParam.ms : 0; // typeof tests === "undefined" => rootSuite -> kindSuite -> storyTest -> [browsers.png] // typeof tests === "function" => rootSuite -> kindSuite -> storyTest -> browser -> [images.png] // typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> [browsers.png] // typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> browser -> [images.png] if (!storyTests) { const test = createCreeveyTest(browserName, storyMeta, skip); tests[test.id] = { ...test, storyId: storyMeta.id, story: storyMeta, fn: storyTestFabric(delay) }; return; } Object.entries(storyTests).forEach(([testName, testFn]) => { const test = createCreeveyTest(browserName, storyMeta, skip, testName); tests[test.id] = { ...test, storyId: storyMeta.id, story: storyMeta, fn: storyTestFabric(delay, testFn) }; }); }); return tests; } async function loadTestsFromStories(browsers, provider, update) { const testIdsByFiles = new Map(); const stories = await provider((storiesByFiles) => { const testsDiff = {}; const tests = {}; browsers.forEach((browser) => { Array.from(storiesByFiles.entries()).forEach(([filename, stories]) => { Object.assign(tests, convertStories(browser, stories)); const changed = Object.keys(tests); const removed = testIdsByFiles.get(filename)?.filter((testId) => !tests[testId]) ?? []; if (changed.length == 0) testIdsByFiles.delete(filename); else testIdsByFiles.set(filename, changed); Object.assign(testsDiff, tests); removed.forEach((testId) => (testsDiff[testId] = undefined)); }); }); update?.(testsDiff); }); const tests = browsers.reduce((tests, browser) => Object.assign(tests, convertStories(browser, stories)), {}); Object.values(tests) .filter(types_js_1.isDefined) .forEach(({ id, story: { parameters: { fileName }, }, }) => // TODO Don't use filename as a key, due possible collisions if two require.context with same structure of modules are defined testIdsByFiles.set(fileName, [...(testIdsByFiles.get(fileName) ?? []), id])); return tests; } function saveTestsJson(tests, dstPath = process.cwd()) { (0, fs_1.mkdirSync)(dstPath, { recursive: true }); (0, fs_1.writeFileSync)(path_1.default.join(dstPath, 'tests.json'), // eslint-disable-next-line @typescript-eslint/no-unsafe-return JSON.stringify(tests, (_, value) => ((0, types_js_1.isFunction)(value) ? value.toString() : value), 2)); } //# sourceMappingURL=stories.js.map