python/selenium: how to access button element in a slot under the shadow-root (shadow DOM)?

171 views Asked by At

I am new to the shadow DOM and I hope I can get help here. Many Thanks!

the link is: wertpapiere.ing.de/ Problem is from clicking the button to accept cookie.

enter image description here

code until locate the shadow-root of this button:

baseurl='https://wertpapiere.ing.de'
driver = webdriver.Chrome()
driver.get(baseurl)
locB = driver.find_element(By.XPATH, "//*[starts-with(@id, 'dialogContent')]")
shadowrootB = driver.execute_script("return arguments[0].shadowRoot", locB)
locC=shadowrootB.find_element(By.CSS_SELECTOR,'ing-cc-button-6610.cc-l0__button__accept') #ok
shadowrootC = driver.execute_script("return arguments[0].shadowRoot", locC) #ok

under this shadow root, the slot can be located: b=shadowrootC.find_element('id','button-btg1c3gu3c') #OK

<!----> <slot name="icon-before"></slot> <div class="button-content" id="button-btg1c3gu3c"><slot></slot></div> <slot name="icon-after"></slot> <slot name="_button"></slot> <!----> <button tabindex="-1" aria-hidden="true" slot="_button" type="submit"></button>

for the button, copy from the chrome:

 css:

ing-cc-button-6610.cc-l0__button__accept > button

xpath:

//*[@id="dialogContent-sjk4n7c2qu"]//ing-cc-button-6610[1]/button

bt=shadowrootC.find_element('xpath','//*[@id="dialogContent-sjk4n7c2qu"]//ing-cc-button-6610[1]/button') #NOK
bt=shadowrootC.find_element(By.CSS_SELECTOR,'ing-cc-button-6610.cc-l0__button__accept > button') #NOK
bt=shadowrootC.find_element(By.TAG_NAME, 'button') #NOK

then I see above this shadow-root there is another parallel shadow-root at the same level which has <div> of iframe. Is there any relation of here?

enter image description here

How to access this button using click() ? furthermore any explanation on shadow-root/iframe and shadow-root/slot/button may help to better understand

1

There are 1 answers

3
Yaroslavm On

You don't need to go to 2nd level shadow-root, first one is enough.

Just wait for consent modal presence, go inside 1st level shadow-root (like you did, that's fine) and then click on element with locator [type=button] which is root locator of button container.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions

baseurl = 'https://wertpapiere.ing.de'
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
driver.get(baseurl)
locB = wait.until(expected_conditions.presence_of_element_located((By.XPATH, "//*[starts-with(@id, 'dialogContent')]")))
shadowrootB = driver.execute_script("return arguments[0].shadowRoot", locB)
locC = shadowrootB.find_element(By.CSS_SELECTOR, '[type=submit]').click()
wait.until(expected_conditions.staleness_of(locB))