I am having some difficulty in testing a Vee-Validate confirmed function on a Vue form built with Vuetify. The component that I am trying to test looks like this:
<template>
<form novalidate ref="loginForm" v-model="formValid" @submit.stop.prevent="formSubmitted" @keyup.enter="formSubmitted">
<v-container grid-list-md text-xs-center>
<v-layout column>
<v-flex>
<v-text-field
name="passwordField"
label="Enter your Password"
hint="At least 6 characters"
v-model="submissionDetails.password"
:type="passwordShown ? 'text' : 'password'"
min="6"
required
:append-icon="passwordShown ? 'visibility_off': 'visibility'"
:append-icon-cb="()=>(passwordShown = !passwordShown)"
v-validate="'required|min:6'"
data-vv-name="password"
:error-messages="errors.collect('password')"
ref="password"
@change="inputTriggered"
@input="inputTriggered"
/>
</v-flex>
<v-flex v-show="createAccountTicked">
<v-text-field
name="confirmPasswordField"
label="Confirm your Password"
hint="At least 6 characters"
v-model="confirmPassword"
:type="passwordShown ? 'text' : 'password'"
min="6"
required
:append-icon="passwordShown ? 'visibility_off': 'visibility'"
:append-icon-cb="()=>(passwordShown = !passwordShown)"
v-validate="'required|confirmed:$password'"
data-vv-name="confirmPassword"
:error-messages="errors.collect('confirmPassword')"/>
</v-flex>
</v-layout>
</v-container>
</form>
</template>
<script>
export default {
name: 'email-password-form',
data () {
return {
submissionDetails: {
email: '',
password: ''
},
confirmPassword: '',
passwordShown: false,
createAccountTicked: false
};
}
};
</script>
The above works fine with the error messages being displayed on the screen correctly and removed when the passwords match, but the below test fails:
describe.only('validation', () => {
it('should not attach an error to confirm password when it does match the password', async () => {
const wrapper = mount(EmailPasswordForm, { localVue });
wrapper.setData({
submissionDetails: {
password: 'wwwwww'
},
createAccountTicked: true,
confirmPassword: 'wwwwww'
});
// await wrapper.vm.$validator.validateAll();
// await wrapper.vm.$validator.validate('password');
await wrapper.vm.$validator.validate('confirmPassword');
console.log(wrapper.vm.errors.collect('confirmPassword'));
// ['The confirmPassword confirmation does not match.']
console.log(wrapper.vm.submissionDetails.password === wrapper.vm.confirmPassword);
// true
expect(wrapper.vm.errors.has('confirmPassword')).to.be.false;
// AssertionError: expected true to be false
});
});
As can be seen from the above code, it appears that while the password and confirmPassword strings do match, the validator still flags the confirm password field as having an error. I can't understand why that might be but any help would be appreciated.
So it turns out that this behaviour is due to how Vee-Validate compares values for multi-field validation, and how those values are propagated. (See this issue)
The easiest solution was to use the new is
validation rule, which allows me to compare against the model, instead of the contents of the field. I just changed the v-validate
rule contents from 'required|confirmed:$password'
to v-validate="{required: true, is: submissionDetails.password}"
I'll leave this here in case anyone else has this issue.
On my case, either one of this two methods works for me:
<input
v-validate="{ required : true, confirmed: 'password'}"
type="password" name="confirm_password"
class="form-control"
placeholder="Confirm Password"
v-model="field.confirm_password"
data-vv-as="confirm password">
<input
v-validate="{ required : true, confirmed: field.password}"
type="password" name="confirm_password"
class="form-control"
placeholder="Confirm Password"
v-model="field.confirm_password"
data-vv-as="confirm password">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With