Playwright - Interacting with Closed Shadow DOM in iFrames

profile
Mike Sell
crashnaut.com

The Problem: Closed Shadow DOM link

When testing iFrames with Playwright (which, unlike Cypress, has excellent iframe support), you may encounter a particularly tricky scenario: the closed Shadow DOM. In your browser's DevTools, it looks like this:

Example of closed shadow root in browser devtools

Notice the #shadow-root (closed) label. This is where things get interesting.

Why Shadow DOM is Closed link

The Shadow DOM provides encapsulation for web components, isolating their internal structure from the rest of the page. When a Shadow DOM is set to closed mode, it's done for security and encapsulation reasons:

While these are valid architectural decisions, they create a challenge for automated testing where you need to verify the component's internal state.

The Testing Challenge link

When you try to use Playwright to interact with elements inside a closed Shadow DOM, you'll encounter errors because Playwright cannot pierce through the closed boundary. The DOM query simply fails to find the elements you're looking for.

For most test engineers, this seems like game over. However, there's a clever workaround.

The Solution: Force Open Shadow DOM link

The key insight is that we can intercept the Shadow DOM creation at the browser level and force all Shadow DOMs to be created in open mode instead:

Example of open shadow root in browser devtools

Notice the difference: #shadow-root (open) allows Playwright to access the internal elements.

Implementation link

Here's the function that makes this possible:

This function uses Playwright's addInitScript() to inject JavaScript that runs before any page scripts load. It:

  1. Saves the original attachShadow method
  2. Overrides Element.prototype.attachShadow
  3. Intercepts all Shadow DOM creation calls
  4. Forces the mode to 'open' regardless of what the component requests
  5. Maintains all other initialization options

Usage in Tests link

Add this to your test setup to apply it to all tests:

Alternatively, for specific tests:

Important Considerations link

This approach gives you the testing capability you need while respecting that closed Shadow DOM serves legitimate purposes in production code.

Feel free to update this blog post on GitHub, thanks in advance!

Share this post

Support me

I appreciate it if you would support me if you have enjoyed this post and found it useful, thank you in advance.

Buy Me a Coffee at ko-fi.com