vue testing vuetify input for disabled

4.9k views Asked by At

I am very new to testing and I'm struggling my way through all this new stuff I am learning. Today I want to write a test for a vuetify <v-text-field> component like this:

  <v-text-field
    v-model="user.caption"
    label="Name"
    :disabled="!checkPermissionFor('users.write')"
    required
  />

my test should handle the following case:

an active, logged in user has a array in vuex store which has his permissions as a array of strings. exactly like this

userRights: ['dashboard', 'imprint', 'dataPrivacy']

the checkPermissionFor() function is doing nothing else then checking the array above with a arr.includes('x')

after it came out the right is not included it gives me a negotiated return which handles the disabled state on that input field.

I want to test this exact scenario.

my test at the moment looks like this:

  it('user has no rights to edit other user overview data', () => {
    const store = new Vuex.Store({
      state: {
        ActiveUser: {
          userData: {
            isLoggedIn: true,
            isAdmin: false,
            userRights: ['dashboard', 'imprint', 'dataPrivacy']
          }
        }
      }
    })
    const wrapper = shallowMount(Overview, {
      store,
      localVue
    })
    const addUserPermission = wrapper.vm.checkPermissionFor('users.write')
    const inputName = wrapper.find(
      'HOW TO SELECT A INPUT LIKE THIS? DO I HAVE TO ADD A CLASS FOR IT?'
    )
    expect(addUserPermission).toBe(false)
    expect(inputName.props('disabled')).toBe(false)
  })

big questions now:

  1. how can I select a input from vuetify which has no class like in my case
  2. how can I test for "is the input disabled?"
2

There are 2 answers

0
Eldar On

wrapper.find method accepts a query string. You can pass a query string like this : input[label='Name'] or if you know the exact index you can use this CSS query too : input:nth-of-type(2). Then find method will return you another wrapper. Wrapper has a property named element which returns the underlying native element. So you can check if input disabled like this :

const buttonWrapper = wrapper.find("input[label='Name']");
const isDisabled = buttonWrapper.element.disabled === true;
expect(isDisabled ).toBe(true)
0
Abraham Brookes On

For question 1 it's a good idea to put extra datasets into your component template that are used just for testing so you can extract that element - the most common convention is data-testid="test-id".

The reason you should do this instead of relying on the classes and ids and positional selectors or anything like that is because those selectors are likely to change in a way that shouldn't break your test - if in the future you change css frameworks or change an id for some reason, your tests will break even though your component is still working.

If you're (understandably) worried about polluting your markup with all these data-testid attributes, you can use a webpack plugin like https://github.com/emensch/vue-remove-attributes to strip them out of your dev builds. Here's how I use that with laravel mix:

const createAttributeRemover = require('vue-remove-attributes');
if (mix.inProduction()) {
    mix.options({
        vue: {
            compilerOptions: {
                modules: [
                    createAttributeRemover('data-testid')
                ]
            }
        }
    })
}

as for your second question I don't know I was googling the same thing and I landed here!