Would you consider an API for custom html.replace functionality?
Hey there! 👋
I needed to add some functionality today that replaces random attributes with deterministic ones. Specifically, I am working with v-tooltip, which generates random ids that end up in the component's HTML.
I essentially needed to add a line after this one that was something to the effect of html = standardizeRandomIDs(html), but your library currently doesn't expose a way to add that functionality.
I had to copy your library to a local file and add the custom replace myself. 😢
Would you consider opening up your print method to optionally take a callback that defines custom replace logic? Something like:
module.exports = {
// test (received) { ... },
print (received, cb) {
let html = (isVueWrapper(received) ? received.html() : received) || ''
html = removeServerRenderedText(html)
html = removeDataTestAttributes(html)
if(cb) html = cb(html)
return beautify(html, { indent_size: 2 })
}
}
That way, I could have a least imported it and created a wrapper around it instead of copying and pasting all the code over to make the edits.
What do you think?
@m4ttsch I think you can do this with attributesToClear: ['id'] in my fork:
- https://github.com/tjw-lint/jest-serializer-vue-tjw
You can set any attribute in vue.config.js settings to clear out the value globally in all snapshots, or you can use do.mock (instructions at the bottom of README), to only clear out certain attributes on a per-test basis.
Also both jest-serializer-vue and my fork jest-serializer-vue-tjw will accept a Vue-Test-Utils wrapper of a component or an HTML string. So if you wanted to convert the component wrapper to a string, manipulate the string first, then pass it in to the expectation, that would work too.
test('My test', () => {
let wrapper = mount(MyComponent);
let markup = wrapper.html();
markup = markup.replace('<b>dog</b>', '<strong>cat</strong>');
expect(markup)
.toMatchSnapshot();
});
The serializer will run and still perform its formatting and other features.
You could even create your own helper function if it is a common thing:
test('My test', () => {
let wrapper = mount(MyComponent);
expect(helpers.snapshotCleanup(wrapper))
.toMatchSnapshot();
});
I use cheerio for help with string manipulation, here is some examples:
- https://github.com/tjw-lint/jest-serializer-vue-tjw/blob/master/src/stringManipulation.js
- https://github.com/tjw-lint/jest-serializer-vue-tjw/blob/master/src/helpers.js#L46
import cheerio from 'cheerio';
import htmlparser2 from 'htmlparser2';
const helpers = {
$: function (html) {
const xmlOptions = {
decodeEntities: false,
lowerCaseAttributeNames: false,
normalizeWhitespace: false,
recognizeSelfClosing: false,
xmlMode: false
};
const dom = htmlparser2.parseDOM(html, xmlOptions);
const $ = cheerio.load(dom, { xml: xmlOptions });
return $;
},
snapshotCleanup: function (wrapper) {
let $ = this.$(wrapper.html());
// target all elements that have an ID that starts with popover and remove their ID
$('[id^="popover"]').removeAttr('id');
return $.html();
}
};
export default helpers;