Locate & Validate Values of li

Viewed 44

Below is the structure of the DOM

enter image description here

Three li are returned after I run a search. All the li have 3 values I need to validate in the below case, P, 15569, Senior big data engineer these 3 values are specific to 1 li only similar other two have different values.

I am using the below script and is working fine.

//Values from first li
   cy.get('[role="listbox"]')
   .contains('P')
   cy.get('[role="listbox"]')
   .contains('15569')
   cy.get('[role="listbox"]')
   .contains('Senior big data engineer')
   //Values from Second li
   cy.get('[role="listbox"]')
   .contains('A')
   cy.get('[role="listbox"]')
   .contains('15585')
   cy.get('[role="listbox"]')
   .contains('DB Developer')

I wanted to know if is there another way I can select the li directly and also validate the href link too.

2 Answers

The .contains() command only checks if the text is within a passed element you have passed and because you have passed in the entire combo box you may be getting false positives in what you are testing.

There are a few ways to check what you are testing with .each(), .within(), and .spread(). I recommend reading the cypress docs for each of them.

cy.get('[role=listbox]')
  .should('be.visible')
  // this gives your the 3 options
  .find('[role=option]')
  .spread(($op1, $op2, $op3) => {
    cy.wrap($op1).contains('span', 'P').should('be.visible')
    cy.wrap($op1).contains('a').should('include.text', 'P')
    .should('include.text', 'Senior big data engineer')
    // you can check href now
    .invoke('attr', 'href')

    // repeat for other options
  })

The thing I note is there's not a lot of usable classes or ids to select inside the outer listbox.

Perhaps a structural approach is better

const expected = [
  { 
    tag: "P", 
    id: "15569",
    description: "Senior big data engineer",
    href: "..."
  },
  { 
    tag: "A", 
    id: "15585",
    description: "DB Developer",
    href: "..."
  },
]

cy.get('[role=listbox]')                 // outer <ul>
  .find('li:contains(Jobs)')             // li with Jobs text
  .find('ul')                            // inner <ul>
  .find('li')
  .each(($jobBlock, index) => {
    
    cy.wrap($jobBlock).within(() => {    // focus on current job

      cy.contains('span', expected[index].tag)

      cy.get(`a[href="${expected[index].href}"]`)
        .should('contain', expected[index].id)
        .and('contain', expected[index].description)
    })
  })
Related