4

My web application, on load, automatically redirects the user to a URL on a different origin via the window.location.replace method based on their user parameters.

When Cypress tests my application and attempts to follow the redirect, it detects the violation of the same-origin security policy and the test crashes. But I still need to test that window.location.replace is being called correctly.

Based on Cypress's documentation, I believe I need to use cy.stub() to mock the function, in order to avoid the side effect of the browser actually redirecting to a different origin.

I have tried several different ways to stub window.location.replace, but none of them seem to work as I expect.

// none of these work

cy.stub(window.location, "replace")
// TypeError: Cannot redefine property: replace

cy.stub(window, "location.replace")
// TypeError: Cannot stub non-existent own property location.replace

window.location.replace = cy.stub()
// TypeError: Cannot assign to read only property 'replace' of object '[object Location]'


cy.visit("http://localhost:3000");

expect(window.location.replace).to.be.called;
expect(window.location.replace).to.be.calledWith('https://some-other-origin.com/some/url')

I do not believe I want to use cy.location() because, by the time the redirect has occurred, the test has already crashed due to the same-origin security violation.

MattSidor
  • 2,599
  • 4
  • 21
  • 32

2 Answers2

1

Take a look at Deal with window.location.replace. The approach is to rename window.location in the source, before the page is loaded.

How well this works depends on the structure of your app. If you post some details, I can look at giving a more specific example.

it('replaces', () => {

  cy.on('window:before:load', (win) => {
    win.__location = {                           // set up the stub
      replace: cy.stub().as('replace')
    }
  })

  cy.intercept('GET', 'index.html', (req) => {   // catch the page as it loads
    req.continue(res => {
      res.body = res.body.replaceAll(
        'window.location.replace', 'window.__location.replace')
    })
  }).as('index')

  cy.visit('index.html')
  cy.wait('@index')

  cy.contains('h1', 'First page')
  cy.get('@replace').should('have.been.calledOnceWith', 'https://www.cypress.io')
})
0

Have you tried relaxing the security policy in your cypress configuration.

There are few options depending on your needs like --disable-features=CrossSiteDocumentBlockingAlways,CrossSiteDocumentBlockingIfIsolating

A good blog which I found on the topic is : https://medium.com/@you54f/configuring-cypress-to-work-with-iframes-cross-origin-sites-afff5efcf61f

Give it a shot and let me know if it was helpful.

Cheers Rupesh

rupesh
  • 241
  • 1
  • 3
  • 7