test-runner
test-runner copied to clipboard
[FR] Support DOMElement based snapshotSerializers
Styling libraries like Emotion use hashes in their generated classnames. These change even if the change is just whitespace, and will also depend on whether you run start-storybook or build-storybook.
In our (Zapier's) case, this results in snapshots generated locally against start-storybook to differ from those that the CI generates against a Vercel deployed build-storybook.
Emotion has a solution for these, which also inline the styles so that they can be covered by the snapshots as well: https://emotion.sh/docs/@emotion/jest
Unfortunately, this expects toMatchSnapshot() to be called for a DOMElement, while AFAIK via Playwright we only have access to the HTML as a string, via innerHTML().
I've tried:
const jsdom = require("jsdom");
const innerHTML = await elementHandler.innerHTML();
const DOMElement = new jsdom.JSDOM(innerHTML);
expect(DOMElement).toMatchSnapshot();
but that fails with:
jest-emotion requires jsdom. See https://jestjs.io/docs/en/configuration#testenvironment-string for more information
It'd be great if we could somehow support this.
How I worked around for now is use this in test-runner-jest.config.js:
snapshotSerializers: [
// Strip unstable Emotion classnames
'<rootDir>/jest/snapshotSerializer.js',
// Jest will use the first working one, but including default to be complete
...defaultConfig.snapshotSerializers,
],
With this as snapshotSerializer.js:
const jestSerializerHtml = require('jest-serializer-html');
const EMOTION_CLASS_PATTERN = /css-[\da-z]+(-[\w-]+)?/g;
module.exports = {
serialize(val) {
const withoutEmotion = val.replace(EMOTION_CLASS_PATTERN, 'removedUnstableClass');
return jestSerializerHtml.print(withoutEmotion);
},
test(val) {
return jestSerializerHtml.test(val);
},
};
Hi @FokkeZB i made a change on the above PR solution that solves this