Search This Blog

Breaking

Wednesday, 22 December 2021

How to access shadow dom [Open] element in selenium?

Recently, I saw in stack overflow that many people were posting question that they are not able to get element which is inside a shadow DOM. So I tried to solve this problem. Below is my learning:


1. If the element is inside the shadow root, first check that is that shadow root is open or close. If it is Open, than you can directly access it by using java script executor.

2. If the element is inside the shadow root which is closed, you can not use it. If you need to interact with such element, you can use keyboard key press operations.


So the first application which I got was an application where the shadow root was open. So it became easy for me. My take here is, first check your locator in developer console. I will explain how we can do it.


So lets first open a page  where this issue occurs . And the easy to accessible page is your chrome download page. If you will inspect "Search Downloads"  element on that page, you will find that it is inside shadow root.












So if we try to find element by using xpath, the xpath value is : '//*[@id="searchInput"]

But if you will try to search this XPATH, you will find it is not highlighting the element. And if you use it in your code, then you will see below error:









So the reason for it's not working is not that your xpath is not correct, it's just that this element is present inside shadow root element.

And if any element is present inside shadow root [Open], you can not access it with normal locator strategies. 

So to access this element, you will have to first find css locator for the topmost element from where the shadow root starts. In this page, it is from the beginning. So just find the locator of the element which is before the shadow root.












Here it is : body > downloads-manager

Now, you will move to find the second shadow root and you need to find the locator of element before that element.

Here it is: #toolbar


















Similar way, when we reach to the input field, we see 2 more shadow root. When we find the css locator of elements before that shadow root, it's like:

Third element : #toolbar
Fourth element: #search

And then at the end, our element appears and it's css locator is : #search

So now, we have all the locators, let's test these locators in browsers console page.

So to execute the CSS locator in browser console page, we use below method:

document.querySelector()

So now we will give our first locator to this:

document.querySelector('body > downloads-manager')

After this, we have our first shadow root. So to navigate inside the shadow root, we use below method:
shadowRoot.querySelector()

So now our locator will become:

document.querySelector('body > downloads-manager').shadowRoot.querySelector('#toolbar')

Similarly, we will have to add all our shadow root locator.

The final output will be like:

document.querySelector('body > downloads-manager').shadowRoot.querySelector('#toolbar').shadowRoot.querySelector('#toolbar').shadowRoot.querySelector('#search').shadowRoot.querySelector('#searchInput')


Now when you will hit this element in your developer console, you will see it is highlighting the element.









Now this, entire locator, we will have to use in our selenium code. (Python)

driver.get('chrome://downloads/')
driver.maximize_window()

# Using java script executor

searchDownload = driver.execute_script("return document.querySelector('body > downloads-manager').shadowRoot.querySelector('#toolbar').shadowRoot.querySelector('#toolbar').shadowRoot.querySelector('#search').shadowRoot.querySelector('#searchInput')")

searchDownload.send_keys("Order_ID_2363900762.pdf")
sleep(10)
driver.quit()

And when you will run this code, it will enter your text inside the field.













So this is how you can enter text inside a shadow root element.

No comments:

Post a Comment