jquerytabscypresshref

Unable to open link within same tab using Cypress


In our web page, we have various links that open in a new tab, but obviously we need to open them in the same tab when using Cypress.

I've tried

cy.get('tr td:nth-child(9)').eq(index).invoke('removeAttr', 'target').click()

but this still opens the URL in a new tab.

I've also tried adding find('a') :

cy.get('tr td:nth-child(9)').eq(index).find('a').invoke('removeAttr', 'target').click()

but the page never loads (I've tried increasing the timeout as well but it still fails).

I would like to get the above to work, but I've also found this alternative which works, so I guess I'm confused by this code below works but I can't get the invoke to work.

cy.get('tr td:nth-child(9)').eq(index).find('a').then(link => {
                   cy.request(link.prop('href')).its('status').should('eq', 200)

Any feedback is appreciated! Thanks


Solution

  • The general recipe for this is

    cy.get('tr td:nth-child(9)').eq(index).find('a')
      .then($el => {
         expect($el).to.have.attr('target','_blank')
         // update attr to open in same tab
         $el.attr('target', '_self')
      })
      .click()
    

    The _self value may not always be required, but the other aspect is timing as you are updating the DOM.

    You could also try this

    cy.get('tr td:nth-child(9)').eq(index).find('a')
      .invoke('attr', 'href').then(myLink => {
        cy.visit(myLink);
      })
    

    Cross origin

    See this blog Stub window.open, shows a way to stub the window open.

    let stub    // variable that will hold cy.stub created in the test
    
    Cypress.on('window:before:load', (win) => {
      if (stub) {
        Object.defineProperty(win, 'open', {
          get() {
            return stub
          }
        })
      }
    })
    
    beforeEach(() => {
      stub = null
    })
    
    const href = 'url/that/link/takes/you to'
    
    it('check that window open was called', () => {
    
      cy.visit('/')  // not stubbing this
    
      stub = cy.stub().as('open')
      
      cy.get('tr td:nth-child(9)').eq(index).find('a')
        .click()    // trigger window.open
    
      cy.get('@open')
        .should('have.been.calledWith', href)   // check href is called
    
    })
    
    it('tests the link page further', () => {
      cy.visit(href)
      // continue tests
    })
    

    If your href is a changeable, you can grab it in a beforeEach

    beforeEach(() => cy.visit('/'))
    
    beforeEach(() => {
      cy.get('tr td:nth-child(9)').eq(index)
        .find('a').invoke('attr', 'href').as('href')   // link value into an alias
    })
    
    it('check that window open was called', () => {
    
      cy.get('@href').then(href => {
     
        stub = cy.stub().as('open')
      
        cy.get('tr td:nth-child(9)').eq(index).find('a')
          .click()    // trigger window.open
    
        cy.get('@open')
          .should('have.been.calledWith', href)   // check href is called
      })
    })
    
    it('tests the link page further', () => {
      cy.get('@href').then(href => {
        cy.visit(href)
        // continue tests
      })
    })