How can I test the focus of a text field in a Vue component?

I am new to Vue and I've been asked to implement tests for some components. This is the component:

 <template>
  <v-form>
    <v-container>
      <v-text-field
        v-on:keydown.enter.prevent
        v-model="filterName"
        dense
        clearable
        style="transition: all 0.3s ease; width: 12rem;"
        class="mt-6"
        @focus="isFocused = true"
        @blur="isFocused = false"
        ref='filter'
      >
      </v-text-field>
    </v-container>
  </v-form>
</template>

<script>
export default {
  name: "FilterBox",

  data: () => ({
    isFocused: false,
  }),

  computed: {
    filterName: {
      get() {
        return this.$store.getters.filter.name
      },
      set(value) {
        this.$store.commit('set_filter_name', value)
      }
    }
  },
  mounted() {
    this.$refs.filter.focus()
  },
}
</script>

This is the test that I implemented for that component:

import Vue from "vue";
import Vuex from "vuex";
import Vuetify from "vuetify";
import { shallowMount } from "@vue/test-utils";
import FilterBox from "@/components/FilterBox";

Vue.use( Vuex );
Vue.use( Vuetify );

describe( 'Filter Box', () => {
  let store;
  let getters;
  let vuetify;

  beforeEach( () => {
    vuetify = new Vuetify();
  } );

  it( 'should return a valid wrapper of the component', function () {
    getters = {};
    store = new Vuex.Store( { getters } );

    const wrapper = shallowMount( FilterBox, {
      store,
      vuetify
    } );
    expect( wrapper.exists() ).toBe( true );
  } );
} );

But when I run it, I keep getting this error:

Cannot read properties of undefined (reading 'focus')
TypeError: Cannot read properties of undefined (reading 'focus')

I tried this approach:

getters = {
  filter: () => {
    return jest.fn()
  }
};
store = new Vuex.Store( { getters } );

But then I got this error:

this.$refs.filter.focus is not a function
TypeError: this.$refs.filter.focus is not a function

Can anyone help me figure out what I'm doing wrong here? How can I test that the text field is focused on mount hook?

Upvotes: 0

Views: 761

Answers (1)

Anh Tuan Nguyen
Anh Tuan Nguyen

Reputation: 979

Try using mount(...) instead of shallowMount(...) for the tests that are testing the focus.

In your case @focus and @blur are events provided by v-textfield and accessed via ref. Using shallowMount you don't actually render v-textfield but a stub instead. This is useful in tests where you don't want to test the implementation of your sub-componentsn

Upvotes: 2

Related Questions