Search code examples
testingurlcypresse2e-testingbrowser-extension

In a browser extension document.location.href behaves differently when system is under test with Cypress


I have a javascript application and somewhere in the application I have to get the current address of the page by:

const currentUrl = window.location.href;

currentUrl should have some value like https//example.com/somepage/. It works fine in manual testing, however, when I put the system under test with Cypress, the return value of window.location.href is different from what I expected:

https://www.example.com/__/#/specs/runner?file=cypress/e2e/integration/example.cy.js

This's the actual url on the Cypress browser address bar.

What caused this behavior and how can I fix it so that during e2e testing with Cypress, the window.location.href will return what I'm expecting it to return?


Solution

  • Unfortunately testing a browser extension is not a first-class experience with Cypress.

    The app under test is contained in an iframe of the page, and as far as I know you can't attach your extension to that iframe specifically (which would give you the correct URL).

    You may be able to "mock" the URL - the only way I can see is to add additional code into the extension

    let url = window.location.href;
    
    if (window.location.hash.startsWith('#/specs')) {
      url = ...
    }
    

    Testing a browser extension in it's own window

    You can provide an isolated window for the extension by using this Cypress using child window

    I made two changes to the code

    • bumped the page load time to 2000ms

    • resolved with the child window reference

    Cypress.Commands.add('openWindow', (url, features) => {
      const w = Cypress.config('viewportWidth')
      const h = Cypress.config('viewportHeight')
      if (!features) {
        features = `width=${w}, height=${h}`
      }
      console.log('openWindow %s "%s"', url, features)
    
      return new Promise(resolve => {
        if (window.top.aut) {
          console.log('window exists already')
          window.top.aut.close()
        }
        // https://developer.mozilla.org/en-US/docs/Web/API/Window/open
        window.top.aut = window.top.open(url, 'aut', features)
    
        // letting page enough time to load and set "document.domain = localhost"
        // so we can access it
        setTimeout(() => {
          cy.state('document', window.top.aut.document)
          cy.state('window', window.top.aut)
          console.log('window.top.aut', window.top.aut)
          resolve(window.top.aut)
        }, 2000)
      })
    })
    
    cy.openWindow('http://example.com').then((win) => {
    
      cy.location('href')
        .should('eq', 'http://example.com/')   //  ✅ passes
    
    })
    

    Also, adding a console.log(url) inside the extension shows the extension is seeing the correct url now.