Search code examples
vue.jscypresspiniacypress-intercept

Can I test my pinia store and intercept URLs with cypress without visiting the GUI?


I want to test my pinia store actions results - right error throwing, and other behavior with cypress.

therefor I want to intercept my api endpoints.

As a result of my interception I get a html result, which I cannot find in any other case:

api call result: (punchline not my expected fixture but a error script from cypress)

<html>
  <head>
    <meta charset="utf-8">
    <title>integration/undefined/api/resource1/1/resource2</title>
  </head>
  <body>
    <script type="text/javascript">
      document.domain = **'localhost'**;
      
      (function(parent) {
        var Cypress = window.Cypress = parent.Cypress;
        if (!Cypress) {
          throw new Error("Tests cannot run without a reference to Cypress!");
        }
        return Cypress.onSpecWindow(window, [{"absolute":"/***/tests/e2e/support/index.js","relative":"tests/e2e/support/index.js","relativeUrl":"/__cypress/tests?p=tests/e2e/support/index.js"},{"absolute":"tests/e2e/specs/undefined/api/resource1/1/resource2","relative":"tests/e2e/specs/undefined/api/resource1/1/resource2","relativeUrl":"/__cypress/tests?p=tests/e2e/specs/undefined/api/resource1/1/resource2"}]);
      })(window.opener || window.parent);
    </script>
  </body>
</html>

My expectation is that this line has the most information, but I don't find anything to that integratoion/undefined part.

<title>integration/undefined/api/resource1/1/resource2</title>

this is my test file:

You can see I don't call cy.visit("/") (is that a problem?)

import { createPinia, setActivePinia } from 'pinia'
import {useRes2Store} from "@/store/resources/res2Store";

describe('Res2 Store', () => {

    beforeEach(() => {
        const pinia = createPinia()
        setActivePinia(pinia)

        
        cy.fixture('res.json').as('res2')
        cy.intercept('GET', '/api/resource1/1/resource2', {fixture: 'res.json'})
    })

    it('Call the tagStore action to get res2 items to a res1', () => {
        const res2Store = useRes2Store()  // Store initialisieren

        cy.wrap(res2Store.getRes2(1)).then(() => {
            cy.get('@res2').then((res2) => {
                expect(res2Store.res).to.deep.equal(res2)
            })
        })
    })
})

I tried to find config parameters. Do I need to set any .env.test file up?

I checked that the fixture is working

I saw, that in the console of the cypress test, the get request is sent

sadly to: http://localhost:8080/__cypress/iframes/integration/undefined/api/resource1/1/resource2

port 8080 is the vuejs app itself:

App running at:
  - Local:   http://localhost:8080/ 

my cypress config:

{
  "pluginsFile": "tests/e2e/plugins/index.js"
}

Solution

  • It may be better to wait on the intercept rather than asserting directly after the action call.

    I didn't have a problem with your test code, but it may depend on the amount of processing occurring post-fetch (in the action).

    There is a sample Pina app lmiller1990/pinia-example which I downloaded and updated to latest Vue/Pinia.

    It has a products store with a fetchAll() action that fetches from window.fetch('http://localhost:8080/products'). I modified the fetch to match yours: window.fetch('/api/resource1/1/resource2').

    Modified test

    import { createPinia, setActivePinia } from 'pinia'
    import { useProductStore } from '../../src/store/products'
    
    describe('Products Store', () => {
      beforeEach(function() {
        const pinia = createPinia()
        setActivePinia(pinia)
    
        cy.fixture('products.json').as('products')
        cy.intercept('/api/resource1/1/resource2', {fixture: 'products.json'})
          .as('pinia')
      })
    
      it('Call the productStore.fetchAll() action', () => {
        
        const productsStore = useProductStore() 
        cy.then(() => productsStore.fetchAll())
    
        cy.wait('@pinia').then(() => {
          cy.get('@products').then(products => {
            const all = productsStore.all
            expect(all['1']).to.deep.eq(products[0])
            expect(all['2']).to.deep.eq(products[1])
          })
        })
      })
    })
    

    products.json fixture

    [
      {"id":"1", "name":"cypress"},
      {"id":"2", "name":"pinia"}
    ]
    

    Cypress log

    enter image description here