Search code examples
vue.jsvue-componentvuex

Vue test component: Can't select element from a snackbar


I'm really confused when using Vue services to test. My test issue is related to vue, vuetify, vuex, vuei18n.

I will summary my set-up test here (I also noted the failed step in it) :

import Vue from "vue";
import Vuetify from "vuetify";
import VueI18n from "vue-i18n";
import store from "@/store/index";
import Login from "@/views/Login.vue";
...

beforeEach(() => {
  Vue.use(Vuetify);
  Vue.use(VueI18n);
  i18n = new VueI18n({
    messages: { fr, en, vi }
  });
  Constructor = Vue.extend(Login);
});

describe("Login.vue", () => {
...
test("should translate helper message when failing in login", () => {
    i18n.locale = "en";
    vm = new Constructor({ store, i18n }).$mount();

    vm.$el.querySelector("input[type='email']").value = "incorrect user";
    vm.$el.querySelector("input[type='password']").value = "incorrect password";
    vm.$el.querySelector("button[type='submit']").click();

    const message = vm.$el.querySelector(".v-snack__content").textContent;

    console.log(111, message); <-- I can't get any string here
    expect(message).toEqual("Login error, please retry");
  });
}

The button I click run this function

** Login.vue

<template>
...
  <v-btn type="submit" :disabled="logMeIn || !valid" :loading="logMeIn" @click="login">{{$t("Login")}}</v-btn>
...
</template>

<script>
methods: {
  login: async function() {
    ...
    } catch (e) {
      this.$store.dispatch("ui/displaySnackbar", {
        message: this.$i18n.t("Login error, please retry")
      });
    ...
  }
}
</script>

We use Vuex to render this component:

** Snackbar.vue

<template>
  <v-snackbar v-model="snackbar.show" :color="snackbar.color" :timeout="snackbar.timeout">
    {{ snackbar.message }}
    <v-btn dark flat @click="snackbar.show = false">{{ $t("Close") }}</v-btn>
  </v-snackbar>
</template>

<script>
import { mapState } from "vuex";

export default {
  name: "Snackbar",
  computed: {
    ...mapState("ui", ["snackbar"])
  }
};
</script>

My question is: Why vm.$el.querySelector can't access element in Snackbar.vue. I need it to test some texts inside


Solution

  • It has just not done async login my guess is here. Test if login has been called and test the login method in its own unit - currently its a weird approach to test the login method.


    E.g.:

    describe("clicked submit", function clickedSubmit(){
    
      it("should call vm.login", function(){
       ...
       expect(vm.login).toBeCalledTimes(1)
       expect(vm.login).toBeCalledWith("args")
      })
    
    })
    
    describe("vm.login", function(){
    
        describe("called with invalid userdata & invalid pass", function(){
    
          it("should invalidate", async function(){
    
            await vm.login(...args)  
            await vm.$nextTick()
            ...
            expect(vm.message).toBe("target value")
            //expect(vm.$el...)
          })
        })
      })