2

I want to access/automate an element of nested shadow DOM. Ley's say for the given link https://books-pwakit.appspot.com/ I want to search some books by sending some book name. I am trying like this according to my learnt knowledge but it is not locating the element. My code is like this...

url = "https://books-pwakit.appspot.com/"
driver.get(url)

shadow_host1 = driver.find_element(By.CSS_SELECTOR, "book-app[apptitle='BOOKS']")
shadow_root1 = driver.execute_script('return arguments[0].shadowRoot', shadow_host1)

shadow_host2 = driver.find_element(By.CSS_SELECTOR, "app-header[effects='waterfall']")
shadow_root2 = driver.execute_script('return arguments[0].shadowRoot', shadow_host2)

shadow_host3 = driver.find_element(By.CSS_SELECTOR, '.toolbar-top')
shadow_root3 = driver.execute_script('return arguments[0].shadowRoot', shadow_host3)

shadow_host4 = driver.find_element(By.CSS_SELECTOR, '.toolbar-bottom')
shadow_root4 = driver.execute_script('return arguments[0].shadowRoot', shadow_host4)

shadow_host5 = driver.find_element(By.CSS_SELECTOR, 'book-input-decorator')
shadow_root5 = driver.execute_script('return arguments[0].shadowRoot', shadow_host5)

shadow_content = shadow_root5.find_element(By.CSS_SELECTOR, '#input')

shadow_content.send_keys("Twilight")   

Can anyone help me please and describe me why I am getting that error.

1 Answer 1

3

In order to get the inner shadow_hosts you need to apply the find_element() method on outer shadow_host element, not on the global driver object.
The following code works:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

options = Options()
options.add_argument("start-maximized")

webdriver_service = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(options=options, service=webdriver_service)
wait = WebDriverWait(driver, 30)

url = "https://books-pwakit.appspot.com/"
driver.get(url)

shadow_host1 = driver.find_element(By.CSS_SELECTOR, "book-app[apptitle='BOOKS']")
shadow_root1 = driver.execute_script('return arguments[0].shadowRoot', shadow_host1)

shadow_host2 = shadow_root1.find_element(By.CSS_SELECTOR, "app-header[effects='waterfall']")
shadow_root2 = driver.execute_script('return arguments[0].shadowRoot', shadow_host2)

shadow_host3 = shadow_root1.find_element(By.CSS_SELECTOR, '.toolbar-top')
shadow_root3 = driver.execute_script('return arguments[0].shadowRoot', shadow_host3)

shadow_host4 = shadow_root1.find_element(By.CSS_SELECTOR, '.toolbar-bottom')
shadow_root4 = driver.execute_script('return arguments[0].shadowRoot', shadow_host4)

shadow_host5 = shadow_root1.find_element(By.CSS_SELECTOR, 'book-input-decorator')
shadow_root5 = driver.execute_script('return arguments[0].shadowRoot', shadow_host5)

shadow_content = shadow_host5.find_element(By.CSS_SELECTOR, '#input')
shadow_content.send_keys("Twilight")

This is the result:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

It's my pleasure to help when I can ☺️

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.