16

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'
}

2 Answers 2

22

Option 1: Check disabled attribute

In 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() 👈

Option 2: Check disabled property

The 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

Sign up to request clarification or add additional context in comments.

Comments

11

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.