Zakaria Shahed
Zakaria Shahed

Reputation: 2707

Access elements inside the shadow-root

Is it possible to find elements of the Shadow DOM with java and selenium?

I want to take element from shadow root

<paper-input id="homeSearch" class="home-search-btn home-inputs" placeholder="Where would you like to go?" no-label-float="" tabindex="0" aria-disabled="false"><iron-icon icon="-search-" slot="prefix" class="form-icons search-icon"></iron-icon></paper-input>

I want to send A Input on homesearch Like driver.findElement(By.id("homesearch")); I search on internet but not get any appropiate solution.

enter image description here

Any type of help will really appreciated

Upvotes: 5

Views: 6522

Answers (1)

Marcel
Marcel

Reputation: 1463

Getting elements inside a shadow dom root takes several steps.

First, get the 'host' element, in your case the input with attribute page = "home"

WebElement host1 = driver.findElement(By.cssSelector("vrs-app[page='home']"));

After that, you need to execute a JavaScript script to get the shadow root from the host, you can get the shadow root by calling .shadowRoot on a web element.

WebElement shadowRoot = (WebElement)((JavascriptExecutor) driver).executeScript("return arguments[0].shadowRoot", host);

But there is one catch, your input is nested inside several shadow doms, so you have to do this a couple of times. Most efficient way to do this, is to use a method, for example:

public WebElement GetShadowRoot(WebElement host) {
    WebElement shadowRoot = (WebElement)((JavascriptExecutor) driver).executeScript("return arguments[0].shadowRoot", host);
    return shadowRoot ;
}

After that, dive down all the shadow roots until you reach the host you need, like this:

WebElement host1 = driver.FindElement(By.cssSelector("vrs-app[page='home']"));
WebElement shadow1 = GetShadowRoot(host1);

WebElement host2 = shadow1.FindElement(By.cssSelector("vrs-home"));
WebElement shadow2 = GetShadowRoot(host2);

// We've reached the shadow dom containing the input
// Note: I'm not using By.id since this may throw an error
WebElement paperInput = shadow2.findElement(By.cssSelector("paper-input[id='homeSearch']"));

Now you can do what you want to do with paperInput.

Side note: I know this method works in Chrome (just tested it), have not tested it in other browsers. Also, I don't know Java so language syntax might be a bit different.

Upvotes: 2

Related Questions