Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intercepted calls are queued before cy.wait #14703

Closed
vojta-k opened this issue Jan 22, 2021 · 5 comments
Closed

Intercepted calls are queued before cy.wait #14703

vojta-k opened this issue Jan 22, 2021 · 5 comments

Comments

@vojta-k
Copy link

vojta-k commented Jan 22, 2021

Current behavior

After calling an intercept for method and path and assigning it an alias, all calls intercepted in this manner are stored in a queue form rather than stacked as I would expect. Meaning if 2 such calls are intercepted but the first one isn't interacted with via .wait(<alias>), then interacting with the second call in this way will return information from the first one instead.

In larger, more complex app and testing code base, it is easy to unintentionally intercept a different, unwanted call prior to interacting with the desired one. So this behaviour is not ideal for that.

Desired behavior

Intercepted call should be rather stacked or possible those that aren't being interacted with forgotten. Maybe ideally there should be an option parameter to define which of these approaches will be used.

Test code to reproduce

const baseUrl = 'https://swapi.dev';

const enterRequest = (path: string) => cy.get('[type="text"]').clear().type(path);

const sendRequest = () => cy.contains('button', 'request').click();

it('processes the intercepted requests in a queue', () => {
  cy.visit(baseUrl);

  cy.intercept({method: 'GET', path: '/api/people/*'}).as('getPeople')

  enterRequest('people/4/');
  sendRequest();
  // intercepted but not waiting for the getPeople here, let's assume I am not interested in this one

  enterRequest('people/6/');
  sendRequest();
  // same situation here

  enterRequest('people/10/');
  sendRequest()
  // this is a call I want to interact with
    .wait('@getPeople').then((req) => {
      const returnedUrl = String(req.response.body.url);
      expect(returnedUrl).to.contain('people/4/'); // this will pass
      expect(returnedUrl).to.contain('people/6/'); // this will fail
      expect(returnedUrl).to.contain('people/10/'); // this should be the one to pass but if fails
    });
});

Versions

Cypress version 6.2.1
Browser Chrome 88

@vojta-k vojta-k changed the title Intercepted call are queued instead of stacked Intercepted calls are queued before cy.wait Jan 22, 2021
@jennifer-shehane
Copy link
Member

I believe this feature request might satisfy what you're asking for? #7663 If so, please add your comments and 👍 on that issue since we use interest in the feature to evaluate priority of development.

Couldn't you also be more specific with the intercept you want to listen for? Defining the path you want to listen for to be /api/people/10?

it('processes the intercepted requests in a queue', () => {
  cy.visit(baseUrl);

  // path: people/10
  cy.intercept({method: 'GET', path: '/api/people/10'}).as('getPeople')

  //...
  // this is a call I want to interact with
    .wait('@getPeople').then((req) => {
      const returnedUrl = String(req.response.body.url);
      expect(returnedUrl).to.contain('people/10/'); // we only intercepted people/10 route
    });
});

@cypress-bot cypress-bot bot added the stage: awaiting response Potential fix was proposed; awaiting response label Jan 25, 2021
@vojta-k
Copy link
Author

vojta-k commented Jan 25, 2021

Hi! Thank you for your response. The #7663 would solve the issue partially - but ideally we would like to not depend on the number of times the interception matched prior to the call that the code is waiting for (possibly if passing -1 as n would always select the last interception, then it would solve it entirely).

As for increasing path specificity, that can also work, but sometimes the full path might be difficult to obtain ("randomly" created new ID) or there might even be the same path called repeatedly but with different responses.

@flotwig
Copy link
Contributor

flotwig commented Mar 24, 2021

Hey @vojta-k, this is the expected behavior of cy.wait(). For tests to be deterministic, it's important to not arbitrarily condense requests based on timing.

As for increasing path specificity, that can also work, but sometimes the full path might be difficult to obtain ("randomly" created new ID) or there might even be the same path called repeatedly but with different responses.

Does per-request aliasing solve this for you? You can dynamically set an alias from a request handler, so you could test for your randomly created ID/whatever: https://docs.cypress.io/api/commands/intercept#Aliasing-individual-requests

@flotwig
Copy link
Contributor

flotwig commented Apr 8, 2021

Closing since all appears to be working as expected. Please open an issue if you have a new bug report or feature request.

@flotwig flotwig closed this as completed Apr 8, 2021
@jennifer-shehane jennifer-shehane removed the stage: awaiting response Potential fix was proposed; awaiting response label May 5, 2021
@mohamedatef2020
Copy link

mohamedatef2020 commented Feb 24, 2022

@flotwig @jennifer-shehane I believe this issue should be open again as it is a bug and doesn't work as expected according to cypress official documentation here: Network Requests - waiting
I'm experiencing the same behavior as @vojta-k that cy.wait() always yields the first sent request while according to the documentation it should yield the latest request.
Here is my use case where I want to verify the content of the displayed list after performing some actions while cypress always return the first default list.

cy.intercept("**list/).as("list")
getListRequest()
cy.wait(@list).then(assertDefaultData())
sortListAction()
cy.wait(@list).then(AssertSortedData()) // this is failing as it yields the first call
filterListAction()
cy.wait(@list).then(assertFilteredData()) // this is failing as it yields the first call again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants