2

I'm trying to use selenium to automate some actions but am unable to find the first element on the page https://developer.servicenow.com/dev.do and so cannot login

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver_path = "../bin/chromedriver.exe"
driver = webdriver.Chrome(driver_path)

driver.get("https://developer.servicenow.com/dev.do")

driver.find_element_by_xpath("/html/body/dps-app//div/header/dps-navigation-header//header/div/div[2]/ul/li[3]/dps-login//div/dps-button//button/span")

I get the error

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/dps-app//div/header/dps-navigation-header//header/div/div[2]/ul/li[3]/dps-login//div/dps-button//button/span"}
undetected Selenium
  • 151,581
  • 34
  • 225
  • 281

4 Answers4

2

To Sign In button is deep within multiple #shadow-root (open)

shadow-root-open-multiple


Solution

Tto click() on the desired element you can use shadowRoot.querySelector() and you can use the following Locator Strategy:

from selenium import webdriver

options = webdriver.ChromeOptions() 
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
driver.get('https://developer.servicenow.com/dev.do')
SignInButton = driver.execute_script("return document.querySelector('dps-app').shadowRoot.querySelector('dps-navigation-header').shadowRoot.querySelector('header.dps-navigation-header dps-login').shadowRoot.querySelector('dps-button')")
SignInButton.click()
        
  • Browser Snapshot:

shadow-root-open


References

You can find a couple of relevant detailed discussions in:

undetected Selenium
  • 151,581
  • 34
  • 225
  • 281
0

You could look at the Automatepro app on the servicenow store. It uses selenium but they have pre-written the selenium behind the scenes to interact with all the servicenow UI components, including those using shadow DOM. You just pick the UI element and supply the data for your test. We found it saves a lot of time writing and maintaining the selenium code ourselves..

Paul
  • 3
  • 1
0

This solution was what I was looking for to log into my instance using Powershell.

driver.executescript("return document.querySelector('dps-app').shadowRoot.querySelector('dps-navigation-header').shadowRoot.querySelector('header.dps-navigation-header dps-login').shadowRoot.querySelector('dps-button')").Click()
Pjotr
  • 1
-1

I think its because you are trying to access the "Sign in" before the website has time to load all of the elements.

I suggest you use

driver.set_page_load_timeout(120)

so the selenium will look for the button after everything is loaded on the website.