Home > front end >  How to get the value of an element only if another specific element is visible?
How to get the value of an element only if another specific element is visible?

Time:10-14

What I am working with:

<ul >
 <li >
  <a href="www.something.com">
   <div>
    <h2>
     <div>
      <div >
       <div>Get this text</DIV>
      </div>
     </div>
    </h2>
   </div>
  </a> 
  <button aria-label="remove">...</button>
 </li>
 <li >...Same stuff here as above li...</li>
 <li >...Same stuff here as above li...</li>
 <li >...Same stuff here as above li...</li>
</ul>

The button here has two states for the aria-label attribute which is remove (for when the button is clicked) and add (for when the button is not yet clicked).

What I want to achieve:
I want to get the value within the <a> tag, which in this case is "Get this text", BUT only if the button within its same <li> tag is set to aria-label="remove". I will also be storing the values that I get within an array to later on compare with another array.

What I have tried:

let myArray: any = []

cy.get('li[]').each(($element) => {
    cy.get('li[]').within(($element) => {
        cy.wrap($element)
            .find('button[aria-label="remove"]')
            .find('div[]')
            .invoke('text').then(text => {
                myArray.push(text)
            })
    })
}).then(() => {
    cy.wrap(myArray).as('myArray')
})

With the above code, I am getting this Assertion Error from Cypress.

CodePudding user response:

You can use has in your selector

let myArray: any = []

cy.get('li[]').each(($element) => {
    cy.get('li[]:has(button[aria-label="remove"])').within(($element) => {
        cy.wrap($element)
            .find('div[]')
            .invoke('text').then(text => {
                myArray.push(text)
            })
    })
}).then(() => {
    cy.wrap(myArray).as('myArray')
})

Or you can use parentsUntil to get back to the parent element after finding the related element with aria-label="remove"

let myArray: any = []

cy.get('li[]').each(($element) => {
    cy.get('li[]').within(($element) => {
        cy.wrap($element)
            .find('button[aria-label="remove"]')
            .parentsUntil('li[]')
            .find('div[]')
            .invoke('text').then(text => {
                myArray.push(text)
            })
    })
}).then(() => {
    cy.wrap(myArray).as('myArray')
})

CodePudding user response:

let myArray = []

const buttonCheck = document.querySelector("button").getAttribute("aria-label");
    
if(buttonCheck === "remove"){
   const aTagInnerText = document.querySelector("a").innerText;
   myArray.push(aTagInnerText.trim(" "));
}

console.log(myArray)
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">

</head>
<body>
<ul >
 <li >
  <a href="www.something.com">
   <div>
    <h2>
     <div>
      <div >
       <div>Get this text</DIV>
      </div>
     </div>
    </h2>
   </div>
  </a> 
  <button aria-label="remove">...</button>
 </li>
 <li>...Same stuff here as above li...</li>
 <li>...Same stuff here as above li...</li>
 <li>...Same stuff here as above li...</li>
</ul>
</body>

</html>

CodePudding user response:

Use the cypress-if package

let myArray: any = []

cy.get('li[]').each(($element) => {
  cy.wrap($element).within(() => {    

    cy.get('button[aria-label="remove"]')
      .if()                                // chained commands only run 
                                           // if [aria-label="remove"] exists
                                           // but does not fail if not existing      
      .parent()                            // up to parent (avoids error)
      .find('div[]')
      .invoke('text').then(text => {
        myArray.push(text)
      })
  })
}).then(() => {
  cy.wrap(myArray).as('myArray')
})
  • Related