Why my custom directive does not appear in my vue element? - unit-testing

In my App?vue template , I have a custom directive ( v-noise )
//App.vue
<template>
<div id="app" class="container" v-noise="'brown'">
<...>
</div>
</template>
Testing my plugin, I don't see the directive in the console.log
import Vue from 'vue'
import App from '#/App'
import VueNoiseGeneratorPlugin from '#/plugins/VueNoiseGeneratorPlugin'
import sinon from 'sinon'
import { mount } from 'avoriaz'
Vue.use(VueNoiseGeneratorPlugin)
...
describe('VueNoiseGeneratorPlugin', () => {
let wrapper
let audioContext = sinon.mock(new (window.AudioContext || window.webkitAudioContext)())
beforeEach(() => {
wrapper = mount(App)
})
it('should start noise', () => {
console.log('WRAPPER.VM.$EL: ', wrapper.vm.$el)
Vue.noise.start()
audioContext.expects('resume').once()
})
})
no v-noise directive
'WRAPPER.VM.$EL: ', <div data-v-ee77fb84="" id="app" class="container">
<h2 data-v-ee77fb84=""><span data-v-ee77fb84="">POMODORO </span>
<span data-v-c15acdbe="" data-v-ee77fb84=""><button data-v-c15acdbe="">
....
I want to be able to change the directive (changing the colour of the noise )
feedback welcome

Related

Unit Testing Login Vue Jest ValidationProvider

I am new to Jest and I am trying to mock the store, an action and to assert that the method was indeed called. Basically I want to check the login function.
I cannot query the button because I am retrieving only a part of the component and I don't know what I'm missing.
Where my Vue component looks like:
<ValidationObserver id="observer" v-slot="{ invalid }" :class="['w-full h-full']">
<form class="flex flex-col justify-around h-full" #submit.prevent="onSubmit">
<ValidationProvider v-slot="{ errors }" name="accessCode" :class="['w-full py-6']">
<sd-field :class="['sd-field_secondary', { ['sd-invalid ']: errors && errors.length > 0 }]">
<label for="email">{{ $t("form.access-code") }}</label>
<sd-input v-model="accessCode" type="accessCode" />
<span class="sd-error">{{ errors[0] }}</span>
</sd-field>
</ValidationProvider>
<div class="btn-group-y">
<button class="btn btn-fixed btn-blueDark" type="submit">
<span>{{ $t("account.login") }}</span>
</button>
<!-- <button class="btn btn-link" type=""> //TODO: temporary hide
<span>{{ $t("account.forgot_id") }}</span>
</button> -->
</div>
</form>
</ValidationObserver>
***MY TEST FILE***
import login from "../../pages/index/login";
import Vuex from "vuex";
import { mount, createLocalVue } from "#vue/test-utils";
const localVue = createLocalVue();
localVue.use(Vuex);
describe("Login form", () => {
it("calls the login action correctly", () => {
const loginMock = jest.fn(() => Promise.resolve());
const store = new Vuex.Store({
actions: {
onSubmit: loginMock,
},
});
const wrapper = mount(login, { localVue, store, stubs: { ValidationObserver: true } });
console.log(wrapper.html());
// wrapper.find("button").trigger("click");
// expect(loginMock).toHaveBeenCalled();
});
});
console.log(wrapper.html()) returns only a part of component
<div class="h-full w-full"><validationobserver id="observer"
class="w-full h-full"> </validationobserver>
</div>
With a warning also:
> console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
> [Vue warn]: Unknown custom element: <ValidationObserver> - did you register the
> component correctly? For recursive components, make sure to provide the "name" option.
> found in
> ---> <Anonymous>
> <Root>
I would like to understand how this works, I have tried to stub and other ways found but with no success.
I can get rid of the warning by adding the stubs: { ValidationObserver: true } to mount but I actually need to access the elements inside.
Thank you!

How to access Vue-test-util console error

I am using Jest to test this Vue component:
import { mount } from '#vue/test-utils'
import ExampleComponent from '../Components/Example.vue'
describe("Test", () => {
it('shows no errors', () => {
jest.spyOn(global.console, 'error');
jest.spyOn(global.console, 'warn');
mount(ExampleComponent)
expect(console.warn).not.toHaveBeenCalled()
expect(console.error).not.toHaveBeenCalled()
})
})
I am expecting this test to Fail since I have this component:
Example.vue
<template>
<div>
{{ number }}
</div>
</template>
<script>
export default {}
</script>
as you can see number is not defined, and if opened this component using the browser it will show me:
[Vue warn]: Property or method "number" is not defined on the instance but referenced during render.
but if I test it, the test will pass. How can If the Vue component has warnings or errors?

Combine vue-gettext with unit tests (Vuejs)

Combining unit-tests and vue-gettext I get this error when running the tests:
ERROR LOG: '[Vue warn]: Error in render function: "TypeError:
undefined is not a constructor (evaluating
'Number.isNaN(parseInt(n))')"
found in
---> < Translate >
< Root >'
I am not sure how to combine these two to work together.
Reduced example looks like this:
Home.vue
<template>
<div>
<h1>
<translate tag="h1">Homepage</translate>
</h1>
</div>
</template>
<script>
export default {
name: 'Home'
}
</script>
Home.vue.spec.js
import Vue from 'vue'
import Home from '#views/Home'
describe('Home.vue', () => {
it('should render correct contents', () => {
const Constructor = Vue.extend(Home)
const vm = new Constructor().$mount()
expect(vm.$el.querySelector('div h1').textContent)
.to.equal('Homepage')
})
})

Using Jest to mock a component which has other components as properties

I'm trying to mock react-bootstrap <Modal> component with jest. <Modal> contains some "sub-components" as properties, for example <Modal.Header>. I'm trying to find out the correct way to mock this kind of components using Jest.
Here's a simple component using <Modal>:
// mymodal.js
import React from 'react'
import {Modal, Button} from 'react-bootstrap'
const MyModal = ({ visible, hide, title, onOk }) =>
<Modal show={visible} onHide={hide}>
<div className='simple-modal'>
<Modal.Header closeButton>{title}</Modal.Header>
<Modal.Body>
<div>I'm body</div>
</Modal.Body>
<Modal.Footer>
<Button className='invert-primary' onClick={hide}>
Cancel
</Button>
<Button bsStyle='primary' onClick={onOk}>
Ok
</Button>
</Modal.Footer>
</div>
</Modal>
export default MyModal
And here's basic snapshot test for it:
// mymodal.test.js
import renderer from 'react-test-renderer'
import * as React from 'react'
import MyModal from './mymodal'
jest.mock('react-bootstrap', () => {
function Modal(props) {
return <div>{props.children}</div>
}
Modal.Header = 'Modal.Header'
Modal.Body = 'Modal.Body'
Modal.Footer = 'Modal.Footer'
return({
Modal: Modal,
Button: 'Button',
})
})
describe('MyModal component', () => {
test('should render a modal', () => {
const modal = renderer.create(<MyModal
visible={true}
hide={() => ''}
onOk={() => ''}
title='Title' />)
expect(modal.toJSON()).toMatchSnapshot()
})
})
And here's snapshot:
// Jest Snapshot v1
exports[`MyModal component should render a modal 1`] = `
<div>
<div
className="simple-modal"
>
<Modal.Header
closeButton={true}
>
Title
</Modal.Header>
<Modal.Body>
<div>
I'm body
</div>
</Modal.Body>
<Modal.Footer>
<Button
className="invert-primary"
onClick={[Function]}
>
Cancel
</Button>
<Button
bsStyle="primary"
onClick={[Function]}
>
Ok
</Button>
</Modal.Footer>
</div>
</div>
`;
I'm quite happy with the snapshot result, but I'd like to get better output for the <Modal> component itself so that the snapshot would contain also component's name (currenlty <div>) and props (currently no props shown).
How should the mocking be done to achieve this?
I couldn't find way to achieve this with jest mocking. Finally I went with enzyme shallow rendering, which handles the basic mocking out of box. To do spanshot matching, I serialized the enzyme wrappers using enzyme-to-json npm package.

"Failed to resolve directive: transition" when trying to use a transition with vue-router

I've got a vue app in which I'm using the vue-router.
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
let router = new VueRouter()
// Components
import App from './App.vue'
import Mapper from './components/Mapper/mapper.vue'
import ToDos from './components/Todos/ToDoApp.vue'
import Punchlist from './components/Punchlist/punchlist.vue'
// Transitions
Vue.transition('slide',{
enterClass: 'slideInRight',
leaveClass: 'slideOutRight'
})
// Redirects
router.redirect({
'*': 'punchlist'
})
// Mappings
router.map({
'/mapper': {
component: Mapper
},
'/todos': {
component: ToDos
},
'/punchlist': {
component: Punchlist
}
})
router.start(App, '#app')
I have a specific transition registered called slide that I would like to use when navigating between routes. In my App component I added the v-transition and transition-mode directives to the route-view:
<template>
<div class="container">
<h1>Component Gallery</h1>
<p>
<a class='btn btn-primary' v-link="{ path: '/punchlist' }">Punchlist</a>
<a class='btn btn-primary' v-link="{ path: '/todos' }">Todos</a>
<a class='btn btn-primary' v-link="{ path: '/mapper' }">Mapper</a>
</p>
<router-view v-transition="slide" transition-mode="out-in" :google-maps-api-key="googleMapsApiKey"></router-view>
</div>
</template>
When I try to run it, I get the console error:
[Vue warn]: Failed to resolve directive: transition (found in component: )
I've been reading through the docs and looking at examples but I can't figure out why it's erroring out when trying to resolve the binding.
Any ideas?
Transition is an attribute, not a directive. No v-:
<router-view transition="slide">