jest-serializer-vue
jest-serializer-vue copied to clipboard
Change (or expose) "pretty" options
The default options shipped in jest-serializer-vue
make snapshots and snapshot diffs pretty unreadable half the time.
Input code like this:
<template>
<div data-test="baseTitle">
<h3 class="inline-block">{{ title }}</h3>
<span v-show="showSpinner">
<i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i>
<span class="sr-only">Loading...</span>
</span>
<router-link
v-if="createNewRouteName"
:to="{
name: createNewRouteName,
params: {
id: 'new'
}
}"
>
<button :disabled="disableCreateNew" type="button" class="primary">
<i class="fa fa-plus"></i>
Create New
</button>
</router-link>
</div>
</template>
Will output code like this:
<div>
<h3 class="inline-block">Create New and Spinner</h3> <span><i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> <span class="sr-only">Loading...</span></span> <a><button type="button" class="primary"><i class="fa fa-plus"></i>
Create New
</button></a>
</div>
If you change the options passed into pretty
, you can get this:
<div>
<h3 class="inline-block">Create New and Spinner</h3>
<span>
<i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i>
<span class="sr-only">Loading...</span>
</span>
<a>
<button type="button" class="primary">
<i class="fa fa-plus"></i>
Create New
</button>
</a>
</div>
Here is a comparison of a diff generated using the default jest-serializer-vue
and my custom options.
Note: This is for a simple, 25 line, template. Imagine a longer, more complex diff, like in a table component with lots of rows of data that have custom markup logic in each cell.
I've changed the serializer on all my projects to a custom one, based on jest-serializer-vue
to have these easier to read snapshots.
// Based on jest-serializer-vue
const beautify = require('pretty');
function isHtmlString (received) {
return received && typeof(received) === 'string' && received.startsWith('<');
}
function isVueWrapper (received) {
return received && typeof(received) === 'object' && typeof(received.isVueInstance) === 'function';
}
function removeServerRenderedText (html) {
return html.replace(/ data-server-rendered="true"/, '');
}
// This removes data-test="whatever" from your snapshots
// If you also want to remove them from your production builds, see:
// https://forum.vuejs.org/t/how-to-remove-attributes-from-tags-inside-vue-components/24138
function removeDataTestAttributes (html) {
// [-\w]+ will catch 1 or more instaces of a-z, A-Z, 0-9, hyphen (-), or underscore (_)
return html.replace(/ data-test="[-\w]+"/g, '');
}
module.exports = {
test: function (received) {
return isHtmlString(received) || isVueWrapper(received);
},
print: function (received) {
let html = received || '';
if (isVueWrapper(received)) {
html = received.html();
}
html = removeServerRenderedText(html);
html = removeDataTestAttributes(html);
// To see available options: https://github.com/beautify-web/js-beautify/blob/master/js/src/html/options.js
const options = {
indent_char: ' ',
indent_inner_html: true,
indent_size: 2,
inline: [],
sep: '\n',
unformatted: ['code', 'pre']
};
return beautify(html, options);
}
};
Adopting the same options in the official jest-serializer-vue
will have much better default snapshots (though will break people's existing snapshots, so it should be a major bump if adopted). Though I would find it preferable to make these options modifiable in some way, so user's can tweak them without having to basically duplicate the same file, losing downstream updates, just to change an option. And from the other perspective it would allow people to opt out of changes in these options in the future by passing in their own overrides if they change again, making breaking changes of the future less painful.
Got tired of waiting and made my own fork.
- https://www.npmjs.com/package/jest-serializer-vue-tjw