Search code examples
node.jscypressend-to-endcypress-intercept

Variable value doesn't change in request intercept


I am trying to intercept some requests in cypress following the click of a button, and I am trying to check if requests were or not made to a list of urls. I used a variable ( isRequestCalled ) as you can see, to update it if the requests were made, but the updates don't seem to be reach the test. When a request is intercepted, the value of isRequestCalled is updated in that scope but it doesn't seem to be visible in the scope of the test. Has anyone encoutered this type of issue, I appreciate all suggestions. Thanks!

describe('E2E test', () => {
  let isRequestCalled
  beforeEach(() => {
    isRequestCalled=false
    cy.origin(Cypress.env('ORIGIN_URL'), () => {
      localStorage.clear();
    })
    cy.wait(1000);
    cy.visit(Cypress.env('BASE_URL'));
    cy.intercept('*', (req) => {
      isRequestCalled=Cypress.env("REQUEST_URLS").some((url)=>{
        return req.url.includes(url)
      }) || isRequestCalled
      // cy.wrap(isRequestCalled).as('isRequestCalled')
      if (isRequestCalled) {   
        
        req.alias =  'apiRequests'
      }
    }
  )
})
  
  it('Consent test: Deny', () => {
    
    cy.get(`[data-testid='${Cypress.env('BANNER_TEST_ID')}']`).should('be.visible').log("Banner visible");
    cy.get(`[data-testid='${Cypress.env('BUTTON1_TESTID')}']`).should('be.visible').log("Button 1 visible");
    cy.get(`[data-testid='${Cypress.env('BUTTON2_TESTID')}']`).should('be.visible').log("Button 2 visible");
    cy.get(`[data-testid='${Cypress.env('BUTTON1_TESTID')}']`).click();
    cy.reload();
    // cy.get('@isRequestCalled').then(isRequestCalled => {
    //   console.log(isRequestCalled)
    //   expect(isRequestCalled).to.eq(false)
    // })
    cy.wrap(isRequestCalled).should('eq',false)
    
    
  });
  it('Consent test: Allow', () => {
    cy.get(`[data-testid='${Cypress.env('BANNER_TEST_ID')}']`).should('be.visible').log("Banner visible");
    cy.get(`[data-testid='${Cypress.env('BUTTON1_TESTID')}']`).should('be.visible').log("Button 1 visible");
    cy.get(`[data-testid='${Cypress.env('BUTTON2_TESTID')}']`).should('be.visible').log("Button 2 visible");
    cy.get(`[data-testid='${Cypress.env('BUTTON2_TESTID')}']`).click();
    
    cy.wait('@apiRequests')
  });
});

Solution

  • When using cy.intercept() you actually have no need for any variable counters if you want to ensure that the intercepted call has been made. I would recommend aliasing all of the requests you want to intercept and simply waiting (cy.wait()) for them after you perform the action that should trigger the call

    describe('E2E test', () => {
      beforeEach(() => {
        cy.intercept('firstRequestUrl').as('firstCall');
        cy.intercept('secondRequestUrl').as('secondCall')
        cy.intercept('thirdRequestUrl').as('thirdCall')
        cy.origin(Cypress.env('ORIGIN_URL'), () => {
          localStorage.clear();
        })
        cy.wait(1000); // look into removing that as it looks kinda redundant
        cy.visit(Cypress.env('BASE_URL'));
      })
      it('Does smth', () => {
        cy.wait('@firstCall')
        cy.get('#secondCallTrigger').click()
        cy.wait('@secondCall')
      })
      it('Does smth else', () => {
        cy.get('#thirdCallTrigger').click()
        cy.wait('@thirdCall')
      })
    })
    

    P.S.Keep in mind that js/ts variables in Cypress are very tricky to use between contexts, when you declare something in the describe, hooks, or a different it, you can't easily reach it from another it block. People use env variables or hacks like this for that, although as you can see there is a native functionality for it.

    Be sure to check the rest of intercept documentation and aliases documentation for more information.