I'm testing a Vue component but I'm having trouble testing a button's disabled state. How can I access a button's disabled status in my tests?
I've tried using .attributes() but in this instance the method only returns the button properties that weren't set by v-bind. SubmitButton.attributes().disabled is always null.
Component
<button
id="edit-resource-modal-submit"
class="btn btn-sm btn-primary modal-button"
:disabled="loadingResource || !formValid"
@click="submit"
>
Save
</button>
Test
describe('Disables buttons if', () => {
beforeEach(async() => {
await wrapper.setProps({ isModalOpen: true });
});
it('modal is loading', async() => {
wrapper.vm.loadingResource = true;
const SubmitButton = wrapper.find('#edit-resource-modal-submit');
expect(SubmitButton.exists()).toBe(true);
expect(SubmitButton.attributes().disabled).toBe('true');
});
});
.attributes() only returns
{
id: 'edit-resource-modal-submit',
class: 'btn btn-sm btn-primary modal-button'
}
disabled attributeIn Vue 2, the disabled attribute is set to "disabled" (not "true") when the element is actually disabled. In Vue 3, it's set to an empty string. The attribute itself is undefined (i.e., absent from the attributes) when the element is enabled.
To be compatible with both versions of Vue, the test could just check if the disabled attribute is defined. Also note the test should await a micro tick (via await wrapper.vm.$nextTick()) to allow the property change (wrapper.vm.loadingResource = true) to take effect in disabling the button:
const wrapper = shallowMount(MyComponent)
// update prop, and wait a tick to allow it to take effect
wrapper.vm.loadingResource = true
await wrapper.vm.$nextTick()
const button = wrapper.find('#edit-resource-modal-submit')
expect(button.attributes().disabled).toBeDefined() 👈
disabled propertyThe test could read the disabled property directly from the element reference itself, which is exposed by the test wrapper's element property:
const wrapper = shallowMount(MyComponent)
// update prop, and wait a tick to allow it to take effect
wrapper.vm.loadingResource = true
await wrapper.vm.$nextTick()
const button = wrapper.find('#edit-resource-modal-submit')
expect(button.element.disabled).toBe(true) 👈
Vue 2 demo
Vue 3 demo
For vue-test-utils with vue 3 the answer of @tony19 is also working. However its using the old api of vue-test-utils for vue 2.
As you can see the return values for attributes() do not contain disabled attribute if the element is enabled. So I would recommend to test it the following way:
expect(SubmitButton.attributes('disabled')).toBeUndefined(); // enabled
expect(SubmitButton.attributes('disabled')).toBe("") // disabled
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