'cy.get div that hasn't got a display: none on it

I'm working on some poor code, that someone else has written. I'm trying to write some tests for the functionality, before we're changing it, so we can ensure it all works, after the feature-changes.

I have 8 siblings divs like this:

<div class="container">

  <!-- Child-1 --> 
  <div class="child-group child-1" style=""> <!-- Notice empty style-tag -->
    <div class="buttons">
      <button class="go-to-child-group-1">Child-group-1</button>
      <button class="go-to-child-group-2">Child-group-2</button>
      <button class="go-to-child-group-3">Child-group-3</button>
      ... <!-- Leaving out all the buttons for readability -->
      <button class="go-to-child-group-8">Child-group-8</button>
    </div>
    <div class="content">Content1 content1 content1</div>
  </div>

  <!-- Child-2 -->
  <div class="child-group child-2" style="display: none"> <!-- Notice display none -->
    <div class="buttons">
      <button class="go-to-child-group-1">Child-group-1</button>
      <button class="go-to-child-group-2">Child-group-2</button>
      <button class="go-to-child-group-3">Child-group-3</button>
      ... <!-- Leaving out all the buttons for readability -->
      <button class="go-to-child-group-8">Child-group-8</button>
    </div>
    <div class="content">Content2 content2 content2</div>
  </div>

  <!-- Child-3 -->
  <div class="child-group child-3" style="display: none"> <!-- Notice display none -->
    <div class="buttons">
      <button class="go-to-child-group-1">Child-group-1</button>
      <button class="go-to-child-group-2">Child-group-2</button>
      <button class="go-to-child-group-3">Child-group-3</button>
      ... <!-- Leaving out all the buttons for readability -->
      <button class="go-to-child-group-8">Child-group-8</button>
    </div>
    <div class="content">Content3 content3 content3</div>
  </div>

  <!-- 
  Etc. etc. etc.
  for group Child-4, Child-5, Child-6, Child-7 and Child-8
  -->

</div>

When you click one of the buttons, it sets display: none on the active group - and removes display: none from the child-group that needs to become visible.

I'm trying to write a test, that first activates a certain child-group (by clicking the the button to make it visible) and afterwards checks the content is correct.

But when I do this:

cy.get( ".child-group .buttons .go-to-child-group-2" ).click();

Then my test fails with this error:

cy.click() can only be called on a single element. Your subject contained 8 elements. Pass { multiple: true } if you want to serially click each element.

It's obviously crap, that all the buttons are loaded on each element. But we can't change that until further down the line.

How do I select only the .child-group that doesn't have display: none set on it?


Solution attempt 1: Select by style

I found this post on how to select by style. But since I'm trying to select the one without the style, that makes this more difficult.

I tried this:

cy.get( ".child-group[style*='display: block'] .buttons .go-to-child-group-2" ).click();

But that doesn't work. And when I inspect the element without the display: none, then I can find no display-style on it. And I could also read that display didn't have any default value.


Solution attempt 2: Make cy.get(...) disregard all non-visible elements.

I found a bit about Interacting with Elements, but it didn't tell me how I could pass that option the my cy.get-function.

I also checked the documentation for cy.get, but couldn't find anything either.


Solution attempt 3: Simply click all the buttons (poor)

I could do what it says and click all the buttons, by calling the click-function like this:

cy.get( ".child-group .buttons .go-to-child-group-2" ).click( {multiple: true, force: true});

This works, but I was hoping for a better solution.



Solution 1:[1]

I think you're looking for the :not() pseudo selector

cy.get('.child-group .buttons .go-to-child-group-2:not([style="display: none"])')

I guess it's also worth trying this, but not sure if the empty string will throw it

cy.get('.child-group .buttons .go-to-child-group-2[style=""]')

Solution 2:[2]

Alternatively, you can use the :visible selector.

cy.get('.child-group .buttons .go-to-child-group-2')
  .filter(':visible') // filter only visible elements

Here is a simple example

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 jjhelguero