Closed sdellis closed 6 years ago
Are you trying to trigger a mock action, or just the function inside of the methods
object? You aren't using the Vuex action in your component at the moment.
Inside of resizeThumbs
you would need to do:
methods: {
resizeThumbs: function (event) {
this.$store.dispatch('resizeThumbs')
this.thumbPixelWidth = event.target.value
}
}
Also in the component you do not need to pass $event
, it is the first argument by default. It should be @input="resizeThumbs"
.
More info can be found in the docs:: https://vue-test-utils.vuejs.org/en/guides/using-with-vuex.html
This does not appear to be a problem with vue-test-utils
, I think stackoverflow might be a better bet for these kind of questions. If you are new to to Vue testing or want some more examples, here are two blogs (myself and the maintainer, Eddy) who write a lot about testing with vue-test-utils, for more examples.
https://eddyerburgh.me/ https://medium.com/@lachlanmiller_52885
Hi @sdellis. This is a problem with your code, rather than vue-test-utils. The input even is getting triggered, but the action isn't called because you haven't added any code to dispatch the action.
This issue tracker is reserved for bug fixes and feature requests. For questions like these, please ask on StackOverflow or the Vue discord channel.
@lmiller1990 FYI, it's Edd, not Eddy 😉
I apologize for erroneously filing this as a bug report. I'll be more careful next time. @lmiller1990 I was trying to trigger the function within the methods
object. I think I got confused as example was simplified from a more complicated component in which the resizeThumbs method doesn't need to touch the store.
If you think this is a bug, could you please create a minimal reproduction that demonstrates the bug? If it's not a bug I'll leave this closed.Thanks 🙂
@eddyerburgh If I'm passing the event properly, I think this may be a bug. Here's a minimal reproduction with all the unnecessary vuex stuff taken out. My component:
<template>
<div class="content">
<input @input="resizeThumbs($event)" id="resize_thumbs_input" type="range">
<div v-model="thumbnails">
<div v-for="thumbnail in thumbnails" :key="thumbnail.id"
v-bind:style="{'max-width': thumbPixelWidth + 'px' }" class="thumbnail">
<img :src="thumbnail.url" class="thumb">
</div>
</div>
</div>
</template>
<script>
export default {
name: 'test',
data: function () {
return {
thumbPixelWidth: 200
}
},
computed: {
thumbnails: function () {
return [{"id":"1","url":"1.png"},{"id":"2","url":"2.png"}]
}
},
methods: {
resizeThumbs: function (event) {
this.thumbPixelWidth = event.target.value
}
}
}
</script>
My test:
import { mount } from 'vue-test-utils'
import Test from '@/components/Test'
describe('Test.vue', () => {
it('changes thumbnail size when range input changes', () => {
const wrapper = mount(Test)
wrapper.find('#resize_thumbs_input').trigger('input', {target: {value: 100}})
const resizedThumb = wrapper.find('.thumbnail')
expect(resizedThumb.hasStyle('max-width', '100px')).toBe(true)
})
})
I get the following error when running the test:
FAIL valhalla/app/javascript/test/unit/specs/Test.spec.js
● Test.vue › changes thumbnail size when range input changes
TypeError: Cannot set property target of [object Object] which has only a getter
According to the docs I think I'm passing event.target.value
properly.
trigger creates a new DOM Event, and tries to overwrite the Event properties with the properties of options. Unfortunately, target is a read only property, which leads to the confusing error.
To trigger an input with the value of 100, you need to set the value of the element you're triggering the event on to 100:
const input = wrapper.find('#resize_thumbs_input')
input.element.value = 100
input.trigger('input', {target: {value: 100}})
I'm going to add a note to the docs that target is unwritable, and throw a custom error inside trigger, so that users get an improved error message.
Let me know if setting the value before triggering the event solves your problem.
@eddyerburgh Thank you for your help, for improving the error message, and adding this to the docs! One small note with your example above is that I needed to remove , {target: {value: 100}}
from the trigger call to get it to work for me.
I have a related issue to @sdellis, except that using a native html 5 input tag, I'm using a b-form-input
component that is provided by bootstrap vue. input.trigger()
seems to trigger an event, but input.element.value
doesn't seem to actually set the value of the b-form-input field. Any thoughts on why this would be different for b-form-input
and how vue-test-utils deals with this kind of custom input component?
Can you provide a link to the component library and snippet? Most likely the component is built (by the library author) like so
<b-form-input>
<div class="bootstrap_styling_etc">
<input value="aaa">
</div>
</b-form-input>
When you call input.element.value
you may be setting it on the <b-form-input>
instead of the actual <input>
wrapper by the library author. If you provide some code and context I can offer other suggestions.
@lmiller1990 In the case of Bootstrap Vue, b-form-input seems to hide the actual input field within the component, so what you end up with is:
<b-form-input v-model="text1"
type="text"
placeholder="Enter your name">
</b-form-input>
You can read more about it here.
In my test, when I create my wrapper object of the component I am trying to test:
const wrapper = shallowMount(MyComponent, { propsData: { options } })
I then get the input field I am trying to manipulate:
<!-- The template markup -->
<div class="row">
<div class="col-lg-12" id="contract-id-input">
<b-form-input
placeholder="7-digit code"
:value="productData.contractId"
@input="updateProduct($event, 'contractId')"
aria-describedby="contractIdFeedback"
autocomplete="off"
maxlength="7"
:state="this.productValidationStates.contractId"
@keydown.native="isNumericAllowed($event)"
>
</b-form-input>
<b-form-invalid-feedback id="contractIdFeedback">
7 digits required
</b-form-invalid-feedback>
</div>
</div>
// The code in my test to get the DOM element
const myInput = wrapper.find('#contract-id-input > b-form-input')
Which, as far as I can tell, successfully gets that b-form-input
node within the component's html template. When I console.log myInput.attributes()
in my test, I can see all the attributes that were attached to the b-form-input
in my template markup.
One thing that I do find very strange is the inconsistency of console.log
values when running the unit tests verses running the code in a browser. A specific case is when I'm trying to console.log
the value of this.productData.contractId
, which is data defined in the component. In the test, I get the value of Event { isTrusted: [Getter] }
, but in Chrome I get an empty string. Each time I add a value to that b-form-input
field, then the value gets logged out to the console in the browser.
If any of this information triggers a thought as to what the problem might be, I'd really appreciate the help. Thanks in advance!
I dug into the bootstrap-vue project on Github and found the tests for the b-form-input
component. In those tests, they use vue-test-utils and they use the trigger()
method in their tests. The expectations in those tests are different from what I was anticipating:
it('apply transform function', async () => {
const wrapper = mount(Input, {
propsData: {
formatter (value) {
return value.toLowerCase()
}
}
})
const input = wrapper.find('input')
input.element.value = 'TEST'
input.trigger('input')
expect(wrapper.emitted().input[0]).toEqual(['test'])
})
In this test, the expectation is on what value was emitted by the input field when an input
event occurs. Naively, I assumed that there was a data property in the b-form-input
component definition, and that the test would assert that a value was set somewhere instead of just emitting a value. This information doesn't really get me any closer to understanding how to get my test case working, but does shed some further context on what I am working with in b-form-input
.
Might as well provide the source code that I am working with to help provide full context:
The component:
<template>
<div>
<div class="cartulary" @click="click">
<div :class="'classification ' + active">
<fuse-icon @click="updateProduct($event, 'delete')" iconClass="dismiss" customCss="float-right"></fuse-icon>
<div class="row align-items-center">
<div class="col-lg-3">
<div class="product-name">
{{ productData.name }}
</div>
</div>
<div class="col-lg-9">
<div class="row">
<!-- Contract ID -->
<div class="col-lg-4">
<div class="row">
<div class="col-lg-5" id="contract-id-label">
<span class="detail-label">
Contract ID *
</span>
</div>
</div>
<div class="row">
<div class="col-lg-12" id="contract-id-input">
<b-form-input
placeholder="7-digit code"
:value="productData.contractId"
@input="updateProduct($event, 'contractId')"
aria-describedby="contractIdFeedback"
autocomplete="off"
maxlength="7"
:state="this.productValidationStates.contractId"
@keydown.native="isNumericAllowed($event)"
>
</b-form-input>
<b-form-invalid-feedback id="contractIdFeedback">
7 digits required
</b-form-invalid-feedback>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import validationHelpers from '../../../helpers/validationHelpers'
export default {
name: 'EnercareLineItem',
props: [
'options',
'active'
],
data() {
return {
datePickerOptions: {
type: 'datetime',
format: 'MM/dd/yyyy hh:mm A',
placeholder: 'Select date and time'
},
productData : this.options,
productValidationStates: {
contractId: '',
caseId: ''
},
isValid: false
}
},
methods: {
click() {
this.$emit('click')
},
/**
* Only allow the user to enter numbers, otherwise prevent the
* input from registering
*/
isNumericAllowed(event) {
if (!validationHelpers.allowNumeric(event)) {
event.preventDefault()
}
},
/**
* updateProducts() sends the product data up to the parent.
*/
updateProduct(value, type) {
if (type === 'delete') {
this.$emit('delete')
return
}
this.productData[type] = value
console.log('#################################')
console.log('Here in updateProduct()')
console.log('#################################')
this.setValidationStates()
this.$emit('update', {
encrProductData: this.productData,
isValid: !Object.values(this.productValidationStates).includes('invalid')
})
},
setValidationStates() {
console.log('#################################')
console.log('Here in setValidationStates()')
console.log(this.productData.contractId)
console.log('#################################')
this.productValidationStates.contractId = this.productData.contractId.length !== 7 ? 'invalid' : 'valid'
switch (this.productData.caseId.length) {
case 0:
this.productValidationStates.caseId = 'reset'
break
case 8:
this.productValidationStates.caseId = 'valid'
break
default:
this.productValidationStates.caseId = 'invalid'
break
}
}
},
created() {
this.setValidationStates()
},
updated() {
console.log('I just updated', this.options)
}
}
</script>
The unit test:
import Vuex from 'vuex'
import BootstrapVue from 'bootstrap-vue'
import { shallowMount, createLocalVue } from '@vue/test-utils'
import EnercareLineItem from '../../resources/assets/js/components/formfields/enercare/EnercareLineItem'
import BaseField from '../../resources/assets/js/components/BaseField'
const Vue = createLocalVue()
Vue.use(Vuex)
Vue.use(BootstrapVue)
describe('EnercareLineItem', () => {
describe('Contract Id input', () => {
it('is valid at a length of 7', () => {
let options = {
index: 0,
name: 'Hot Water Heater Tune Up',
contractId: '',
appointmentTime: '2018-01-01T12:00:00Z',
caseId: ''
}
const wrapper = shallowMount(EnercareLineItem, {
propsData: { options }
})
const contractIdInput = wrapper.find('#contract-id-input > b-form-input')
expect(contractIdInput.attributes().state).toBe('invalid')
contractIdInput.element.value = '1234567'
contractIdInput.trigger('input')
expect(contractIdInput.attributes().state).toBe('valid')
})
})
})
Hi @mjvezzani
There is a bit of code missing (like what kind of props are received, and what validationHelpers
is). This made it a bit hard to recreate your example, so I simplified the code to only have the b-form-input
and attempted to test the thing you want to test.
Simplified component:
<template>
<div>
<div class="col-lg-12" id="contract-id-input">
<b-form-input
id="b-form-input"
v-model="productData.contractId"
maxlength="7"
:state="productValidator"
>
</b-form-input>
</div>
</div>
</template>
<script>
export default {
name: 'EnercareLineItem',
data() {
return {
productData: { contractId: '' }
}
},
computed: {
productValidator() {
switch (this.productData.contractId.length) {
case 0:
return 'reset'
case 8:
return 'valid'
default:
return 'invalid'
}
}
}
}
</script>
Passing Tests:
import BootstrapVue from 'bootstrap-vue'
import { shallowMount, mount, createLocalVue } from '@vue/test-utils'
import EnercareLineItem from '@/components/HelloWorld'
const Vue = createLocalVue()
Vue.use(BootstrapVue)
describe('EnercareLineItem', () => {
describe('Contract Id input', () => {
it('is invalid at a length of 7', () => {
const wrapper = shallowMount(EnercareLineItem, {
localVue: Vue,
data() {
return {
productData: { contractId: "1234567" }
}
}
})
const contractIdInput = wrapper.find('#b-form-input')
expect(contractIdInput.attributes().state).toBe('invalid')
})
it('is valid at a length of 8', () => {
const wrapper = shallowMount(EnercareLineItem, {
localVue: Vue,
data() {
return {
productData: { contractId: '12345678' }
}
}
})
const contractIdInput = wrapper.find('#b-form-input')
expect(contractIdInput.attributes().state).toBe('valid')
})
it('changes state', () => {
const wrapper = shallowMount(EnercareLineItem, {
localVue: Vue,
data() {
return {
productData: { contractId: '1234567' }
}
}
})
const contractIdInput = wrapper.find('#b-form-input')
expect(contractIdInput.attributes().state).toBe('invalid')
wrapper.setData({ productData: { contractId: '12345678' } })
expect(contractIdInput.attributes().state).toBe('valid')
})
})
})
I am not sure why your test was not working, I could not get it running locally without the rest of your project. I am not sure if this is exactly what you are looking for, but it shows how you can check the state
is valid or not.
Hopefully this example might give you some ideas?
One unfortunate thing is wrapper.find('#contract-id-input > b-form-input')
does not work. I tried hard to solve this in https://github.com/vuejs/vue-test-utils/pull/897, but there are some impossible edge cases to allow selecting by custom component tags. The select API looks like this:
find(ComponentName)
. This means you need to also do import Component from '../Component.vue'
find({ name: 'component-name })
. Using the name
prop.find('#dom-selector')
. This uses document.querySelector
under the hood, which is why it won't work with custom component tags.PS: don't forget to pass localVue: Vue
to shallowMount
. Otherwise you won't be using the localVue
instance
Okay, so I wired up my test to work in a similar way that you suggested, @lmiller1990, and I have passing tests. So now I have a question about unit testing philosophy. My understanding is that one should unit test public facing inputs and public facing outputs. I was under the impression that setting up a test in which contractId is not initially populated, and then mimicking user input into the b-form-input
field, and then asserting that validity on that field is set is how I wanted to test.
The examples that you provide me exercise an assertion on a wrapper component that already has the internal state set. In other words, in the Assemble, Act, Assert model of unit testing, the example tests Assemble and then Assert, bypassing the need to Act on anything. I'd be curious to hear more about why Assemble and Assert is preferable to Assemble, Act, and Assert. Thanks!
@mjvezzani great questions and observations. I like these kind of discussions in issues, as opposed to simply "how do I do X", we should be asking "how should I do X"?
I don't think there is any one "correct" way to test. What I've been doing lately is identifying all the states a component can be in (for example a form can be valid and invalid). Then I set up the component (assemble), act if necessary (click submit, for example) and assert (the form was not submitted).
In the example I provided, I used setData
. What if I forgot to write v-model
in the markup? The test would still pass based on how I wrote it. It would be giving a false positive. So I do agree with you, it would be ideal to simulate the user input in this case.
Either way I would still write an e2e test using something like cypress.io, and fully exercise that entire page to have full confidence. But this is something Vue test utils should (can?) do.
@eddyerburgh I'm interested in your opinion about this topic, and is there even a way to set a input
inside a shallowMount
component using vue-test-utils
?
@eddyerburgh I would also be curious to hear your thoughts on this.
As an aside to all the previous comments, I purchased the Testing Vue.js Applications (V6) recently, and attempted to use the code in chapter 5 that demonstrates how to test a component when a user inputs data into an input field.
wrapper.find('#my-element').value = '1234567'
wrapper.find('#my-element').trigger('change')
Doesn't seem to work for me. Currently the DOM element that I have my #my-element
id on is a b-form-input
provided from Bootstrap Vue. Does this pattern for mimicking user behavior in a unit test also work for a b-form-input
? If so, that would go a long way in helping me know that this behavior is a result of something that we've done something wrong, and not that unit testing a b-form-input
by changing its value with .value =
and .trigger('change')
inherently doesn't work. Thanks!
I think that should be trigger('input')
if he is updating a <input>
. Change is for <select>
. (haven't got the book on hand right now, so can't confirm).
Ya. That is how I originally had my code, and it wasn't working, so I attempted to use .trigger('change')
, but had the same result.
As another aside, I've been a long time proponent of TDD coming from a background of server side programming languages, but my experience with TDD as it relates to JavaScript frameworks has been less than mediocre. Blog articles that I read (and books for that matter) do a good job of laying out how to TDD an application that is fairly simple, but thus far I've only worked on (perhaps needlessly) complicated projects.
In the current project I am working on, we have built a custom form builder, which has required that we create several base Vue components that get extended by several other components, and our Vuex store has a fair amount of complexity in it as well. I'm finding it more and more difficult to find answers on how to wrap these components with unit tests because I'm finding it impossible to get the component under test to mount
or shallowMount
so I can actually test it. I fully recognize that this is likely because the application has been written in such a way that it is difficult to test, but what is the path forward? So far I haven't found any good resources on how to begin refactoring a Vue.js (or any JavaScript framework project) so that it is testable.
@lmiller1990 @eddyerburgh any encouraging words for me to maintain my belief/desire to continue practicing TDD?
@mjvezzani I hear you loud and clear. I come from Ruby on Rails, where testing is built in and works great out of the box (mainly from many years of hard work by the community. I'm sure it was not good back in the early days, either).
This is my opinion from the last year or two of developing with Vue - take it was a grain of salt, everyone has their own style and preferences.
My experience regarding Vuex has been to test the two "sides" of it, if you will.
commit
with jest.fn
, and assert expect(commit).toHaveBeenCalledWith(mutationHandler, payload)
.Of course this means that you could break a getter, and the Vue component that relies on that getter will not fail. That's unit tests for you, they only test things in isolation.
Not to plug my own guide, but I wrote about it in detail here (with the help of 15 contributors).
For the case of a complex form using a Vuex store and several components that compose together, I think you should test each part individually (store, mutations, validations). As for making sure it works together, it should be tested using an e2e test, using something like Selenium (meh, but what I use at work) or cypress.io (awesome).
shallowMount
and testing around component frameworksMy personal experience reflects what you are encountering, regarding testing components composed of many other components. It's awkward and doesn't feel very beneficial. If possible, make your components smaller and more focused, so they are easier to test.
Some practices I have adopted:
shallowMount
almost exclusively. It's a unit test, by using mount
it doesn't seem like a unit test anymore. I haven't found many use cases for mount
.setMethods
, setData
etc). Like I demonstrated above in my snippet.trigger
to test clicking buttons, then assert events are emitted, or some method is called.Another case that comes up a lot is "how do I test my components that use vuetify/vuebootstrap/whatever. I don't know what other people are doing, but in my experience if I have a component like this:
<template>
<v-form v-model="valid">
<v-text-field
v-model="name"
:rules="nameRules"
:counter="10"
label="Name"
required
></v-text-field>
</v-form>
</template>
<script>
Vue.use(Vuetify)
export default {
data() {
name: '',
nameRules: [this.short, this.long]
},
methods: {
short(val) { return val.length < 3 },
long(val) { return val.length > 10 }
}
}
</script>
In this case, I know that v-form
works, since Vuetify already has tests around that. That means I should not be testing it. In this case, the code I test is the validations. I would just test it like this (docs here for v-form
):
const factory = (name) => shallowMount(Component)
it('prohibits short names', () => {
const wrapper = factory()
expect(wrapper.vm.short('aa')).toBe(false)
})
it('prohibits long names', () => {
const wrapper = factory()
expect(wrapper.vm.short('12345678910')).toBe(false)
})
it('accepts the name', () => {
const name = 'some_name'
const wrapper = factory()
expect(wrapper.vm.short(some_name)).toBe(true)
expect(wrapper.vm.long(some_name)).toBe(true)
})
Let's say name
actually comes from this.$store.state.name
. Test doesn't change - the component does not need to know where the name
comes from, only if it is valid.
So, say we have a very complex Vuetify + Vuex form. What do I do?? Unit test the mutations and actions, and validations. Since my backend is Rails, I write a bunch of E2E tests using the testing tools there, filling out the form, submitting, and making sure that the form submission did not occur, or the correct error message is rendered, or database was correctly updated.
This take a lot longer to write, and run, that a unit test, but it is the only way I have found I can have confidence everything works together.
That was a pretty long answer, but hopefully it gives you some food for thought and keeps your motivation for Vue testing and TDD in general high! Although you can force it, I don't think vue-test-utils
alone is enough to fully "test" your Vue app, and is best when used to test small units of work.
@lmiller1990 Thanks for sharing it, but I still have some questions about testing with shallowMount only, maybe you can clarify it for me.
How to use shallowMount
if component I want to test doesn't have pure inputs/buttons, but uses some wrapper components, e.g <input-wrapper v-model="someValue" />
. In that case I just have to use mount to reach the input.
I'd be happy to work with component-wrapper itself instead of input. If I use shallowMount, I still can find input-wrapper
by name or importing it and passing into find
like this:
import InputWrapper from '@/some/path/to/InputWrapper.vue'
const inputWrapper = wrapper.find(InputWrapper)
But I can't neither trigger input on that component nor call setValue
- both don't work. Should they?
// doesn't work (also type of second arg `object` according to typings I have now)
input.trigger('input', { some: 'more complex value than just string' } as any)
// produces error: wrapper.setValue() cannot be called on this element
input.setValue('some value')
upd: this how it works for me now:
const input = wrapper.find(InputWrapper)
input.vm.$emit('input', 'some value')
I think I'm passing through a similar issue by now. In my case I'm using Choices as a third party component and Jest as test runner.
Here is a JSFiddle as an example.
Here is my test:
import CustomSelect from '@/CustomSelect';
import { mount } from '@vue/test-utils';
let wrapper,
options = [
{
key: 'Foo',
value: 'foo',
},
{
key: 'Bar',
value: 'bar',
},
{
key: 'Baz',
value: 'baz',
},
];
beforeEach(() => {
wrapper = mount(CustomSelect, {
propsData: {
options,
},
});
});
it('Emits an `input` event when selection changes', () => {
wrapper.vm.choicesInstance.setChoiceByValue([options[1].value]);
expect(wrapper.emitted().input).not.toBeFalsy();
});
This only test case above does not work..
For some reason, when I change the value through the choicesInstance
it does not emits the input event only when unit testing. If I do the exact change programmatically using the browser console or interacting with Choices it works. Vue extension detects the input event correctly, but somehow this is not happening while testing with Jest.
@Alendorff My thoughts about all this discussion is: I want to expect 'input' emitted but instaead of this I should emit 'input', but it's not I wanted initially
This test for vue-multiselect is not working =(
it('node_modules vue-multiselect is emitted input by changing prop value', () => {
expect.assertions(1);
const wrapper = mount(VueMultiselect, {
localVue,
propsData: {
options: ['foo', 'bar', 'baz'],
},
});
// setValue unsupported, cause root-element
// wrapper.setValue('bar');
wrapper.setProps({ value: 'bar' });
expect(wrapper.emitted('input')).toHaveLength(1);
});
I am having more or less the same problem that @lmiller1990 solved, I post the link of my question about stack overflow so I avoid rewriting a lot here: https://stackoverflow.com/questions/64572492/unit-test-how-can-i-correctly-trigger-a-trigger-event-on-an-input-which-calls-a
Thanks in advance for your answers.
Can you share more code? Where is checkSubmitStatus
and what does tit look like?
@lmiller1990
checkSubmitStatus is written what it does, it calls updateSubmitDisabled (which is itself in the mutations) to check if the vmodel is greater than 0.
I will reply in SO
I will reply in SO
I finally settled with:
it("should call the updateSubmitDisabled mutation", () => { const wrapper = mount(UserForm, { localVue, store }); const input = wrapper.get('input[name="name"]'); input.element.dispatchEvent(new Event('input')); expect(mutations.updateSubmitDisabled).toHaveBeenCalled(); });
Currently have similar issue with the input events been not triggering events, have tried both 'trigger' function and also the dispatchEvent doesn't really work.
GitHUB reference component (AddCustomer ==> InputWidget ==> BFormInput)
[Error log for discussion ] GitHUB reference test spec file
test("Given a encoded base57-UUID for 'Add Customer->Alphanumeric ID' is input, When the base57-UUID is matching all validation criteria, Then this results in valid condition and feedback text is <empty>", async () => {
const spied_text_validator = jest.spyOn(
TextValidation.prototype,
"validate_uuidBase_fiftyseven_encode"
);
const input_all_ids = wrapper.findAll("#input-widget");
const input_alphanumeric_ids = input_all_ids.at(0);
input_alphanumeric_ids.element.setData(String,uuid_base57);
input_alphanumeric_ids.element.dispatchEvent(new Event('input')); // is not a function error received.
await Vue.nextTick();
const parent_id_events = input_alphanumeric_ids.emitted("update:value"); // the event sent from the child component
expect(parent_id_events).toHaveLength(1); <--- // **error as the response we obtain is undefined**
}
Please let me know how to properly dispatchEvent as its not working the relationship (Parent) AddCustomer ==> (Child) InputWidget ==> (Grand Child) BFormInput
The input event when triggered on instance of the (Child) instance isn't responding with ('update:value')
So many things are confusing here.
input_alphanumeric_ids.element.setData(String,uuid_base57);
element
is an HTML element right? Those don't have setData
functions, that's part of Vue Test Utils.
If you would like to update an input with v-model
on it, you can use await wrapper.find('#foo').setValue('some value')
. Hopefully this will get you going in the right direction - you should not need dispatchEvent
or element
very often.
Thanks, for a quick response.. I will try your suggestion of await wrapper.find('#input-widget').setValue('data')
, and tryout the testing today.
I'm able to trigger a click event with vue-test-utils, but can't seem to trigger an input event.
Here's my component:
Here's my test:
The test fails with the following output: