cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
46.69k stars 3.16k forks source link

Intercept does not work between tests (`it`) #18063

Open giacaglia opened 3 years ago

giacaglia commented 3 years ago

Current behavior

We intercept every request call that goes out of cypress to add an AUTH header to every request. When the header is not attached we get network requests that fail. Before when using Cypress 6.8, all requests were intercepted even between tests (it). Now that is not the case anymore. This causes our tests to flake very frequently.

Desired behavior

Intercept all requests!

Test code to reproduce

You can reproduce the errors pretty consistently with the repo: https://github.com/giacaglia/cypress-test-tiny

You need to run both the frontend and the backend to test it out.

Cypress Version

8.3.1

Other

No response

michaelfarrell76 commented 3 years ago

this happens in a couple of places in our test specs:

1) dangling network requests that get triggered by some interaction with the page (i.e. someone clicks a button). we can normally resolve these by adding a cy.contains(<text that appears on the page after the mutation is completed. however there are some that are much harder to wait for completion such as a GraphQL refetchQueries request. in this case after the mutation is completed, we may want to re-fetch some other content on the page that often may not even change what is rendered on the page. there is no easy way to wait for this kind of query to be completed and we end up seeing a lot of errors in our logs.

  1. lazy loaded chunks. this is the hard one to find a workaround for. when using webpack to break out application up into smaller chunks, clicking around the application via cypress often causes these chunks to be loaded asynchronously. we may have one it statement that goes to a page that triggers a chunk to load, but we dont test that chunk until the next it statement. the sequence of events may be like:
michaelfarrell76 commented 3 years ago

at the end of the day, our goal is to attach a fixed header to any network request sent to a wildcard domain *.my-domain.com. intercept almost does this perfectly, the only issue is that these hard to control network requests between it statements dont get intercepted. our intercept code looks like:

/**
 * Intercept network requests and attach cognito auth
 */
function intercept() {
  const branch = env.branch();
  cy.intercept({ hostname: /.*.my-domain.com/ }, (req) => {
    req.headers = {
      ...(req ? req.headers : {}),
      'X-CYPRESS-AUTH': env.cognitoAuth(),
    };
    req.url = new ImmutableUrl(req.url);
  });
}

before(() => {
  intercept();
});

beforeEach(() => {
  intercept();
});
giacaglia commented 3 years ago

This is blocking our upgrade to 8.3.0

giacaglia commented 2 years ago

Would love any updates on this issue!

giacaglia commented 2 years ago

@jennifer-shehane do you need any more information for this issue? I've created a repo to reproduce the error above!

michaelfarrell76 commented 2 years ago

hey @jennifer-shehane sorry to bother here, but do you know if any new functionality has shipped recently that may have helped with this? we are still stuck on cypress 6

michaelfarrell76 commented 2 years ago

this was fixed in cypress 9 it seems!

ismyrnow commented 2 years ago

I can confirm that I'm still seeing this behavior in cypress v10.6.

My use case is defining intercepts in a beforeEach hook. It appears that a test can complete, yet the page can still trigger a network request while the next test's beforeEach hook is running (which is prior to those network request intercepts being defined).

In other words:

  1. Test1 a. beforeEach: define some intercepts b. run the test c. test passes
  2. Test2 a. beforeEach: define some intercepts... FAILURE! Network requests triggered from Test1 are showing up in the beforeEach step, prior to intercepts getting defined!
jrogers23 commented 1 year ago

I was able to solve this by using cy.wait():

`const wait = function() { cy.wait("@countries"); cy.wait("@users"); }

beforeEach(() => { cy.intercept("GET", "/api/countries", { statusCode: 200, body: [...], }).as("countries");

cy.intercept("GET", "/api/users", {
  statusCode: 200,
  body: [...],
}).as("users");

});

it("should render correct table headers", () => { cy.mount(ManageUsers);

wait();

cy.get().should() //etc

});`

cypress-app-bot commented 1 year ago

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.

simcha90 commented 1 year ago

Still see same issue in 12.17.0 For me it happens with RTKQuery library, when you call request using internal apis:

 fetchTenantsAccess: build.query<
      MyType,
      string | number
    >({
      async queryFn(tenantId, { dispatch }, _extraOptions, fetchWithBQ) {
        const tenantAccess = await fetchWithBQ('/api1...')  // <------ This request not catched by intercept in second test
        let tenantAccessData = tenantAccess.data as TenantAccess
        let parentTenant
        if (tenantAccessData?.parentId) {
          parentTenant = await fetchWithBQ('/api2...')  // <------ This request not catched by intercept in second test
          tenantAccessData = { ...tenantAccessData, parentName: parentTenant.data?.name }
        }

        return {}
      },
      providesTags: ['Tenants', 'Access'],
    }),
  }),
michaelfarrell76 commented 1 year ago

any plans to resolve this?