Search code examples
vue.jsvuexcypress

How to make cypress wait for the end of a vuex action before to clean localStorage?


I use cypress to test an app made with vuejs / vuex / graphql. It works thanks to this great article.

One test dispatches a vuex action from a component. This action makes multiple requests to the server. In every request, an auth token is injected from localStorage (if it exists) to the headers.

The problem: the first request of the action works fine but subsequent requests do not have the auth token in the headers anymore and fail. From what I understand, Cypress does not wait for all the requests to complete before cleaning localStorage.

component

<template>
  <button @click="save">Save</button>
</template>

<script>
export default {
  methods: {
    save() {
      this.$store.dispatch('update')
    }
  }
}
</script>

store

export const actions = {
  async update({ commit, dispatch }) {
    try {
      // the token is here
      console.log('a. token ->', localStorage.getItem('token'))

      // this works
      const res = await apiUpdate()

      // now the token is null, but why? Is it because of Cypress?
      console.log('b. token ->', localStorage.getItem('token'))

      commit('set', res)

      // this fails because the token is null in localStorage
      await apiAnotherUpdate()

    } catch (e) {
      //…
    }
  })

test

describe("My app", () => {
  beforeEach(function() {
    cy.visit("http://localhost:8080/");

    // log the user and sets the token
    cy.login();
  });

  it("test button", function() {
    cy.get("button").click();
    cy.get("#page").should("contain", "Updated content");
  });
});

What is the proper way to make this test work?

Thank you


edit

I found an ugly fix using cy.wait(2000) at the end of the test, but am still open to a cleaner solution.


Solution

  • making the function async in the component solved it.

    methods: {
      async save() {
        await this.$store.dispatch('update')
      }
    }