1

As I don't have experience in handling shadow-root element, I am unable to click on this button called "Choose File"

I'm trying to click on "Choose File" button under shadow-root (user-agent) element, can I get help with the code.

Html Code below::

<input class="webbrowse" id="web263">
  #shadow-root (user-agent)
    <input type="button" value="Choose File">
      #shadow-root (user-agent)
        "Choose File"
      </input>
      <span aria-hidden="true">No file chosen</span>
</input>

Thank you all i really appreciate it.

Ankur Saxena
  • 177
  • 1
  • 11
AR Rahman
  • 23
  • 7

3 Answers3

0

make use of JavascriptExecutor

WebElement element = (WebElement) ((JavascriptExecutor)driver).executeScript("return arguments[0].shadowRoot", driver.findElement(By.xpath("//input[value = 'Choose File']")));
element.sendKeys("some keys");
cruisepandey
  • 28,520
  • 6
  • 20
  • 38
0

you have to access the parent node (<input class="webbrowse" id="web263">) and then you can locate your input:

WebElement element = (WebElement) ((JavascriptExecutor)driver).executeScript("return document.querySelector('.webbrowse').shadowRoot.querySelector('input[value=\"Choose File\"]');");

element.click();
doris
  • 36
  • 2
0

I had a very similar problem and could not find a solution with JavascriptExecutor

I tried this method and it never worked. Locator is not a problem.

elem = driver.execute_script('return document.querySelector(".clr-form-control .clr-input").shadowRoot.querySelector("#picker")')
elem.click()

Solution

I'm using Python, but the idea is the same. The solution is based on my case.

What I see in Chrome:

enter image description here

What Selenium Chromium-browser sees:

enter image description here

As you can see that Selenium is not capable to define and consequently click an element in #shadow-root (user-agent) It can only get a text from there. Check this answer to see how Finding shadow DOM text with Selenium and CSS

However, you can click your element, that's located in #shadow-root (user-agent) with ActionChains

This is the example of my code:

expire_field = driver.find_element(By.CSS_SELECTOR, ".clr-form-control .clr-input")
actions = ActionChains(driver)
actions.move_to_element(expire_field)
time.sleep(1)
actions.move_by_offset(73, 0)
time.sleep(1)
actions.click().perform()

A few things to note from it:

  • The field size with icon I want to click is 18024 px. Icon size is 1717 px. Thus to calculate x offset I used:

  • 180/2 = 90 (the center of the whole input)

  • 90-17 = 73 to calculate the x location of the calendar icon. (note that this amount can be a little different depending on a case)

  • It's almost not possible to avoid a small time.sleep (at least for this case). Otherwise, there won't be enough time to move mouse cursor. Sleep can be less than 1 second. This is just for example.

This approach always works for me, but I agree, that it's not as stable as using traditional approaches. Read about move_by_offset in detail here.

vitaliis
  • 4,082
  • 5
  • 18
  • 40