Search code examples
automated-testscucumbercapybaraaws-amplifyshadow-dom

Is there an easy way to traverse nested Shadow DOM when testing with Cucumber, Selenium & Capybara?


I am attempting to write automation tests for the front-end UI of an app , that has a lot of nested shadow-doms and I am unable to access them using the Capybara, Cucumber & Selenium (using chromedriver). The app is using AWS Amplify Authenticator . I keep getting the following error when I try to find an input element :

Unable to find css "input[id$='username']" (Capybara::ElementNotFound)

This is what my test looks like:

When('I type into the username field my {string}') do |string| find("input[id$='username']").set(string) end

I have read on other posts that chrome driver supports shadow-doms but not sure how it would be handled in this scenario


Solution

  • Currently you need to use evaluate_script to get access to the shadow-dom - like

    element = find(...) # find element that contains shadow dom
    shadow_root = @session.evaluate_script(<<~JS, element)
            (function(root){
              return root.shadowRoot;
            })(arguments[0])
          JS
    shadow_root.find("input[id$='username']")
    

    and then you can only use CSS based finders/actions/etc on the shadow DOM.

    The WebDriver spec has been updated to bring more support for the shadow dom but it's not implemented in drivers yet - https://w3c.github.io/webdriver/#shadow-root