How Functionize lets you test Shadow DOMs

Shadow DOMs are getting common, but are hard to test


With Functionize you can now test them transparently

Shadow DOMs are used to embed widgets and 3rd party content in your site. They are impossible to test with tools like Selenium because they are invisible to JavaScript. Functionize’s system allows you to test these transparently as if they were any other element in your application.

What is a shadow DOM, and why use one?

In a normal DOM, JavaScript can access every element (e..g text box, image, button). Shadow DOMs are used when you want to embed functionality that can’t be interacted with by JavaScript. For instance, you may have a recording widget you want to embed, but this shouldn’t be accessible to JavaScript. They are also used when you embed content from 3rd parties within your website (widgets, etc.). In some cases you may also choose to use them to conceal content from web crawlers and search bots. Originally, shadow DOMs were a relatively rare beast. But increasingly, we see clients coming to us who have used them in their websites.

Twitter widget configuration

Twitter allows you to embed a Twitter feed as a widget

Testing Shadow DOMs

Why are they hard to test?

Shadow DOMs are hidden from JavaScript, so test frameworks like Selenium just see them as a single element/selector. This makes recording or creating tests impossible.

Shadow DOMs are hard to test because test automation frameworks like Selenium use JavaScript to access and manipulate page elements. By definition, elements within shadow DOMs are hidden from JavaScript. So it’s easy to see that makes them hard to test! Effectively to most test recorders, a widget or other shadow DOM element looks like a single selector. You can tell if it’s been clicked or not, but you have no idea what was actually being clicked inside the DOM.

Why do you need to test shadow DOMs?

Shadow DOMs are becoming increasingly common within websites and web applications. So, if you can’t test them, you are unable to test whole swathes of functionality in your site. Clearly, this is suboptimal to say the least! As a result, here at Functionize we saw a slew of customer requests to add this functionality. And, as you know, we always try to solve any such problems our customers have.

How does Functionize’s solution work?

When we began to look at solving this issue we quickly found out why this is a hard problem. Put simply, shadow DOMs are invisible to most test frameworks. If you can’t see it, you can’t test it. Testing is a two stage process. First you have to create the test, then you need to be able to replay it. So, first we had to come up with a way to locate the shadow DOM. Then we had to drill down through it and find the enclosed elements.  Finally, having added those to the test we needed to be able to access them again when replaying the test.

Our solution is able to find and access shadow DOMs because it is able to access all elements on the page, not just those that are “visible” to JavaScript. This means that you can create tests exactly as if the shadow DOM wasn’t there. Say your page has an embedded video player widget. You can write a test plan as usual using our Adaptive Language Processing (ALP™) system. (ALP™ uses Natural Language Processing to convert a test written in plain English into a fully-functioning Functionize test).

Within your test plan you may have a couple of lines saying:

  • Locate the video player in the middle of the page.
  • Click on the play button.
  • Verify that the video begins to stream.

These will be converted into a test and when the system comes to replay the test it will simply find the player, click Play and check the result. Effectively you are just treating widgets and other shadow DOM elements like any element within your web page.

How can I try this out?

Trying this out couldn’t be simpler! Find one of your pages that includes a widget in a shadow DOM and simply write a test that interacts with it! Chances are that some of you are already doing this without even realising it!