Home > Net >  Trying to click through list of links in table - Cypress
Trying to click through list of links in table - Cypress

Time:08-18

I am trying to itirate through a list of links on a table and ensure the next page has ht ecorrect url but running into issues. One problem is that there are no good class names to work with so I have been using cy.xpath.

//Loop through each element (This is a dynamic amount of elements)
cy.xpath('//span[text()="Id"]//following::a[contains(@href,"maps")]'.each($el) => { 
  cy.get($el).then(($btn) => {
    let id_text = $btn.text()
    
    //Check that the element is visible and click on it
    cy.get($el)
      .should('be.visible')
      .click()

    //Check that the url contains the text value of the element that was clicked on
    cy.url()
      .should('contain', id_text)
    
    })
  })

It works one time through and then gets tripped up saying the DOM element became detached

CodePudding user response:

You can shorten your code like this:

cy.get('[href*="maps"]').each(($el) => {
  let id_text = $el.text().trim()

  //Check that the element is visible and click on it
  cy.wrap($el).should('be.visible').click()

  //Check that the url contains the text value of the element that was clicked on
  cy.url().should('contain', id_text)
})

CodePudding user response:

When you see DOM element became detached it means an action has made the page refresh and a previous query is no longer pointing at a valid element.

In you case, the action is the .click() and the list of elements selected by cy.xpath('//span[text()="Id"]//following::a[contains(@href,"maps")]') has been refreshed, so the list that Cypress is iterating over is no longer valid.

One approach to solving this is to separate the test into two loops.

const links = [];   // save link info here

cy.xpath('//span[text()="Id"]//following::a[contains(@href,"maps")]')
  .each(($el, index) => { 
    const id_text = $el.text()
    links.push(id_text)
    cy.wrap($el).as(`maps${index}`)    // save a unique alias for this link
  }) 

cy.then(function() {

  links.forEach((link, index) => {

    //Check that the element is visible and click on it

    cy.get(`@maps${index}`)             // get the element from the alias      
      .should('be.visible')
      .click()

    //Check that the url contains the text value of the element that was clicked on
    cy.url()
      .should('contain', link)
  })
})
  • Related