@lewiswright/vitest-plugin-vis
Version:
Vitest visual testing plugin
98 lines (96 loc) • 4.05 kB
JavaScript
import dedent from 'dedent';
import { afterEach, beforeAll } from 'vitest';
import { toTaskId } from "../client.js";
import { ctx } from "../client/ctx.js";
import { shouldTakeSnapshot } from "../client/should_take_snapshot.js";
import { enableAuto, extractAutoSnapshotOptions } from "../client/snapshot_options.js";
export function createVis(commands) {
let subjectDataTestId;
const vis = {
presets: {
enable() {
beforeAll(vis.beforeAll.setup);
afterEach(vis.afterEach.matchImageSnapshot);
},
manual() {
beforeAll(vis.beforeAll.setup);
},
auto() {
beforeAll(vis.beforeAll.setup);
afterEach(vis.afterEach.matchImageSnapshot);
enableAuto();
},
theme(themes) {
beforeAll(vis.beforeAll.setup);
afterEach(vis.afterEach.matchPerTheme(themes));
},
},
beforeAll: {
async setup() {
subjectDataTestId = (await commands.setupVisSuite()).subjectDataTestId;
},
},
afterEach: {
async matchImageSnapshot() {
const test = ctx.getCurrentTest();
if ((test?.result?.errors?.length ?? 0) > 0)
return;
const meta = extractAutoSnapshotOptions(test);
if (!shouldTakeSnapshot(meta))
return;
test.meta.vis = { ...test.meta.vis, isAutoSnapshot: true };
await test.context.expect(getSubject(meta?.subjectDataTestId ?? subjectDataTestId)).toMatchImageSnapshot(meta);
},
matchPerTheme(themes) {
return async function matchImageSnapshot() {
const test = ctx.getCurrentTest();
if ((test?.result?.errors?.length ?? 0) > 0)
return;
const meta = extractAutoSnapshotOptions(test);
if (!shouldTakeSnapshot(meta))
return;
const errors = [];
for (const themeId in themes) {
try {
await new Promise((a) => setTimeout(a, 10));
const r = await themes[themeId](meta);
if (r === false)
continue;
await test.context
.expect(getSubject(meta?.subjectDataTestId ?? subjectDataTestId))
.toMatchImageSnapshot({
...meta,
customizeSnapshotId: meta?.customizeSnapshotId
? ({ id, index }) => `${meta.customizeSnapshotId({ id, index, isAutoSnapshot: true })}-${themeId}`
: ({ id }) => `${id}-${themeId}`,
});
}
catch (error) {
errors.push([themeId, error]);
}
}
if (errors.length > 0) {
if (errors.length === 1)
throw errors[0][1];
const taskId = toTaskId(test);
throw new AggregateError(errors, dedent `Snapshot \`${taskId}\` mismatched
${errors
.map(([themeId, error]) => {
return `Theme \`${themeId}\` failed: ${error.message}`;
})
.join('\n\n')}`);
}
};
},
},
};
return vis;
}
function getSubject(subjectDataTestId) {
if (subjectDataTestId) {
const subject = document.querySelector(`[data-testid="${subjectDataTestId}"]`);
if (subject)
return subject;
}
return document.body;
}