Cypress - How to iterate over elements and filter out ones which have a shadow dom?
Asked Answered
T

1

0

I have a page with many elements, five of which are div elements with zero attributes. Each of those five divs have a shadow root/shadow dom. I am interested in only one of the five divs which has an element with specific text. I am unable to find and filter out the correct div. How do I do that ? I have some code which works only when I have one such div instead of five.

cy.get("div").find(
   'div.items span:contains("7")',
   {
     includeShadowDom: true,
   }
).click();
Trampoline answered 19/9, 2023 at 2:1 Comment(1)
Why are you not able to find it? That code looks like it should work. I think we need the HTML because I could construct something from your description and the test would pass.Stress
S
4

I think you might be specifying the div#shadowroot twice - once in the get and once in the find.

If I construct a similar page using Cypress' <cy-test-element> which has shadowDOM children, I can find span:contains("7") without problem.

Test page with five shadow elements

<body>
  <cy-test-element content="1"></cy-test-element>
  <cy-test-element content="3"></cy-test-element>
  <cy-test-element content="5"></cy-test-element>
  <cy-test-element content="7"></cy-test-element>
  <cy-test-element content="9"></cy-test-element>
  
  <script type="text/javascript">
    if (window.customElements) {
      window.customElements.define('cy-test-element', class extends HTMLElement {
        constructor () {
          super()

          const root = this.attachShadow({ mode: 'open' })
          const content = this.getAttribute('content') || 'Shadow Content'
          const className = this.hasAttribute('innerClass') ? this.getAttribute('innerClass') : 'shadow-content'
          const rootAddition = this.hasAttribute('rootAddition') ? this.getAttribute('rootAddition') : 'shadow-content'

          root.innerHTML = `<div class="shadow-div"><span class="${className}">${content}</span><input /><slot></slot></div>${rootAddition}`
        }
      })
    }

    if (window.location.search.includes('wrap-qsa')) {
      const realQuerySelectorAll = document.querySelectorAll;
      document.querySelectorAll = function (...args) {
        return realQuerySelectorAll.apply(document, args);
      };
    }
  </script>

</body>

DOM of live page

<cy-test-element innerclass="7" content="7">
  #shadow-root
  <div class="shadow-div">
    <span class="7">7</span>
    <input>
    <slot></slot>
  </div>
</cy-test-element>

Test

cy.get('cy-test-element')
  .find('span:contains("7")', {includeShadowDom:true})  // passes
Salic answered 19/9, 2023 at 4:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.