3 votes

Tester vuex avec cypress

J'utilise Cypress dans mon projet Vue.js (Nuxt.js). Le principal problème que je n'arrive pas à gérer est de savoir comment comprendre que le magasin Vuex est prêt. Disons que j'ai un bouton qui peut appeler axios pour récupérer des données. Ensuite, les données arrivent dans le magasin par mutations et Vue les rendra dans un modèle. L'élément suivant avec lequel je veux interagir est vide avant que le magasin ne soit construit. Mais le cyprès essaie de le vérifier.

Comment appeler l'action cypress suivante (comme cy.get) après que le magasin ait été construit ?

Mon projet est plus compliqué. Mais le problème principal est que Cypress n'attend parfois pas la construction du magasin pour essayer de travailler plus loin. Pour la première fois, nous avons utilisé cy.wait(1000) mais il semble que la décision ne soit pas si parfaite.

<div>
    <button data-cy="fetchDataBtn" @click="fetchData">get items</button>
    <ul>
        <li v-for="item in items">
           <p>{{ item.title }}</p>
           <button
                @click="fetchProduct(item.id)"
            >
                buy {{ item.name }}
            </button>
        </li>
    </ul>
</div> 

    <script>
    import { mapState } from 'vuex';
    export default {
        name: 'App',
        computed: {
            ...mapState('list', ['items'])
        }
    } 
    </script>

Je m'attends au scénario suivant :

cy.get([‘data-cy=fetchDataBtn’]).click()
// wait for store is ready and list is already rendered 
// (NOT cy.wait('GET', 'url_string') or cy.wait(milliseconds))
cy.contains(‘button’, 'buyItemName').click()

2voto

Richard Matsen Points 7624

Jetez un coup d'œil à cet article Test ... avec Vuex Store ... La clé est d'ajouter une référence à l'application Vue dans la fenêtre,

const app = new Vue({
  store,
  el: '.todoapp'
  //
})
if (window.Cypress) {
  // only available during E2E tests
  window.app = app
}

puis testez le magasin pour les clés appropriées avant de procéder au test du DOM.

const getStore = () => cy.window().its('app.$store')

it('has loading, newTodo and todos properties', () => {
  getStore().its('state').should('have.keys', ['loading', 'newTodo', 'todos'])
})

Pourtant, cela peut être encore plus simple que cela !

Vous dites

L'élément suivant avec lequel je veux interagir est vide avant que le magasin ne soit construit.

Avec la bonne combinaison de commandes, Cypress attendra le contenu récupéré via axios, pour autant que vous choisissiez l'élément "indicateur" correct et que vous testiez son état de fonctionnement. contenu par exemple

cy.contains('my.next.element.i.want.to.interact.with', 'the.content.fetched.with.axios', { timeout: 10000 })

Cela permet d'attendre jusqu'à 10 secondes pour que le contenu récupéré s'affiche (ou moins s'il apparaît plus tôt). Sans paramètre de délai d'attente, elle attend jusqu'à 5 secondes, ce qui peut être suffisant.

NOTE il y a un piège subtil avec les commandes enchaînées de Cypress.

N'utilisez pas

cy.get('my.next.element.i.want.to.interact.with')
  .contains('the.content.fetched.with.axios')

car votre modèle Vue possède probablement la balise ou la classe de l'élément dès le départ, mais son contenu est initialement vide et ce modèle n'attendront pas le contenu que vous voulez voir . Il se contentera de comparer le contenu initial (rien) sans attendre la fin de la récupération.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X