Search code examples
javascriptcypress

How can I filter out elements that only differ in class name?


I am trying to find a way to click on one of the buttons, the only difference between them locator-wise is the parent class. So the simplified locators for these elements would look something like this:

<div class="info-card-red">
<button type="button">click</button>

<div class="info-card-green">
<button type="button">click</button>

<div class="info-card-grey">
<button type="button">click</button>

They are all under a common parent class <div class="info-card>

The problem is that the environment changes dynamically, and I don't know which card and how many will be displayed. I need to click on a button under info-card-red or info-card-green but not on info-card-grey.

So I need a way to either single out pressing a button under any class that is NOT info-card-grey or to click a button under info-card-red OR info-card-green. I have not figured out how to implement OR in Cypress yet.

I tried this, but it didn't work :

cy.get('.info-card')
    .find('class')
    .not('.info-card-grey').eq(0)
    .find('button')
    .click()

Solution

  • If your HTML looks like this (edited your sample to include closing divs)

    <div class="info-card">
      <div class="info-card-red">
        <button type="button">click red</button>
      </div>
        
      <div class="info-card-green">
        <button type="button">click green</button>
      </div>
    
      <div class="info-card-grey">
        <button type="button">click grey</button>
      </div>
    </div>
    

    then your test would be

    cy.get('.info-card')
      .find('[class^="info-card"]')          // yields red, green, grey
      .not('.info-card-grey')                // yields red, green
      .eq(0)                                 // yields red
      .should('have.class', 'info-card-red') // confirm the card you want is correct
      .find('button')
      .click()
    

    The only real change to your test is .find('class') is looking for an element with tag "class", i.e <class></class>.

    Using [class^="info-card"] in the selector means

    • searching for an attribute (designated by [...])
    • which has key of class ([class...])
    • and value starting with (^=)
    • the text ^="info-card".