Custom components registered to stories are not mounted when running storyshots.
console.error node_modules/vue/dist/vue.esm.js 591
[Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <Pager>
<Root>
I pretty much followed every steps displayed on the example.
Package versions:
// package.json
...
{
"scripts": {
"snapshot": "jest --config=jest.config.snapshot.js",
...
}
}
// jest.config.snapshot.js
module.exports = {
moduleFileExtensions: ['vue', 'js', 'ts', 'json'],
moduleDirectories: ['node_modules'],
transform: {
'^.+\\.js$': 'ts-jest',
'^.+\\.ts$': 'ts-jest',
'.*\\.(vue)$': '<rootDir>/node_modules/jest-vue-preprocessor'
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
'[^/]vue$': 'vue/dist/vue.esm.js',
'^@storybook/(.*)$': '<rootDir>/node_modules/@storybook/$1'
},
snapshotSerializers: ['jest-serializer-vue'],
testMatch: ['<rootDir>/test/snapshot/*.js'],
verbose: true,
setupFiles: ['<rootDir>/.jest/register-context.js'],
transformIgnorePatterns: [
'./node_modules/(?!vue)',
'./node_modules/@storybook'
],
globals: {
'ts-jest': {
babelConfig: '.babelrc'
}
}
}
// .jest/register-context.js
import registerRequireContextHook from 'babel-plugin-require-context-hook/register'
registerRequireContextHook()
// Pager.vue
<template>
<div class="Pager">
<button
:disabled="internalCurrentPage === 1"
class="Pager__ArrowButton"
@click="onClickPrev"
>←</button>
<button
:disabled="internalCurrentPage === maxPage"
class="Pager__ArrowButton"
@click="onClickNext"
>→</button>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
interface IData {
internalCurrentPage: number
}
export default Vue.extend({
props: {
currentPage: {
type: Number,
default: 1
},
size: {
type: Number,
default: 1
},
total: {
type: Number,
default: 20
}
},
data(): IData {
return {
internalCurrentPage: 1
}
},
computed: {
maxPage(): number {
return Math.ceil(this.total / this.size)
}
},
watch: {
currentPage: {
immediate: true,
handler(val) {
this.internalCurrentPage = val
}
}
},
methods: {
onClickNumButton(pageNum: number) {
this.internalCurrentPage = pageNum
this.$emit('change', this.internalCurrentPage)
},
onClickPrev() {
this.internalCurrentPage -= 1
this.$emit('change', this.internalCurrentPage)
},
onClickNext() {
this.internalCurrentPage += 1
this.$emit('change', this.internalCurrentPage)
}
}
})
</script>
<style scoped>
...
</style>
// Pager.story.ts
import { storiesOf } from '@storybook/vue'
import Pager from './Pager.vue'
storiesOf('components/Base/Pager', module).add('Default', () => ({
components: { Pager },
data() {
return {
currentPage: 1
}
},
template: `
<div class="Storybook">
<div class="StorybookSection">
<div class="StorybookSection__Header">Pager</div>
<div class="StorybookSection__Body dark">
<div class="wrapper" style="width: 100%">
<div style="color: #fff;margin-bottom: 16px;font-size: 18px;font-weight: bold;">Current Page: {{ currentPage }}</div>
<Pager :currentPage="currentPage" :size="1" :total="10" @change="num => currentPage = num" />
</div>
</div>
</div>
</div>
`
}))
Yes, everything is working on Storybook.

It breaks only when running on Jest.
Looking forward any advice could fix my issue.Thanks
I can't point to something specific in your setup. Having a reproduction will be much helpful
I've pushed a dedicated branch to reproduce the problem in my repo.
https://github.com/andoshin11/spa-playground/tree/fix/storyshots-error
Running $ yarn run snapshot will give you the error shown above.
I've tried to figure it out what's going on, but without progress. Will try to debug a bit later.
Thanks a lot for your kindness, Igor
I've managed to make it work without typescript.
Thise error:
[Vue warn]: Failed to mount component: template or render function not defined.
means we can't use dist/vue.common, because it's bundled without compiler, and we need compile to compile templats =/
If I remove this mapping, I am getting a TS error that seems to be similar to this - https://github.com/vuejs/vue-hot-reload-api/issues/61
Will continue to dig in it
Actually, we are mocking vue to use vue.common inside the storyshots. So probably ☝️ is not 100% accurate
Got it working with a bit different approach.
First of all, I can confirm that the problem is with vue/jest/typescript . So probably there is a different solution by changing something in tsconfig.
Currently, the vue-jest-preprocessor is using typescript compiler when the lang="ts" is defined in the