Search code examples
cypresscy.intercept

Unable to reference callCount on cypress spy


Basically in our internal system we have an order page that someone fills out, then hits save to 'publish' it to the DB. The published page is then displayed and the pageview POST is sent.

I have attempted to follow the examples as follows -->

cy.intercept('POST', '/api/order/').as('orderPublished');
cy.intercept('POST', '/api/user/pageview', cy.spy().as('postSpy');
cy.wait('@orderPublished').then((capture) => {
    cy.log('pageViewPostCount --> ', cy.get('@postSpy').its('callCount'));
    });

However instead of getting a count i am getting a window object in the log --> cypress log output

Am trying to find out 2 things:

  1. Am I creating the spy correctly for the Interception object returned?
  2. How do I path to the value of the call count of the alias?

I have looked over the documentation at Cypress and it shows how to 'spy' on an object that is easily created or a method that is easily referenced but I do not see examples on how to do what I am attempting. I have seen one or two articles referencing that the @ doesn't work for the cy.get but in other articles people say it works. I obviously by the log am getting something, it appears the window object, so not really certain how to proceed.

I have excluded multiple lines of code but the traditional cy.intercept().as(aliasName) coupled with the cy.wait(aliasName) doesn't work for this.


Solution

  • It's quite tricky to get the call count for a spy that records something that happens asynchronously (like waiting for a network intercept).

    The command cy.get('@postSpy') gives you a snapshot of the spy at that time, but it doesn't wait for all the calls to be made.

    From what you describe, orderPublished occurs first then pageview. So you need to wait for pageview also.

    Using cy.intercept(...).as('some-alias') is actually a spy, so you can drop the cy.spy() code altogether.

    So, to start with do this

    cy.intercept('POST', '/api/order/').as('orderPublished');
    cy.intercept('POST', '/api/user/pageview').as('pageview');
    
    // Submit form
    
    // wait for publish call
    cy.wait('@orderPublished')  
    
    // wait for pageview
    cy.wait('@pageview')
    

    Now, the question is - what do you want to do with callCount?

    If your test is

    it('Check that there is only one `pageview` call', () => 
    

    how do you check that a second call never happend?

    IMO the best is to allow the test to fail and assert that it does fail.

    • add a done parameter to the test

    • add a cy.on('fail') handler to catch the test failure

    • add a second cy.wait('@pageview') which will cause the failure

    it('Check that there is only one `pageview` call', (done) => {
    
      cy.on('fail', () => done())  // this tells Cypress we expect to fail
    
      cy.intercept('POST', '/api/order/').as('orderPublished');
      cy.intercept('POST', '/api/user/pageview').as('pageview');
    
      // Submit form
    
      // wait for publish call
      cy.wait('@orderPublished')  
    
      // wait for pageview TWICE
      cy.wait('@pageview')
      cy.wait('@pageview')   // will cause an error if the 2nd call does not happen 
    })
    

    What's wrong with the cy.log()

    The problem in the cy.log() statement is that all cy.get() return the object you see in the screenshot, not the raw callCount number you want.

    You can fix that by using .then(), although as already mentioned that does not help your test pass.

    cy.get('@postSpy').then(spy => {
      cy.log('pageViewPostCount --> spy.callCount)
    })