cypress-io / cypress

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

`url:changed` should capture redirects #5577

Closed scommisso closed 1 year ago

scommisso commented 5 years ago

Current behavior:

cy.on('url:changed') does not fire with URL's that trigger 302's. It only fires with the final destination (2xx code).

Screen Shot 2019-11-01 at 1 44 00 PM Screen Shot 2019-11-01 at 2 01 43 PM

Desired behavior:

This event (or possibly a new event) should fire when a 302 is encountered. For example, cy.visit() will return redirects in the response object that can then be captured, so hopefully there is a mechanism to capture this. If you want to test on the URL that triggered the redirect, it must be known. However, if the test performs a URL change in response to a UI interaction that ends up triggering the redirect, it may not be possible to know what that URL is in order to perform asserts on it.

Real world use case:

tl;dr: I am testing an entry point to my application from another application where the user redirects into my application. I need to run asserts on the URL that triggers the redirect.

full scenario: A product purchase triggers a navigation to a product configuration page that may (due to A/B testing through split.io) contain a URL parameter that instructs that page to perform a redirect out, effectively skipping product configuration. This URL is generated on-the-fly. I don't want to skip product configuration in my UI test, because I need the configuration in order to set up my product correctly for further stages of the test. I need to capture that URL, strip out the query parameter that triggers the redirect, and then perform a cy.visit() on that URL in order to set up the test appropriately.

Related issue (must be solved first): https://github.com/cypress-io/cypress/issues/5576

Steps to reproduce: (app code and test code)

  cy.on('url:changed', newUrl => {
    console.log('newUrl', newUrl);
  });
  cy.visit('https://httpstat.us/302');

This will log newUrl https://httpstat.us/, which is the target of the redirect from the 302 page. I should see both newUrl https://httpstat.us/302 and newUrl https://httpstat.us/ logged to console.

Note: This test is contrived because I know that you can look at the response object from the cy.visit(), but if this navigation was triggered from UI interaction you would not be able to do this.

Versions

jennifer-shehane commented 5 years ago

Can confirm this only triggers once when visiting 302 redirected sites.

jennifer-shehane commented 5 years ago

This may have been discussed as part of the v5 work https://github.com/cypress-io/cypress/issues/2840

Temi89 commented 3 years ago

Hi there this issue still very much exists how do we go about resolving it or do we need to pass in extra parameters ? I guess the reason why you are not able to replicate this is because you dont make any cy command calls as part of the function you are passing into event Url:changed. If you replace console.log() with cy.log you will get the same error as the reporter :

This will work !!!

cy.on('url:changed', (newUrl) => { console.log('newUrl', newUrl) })

This will give you promise errors

cy.on('url:changed', (newUrl) => { cy.log('newUrl', newUrl) })

jscheinhorn commented 2 years ago

I have seen the on url:changed event handler be flaky. I have two separate cypress runs of the same test where the video on dashboard shows success in one run (all URLs successfully collected from the "url:changed" event), and another run that fails because it does not gather one of the redirect URLs --even though I can see the redirect URL change in the dashboard video.

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.

cypress-app-bot commented 1 year ago

This issue has been closed due to inactivity.