0

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')
  });
});
Fody
  • 23,754
  • 3
  • 20
  • 37
ElVincitore
  • 355
  • 2
  • 12
  • The use of Cypress.env may be complicating things for your tests. Do your testids and urls change between each environment? – jjhelguero Aug 31 '22 at 01:14

2 Answers2

0

It could be that the cy.reload() is resetting isRequestCalled.

If any commands such as visit or reload causes the browser to reset, you will notice the browser clearing and it's a sure sign that variables set up globally such as isRequestCalled are also cleared.

I can't really tell the intention of some of the commands, but perhaps you could test the value before the reload.

cy.wrap(isRequestCalled).should('eq',false)
cy.reload()

Also, what is the trigger for requests intercepted by Cypress.env("REQUEST_URLS")?

If it's cy.visit(Cypress.env('BASE_URL')) then the intercept needs to come before the visit.

If it's cy.get(```[data-testid='${Cypress.env("BUTTON1_TESTID")}']```).click() then the ordering is ok.

Fody
  • 23,754
  • 3
  • 20
  • 37
0

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.

  • 1
    I think that wouldn't work, I want to verify that the requests were not made so using $cy.wait()$ would eventually time out. – ElVincitore Sep 01 '22 at 17:00
  • Oh, my bad, I did not see that you want to assert them *not* being called. This is way trickier. I tried some hacks, but was not able to do so. – Viktor Nedelko Sep 02 '22 at 08:32
  • In that case, what you might wanna do is throw a new custom error within the `then` block of the provided intercept. `cy.intercept('**/path/**').then(() => { throw new Error('Request intercepted');});` Note, that in this case you'd probably need to define intercepts within the `it` blocks as throwing errors in hooks is not supported in Cypress. – Viktor Nedelko Sep 02 '22 at 08:44