Mocha Chai getting an element by id - vuejs2

This is my vue.js 2.0 Mocha Chai testing unit, I can't get an element by Id, maybe you have a solution ? I need to test if the input field gets correctly displayed ... :
import { expect } from "chai";
import { shallowMount } from "#vue/test-utils";
import Register from "#/components/Register.vue";
const wrapper = shallowMount(Register);
describe("Register tests", () => {
it("Should display an Email input", () => {
expect(wrapper.vm.$el.querySelector("input[type='email']") !==null).to.be.true
});// IT WORKS
it("Should display a name input", () => {
expect(wrapper.vm.$el.getElementById('name') !== null).to.be.true
});
});
This is the error :
1) Register tests
Should display a name input:
TypeError: wrapper.vm.$el.getElementById is not a function
at Context.it (dist\js\webpack:\tests\unit\register.spec.js:26:1)
This is the element that I want to test. ;
<input type="text" class="form-control form-control-user" min="1" v-model="user.name" name="name" value ="name" id="name" placeholder="name">

Related

How to set initial focus on input field on page load (with VueJS 3 using Composition API)

How can I set the focus on an HTML input field upon page loading while using the Composition API of VueJS 3?
I have the following HTML:
<div>
<input type="text" id="filter" v-model="filter">
</div>
And have tried this in the setup() function, but that doesn't set the focus:
setup() {
onMounted(() => {
const filter_fld = document.getElementById('filter')
filter_fld.focus()
})
}
I also tried using the below.
HTML:
<div>
<input type="text" ref="filter_fld" v-model="filter">
</div>
And in setup() function:
setup() {
const filter_fld = ref(null)
onMounted(() => {
filter_fld.value?.focus()
})
}
But also to no success unfortunately. Any suggestions?
Have an input with a ref in your template e.g.:
<input ref="filter" />
Then after component is mounted focus it by reference on next tick:
import { ref, onMounted, nextTick } from 'vue';
setup() {
const filter = ref(null);
onMounted(() => {
nextTick(() => {
filter.value.focus();
});
});
return {
filter
};
}
You can also use the autofocus native's HTML attribute:
<input type = "text" id = "filter" v-model = "filter" autofocus/>

Cannot spyOn on a primitive value; undefined given . Vue JS, Jest, Utils

I try to use spyOn to spy the functions and it's implementation. However, i got this error. "Cannot spyOn on a primitive value; undefined given".
I already read the documentation of jest.spyOn in https://jestjs.io/docs/en/jest-object . But it keeps showing the same errror... is there anything that i should add and improve?
below is the code
<template>
<div>
<form #submit.prevent="onSubmit(inputValue)">
<input type="text" v-model="inputValue">
<span class="reversed">{{ reversedInput }}</span>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
props: ['reversed'],
data: () => ({
inputValue: '',
results: [],
}),
methods: {
onSubmit(value) {
const getPromise = axios.get(
'https://jsonplaceholder.typicode.com/posts?q=' + value,
);
getPromise.then(results => {
this.results = results.data;
});
return getPromise;
},
},
};
</script>
while the test code is
import axios from 'axios'; // axios here is the mock from above!
import { shallowMount } from '#vue/test-utils';
import Form from '#/components/Form.vue';
describe('Form.test.js', () => {
const wrapper;
describe('Testing Submit events', () => {
wrapper = shallowMount(Form);
it('calls submit event', () => {
const onSubmit = jest.spyOn(Form.prototype, 'onSubmit') // mock function
// updating method with mock function
wrapper.setMethods({ onSubmit });
//find the button and trigger click event
wrapper.findAll('form').trigger('submit');
expect(onSubmit).toBeCalled();
})
});
})
Can you also vrief me what and how to use spyOn to test the method?
Thank you so much
Best regards
Lughni
Component definition suggests that Form is an object. Form.prototype === undefined because Form is not a function. Since Vue class components aren't in use, nothing suggests the opposite.
It can be spied as:
jest.spyOn(Form.methods, 'onSubmit')
This should be done prior to component instantiation. And spyOn with no implementation provided creates a spy, not a mock.

How do I mock ApolloMutation component?

Everything about the app works fine except the testing.
I have tried to use mount and shallowMount methods exposed by #vue/test-utils to mock the ApolloMutation component.
I have seen couple of solutions on VueApollo testing. I have tried this. In my case, I'm using NuxtApollo community module. I tried to apply it the same way, but throwing error about the wrapper been empty, not sure if importing the #nuxtjs/apollo is the right thing to do.
import { createLocalVue, shallowMount } from '#vue/test-utils'
import VueApollo from '#nuxtjs/apollo'
import Register from '../pages/register/index.vue'
describe('Register user', () => {
let localVue
beforeEach(() => {
localVue = createLocalVue()
localVue.use(VueApollo, {})
})
it('Should click the register button to register', () => {
const mutate = jest.fn()
const wrapper = shallowMount(Register, {
localVue,
mocks: {
$apollo: {
mutate,
}
}
});
wrapper.find('.callMe').trigger('click')
expect(2+2).toBe(4)
});
});
The component I want to test.
<template>
<ApolloMutation
:mutation="require('../../apollo/mutations/createUser.gql')"
:variables="{firstName, lastName, username, phone, email, password}"
#done="onDone">
<template v-slot="{ mutate, loading, error }">
<input v-model="firstName" placeholder="first name">
<input v-model="lastName" placeholder="last name">
<input v-model="username" placeholder="username">
<input v-model="phone" placeholder="phone">
<input v-model="email" placeholder="email">
<input v-model="password" placeholder="password">
<button :disabled="loading" #click="mutate">CreateUser</button>
<button class="callMe" #click="callMe">CreateUser</button>
<p v-if="error">An error occurred: {{ error }}</p>
<p v-if="loading">loading...</p>
</template>
</ApolloMutation>
</template>
I expected the output to be 4 but I got the error: [vue-test-utils]: find did not return .callMe, cannot call trigger() on empty Wrapper
Should be import VueApollo from 'vue-apollo' not import VueApollo from '#nuxtjs/apollo'.
Replace that everything should be fine.

Testing Child Component's input field with Jest (Vue)

I am implementing unit test cases for my vue application with jest
I have a situation where i need to test a input field in a child component.
<parent-component>
<child-component>
<input type="text" v-model="inputValue" />
</child-component>
</parent-component>
My test goes like below
it('check empty validation', () => {
const wrapper = mount(parentComponent, {
propsData: {
test:test
}
});
wrapper.find(childComponent).vm.inputValue = "";
expect(wrapper.vm.errorMessage).toBe("cannot be empty");
});
But setting model doesnt seems to be working.
How to set value to text box and test the same is my question
Thanks
You can use the Vue Test Utils setValue method on the element:
it('check empty validation', () => {
const wrapper = mount(parentComponent, {
propsData: {
test: test
}
})
wrapper.find('input').setValue('')
expect(wrapper.vm.errorMessage).toBe('cannot be empty')
})
This sets the element value property and forces the model to update.
Try using setData from vue-test-utils:
https://vue-test-utils.vuejs.org/api/wrapper/#setdata-data

Vuejs testing value after click

<!-- template -->
<div>
<textarea v-model="someText">{{someText}}</textarea>
<div v-if="hasError">Something wrong here</div>
<input v-on:click="store" type="submit" value="update" />
</div>
//script
{
data() {
hasError: false,
someText: ""
},
store(){
return axios.post('/my/api/endpoint', { myvalue: this.someText })
.then(() => {
this.hasError= false;
})
.catch(() => {
this.hasError= true;
};
}
}
//test
import { mount } from 'vue-test-utils';
import MyComponent from "./component.vue";
import * as httpMock from 'moxios';
import Vue from "vue";
it("notifies when updates fail", (done) => {
const wrapper = mount(MyComponent);
httpMock.stubFailure("PUT", "/my/api/endpoint",
{
status: 500
});
httpMock.wait(() => {
wrapper.find(".button").trigger ("click");
Vue.nextTick(() => {
expect(wrapper.html()).toContain("Something wrong here");
done();
});
});
I have the above code to test error state in the vue app. Simply, i'm trying to test that if there is an error calling the server, a bit of text is displayed to say so. i've manually tested this in the browser and its all good, but i can't get a unit test around it. it just fails, saying expected '...' does not contain Something wrong here
probably something to do with the dom not being updated yet? But I thought that was what Vue.nextTick was for?
You're running wait before you actually trigger the axios call. Your call of the click event must be outside of wait.
wrapper.find(".button").trigger ("click");
httpMock.wait(() => {
Vue.nextTick(() => {
expect(wrapper.html()).toContain("Something wrong here");
done();
});
})
Also, I'm assuming you're importing axios in the component, as I don't actually see the import.