You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
By clicking “Sign up for GitHub”, you agree to our
terms of service
and
privacy statement
. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
What happened?
If you use any other By type than CSS_SELECTOR with a find_element on a shadow root object you get an Invalid Locator error. It seems the tests only test this function with By.CSS_SELECTOR so unsure if this is intentional.
Also the find_element on the ShadowRoot object has a different signature to all other find_element functions (it uses
using
rather than
by
), this makes it annoying if you are trying to call find_element with keyword arguments, as the keyword arguments might be different if you happen to be on a shadow root element.
The other find_element functions do a conversion of the different By types into equivalent By.CSS_SELECTORs so i am wondering if this is missing from the shadow root?
How can we reproduce the issue?
Change this test:
@pytest.mark.xfail_safari
def test_can_find_element_in_a_shadowroot(driver, pages):
pages.load("webComponents.html")
custom_element = driver.find_element(By.CSS_SELECTOR, "custom-checkbox-element")
shadow_root = custom_element.shadow_root
element = shadow_root.find_element(By.CSS_SELECTOR, "input")
assert isinstance(element, WebElement)
To access the element within the shadow_root by tag name instead.
@pytest.mark.xfail_safari
def test_can_find_element_in_a_shadowroot(driver, pages):
pages.load("webComponents.html")
custom_element = driver.find_element(By.CSS_SELECTOR, "custom-checkbox-element")
shadow_root = custom_element.shadow_root
element = shadow_root.find_element(By.TAG_NAME, "input")
assert isinstance(element, WebElement)
Relevant log output
return shadow_root.find_element(By.TAG_NAME, 'upload-button')
File "python3.8/site-packages/selenium/webdriver/remote/shadowroot.py", line 45, in find_element
return self._execute(Command.FIND_ELEMENT_FROM_SHADOW_ROOT, {"using": using, "value": value})['value']
File "python3.8/site-packages/selenium/webdriver/remote/shadowroot.py", line 64, in _execute
return self.session.execute(command, params)
File "python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 424, in execute
self.error_handler.check_response(response)
File "python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 247, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: invalid locator
(Session info: headless chrome=96.0.4664.45)
Operating System
Ubuntu
Selenium version
Python Selenium 4.1.0
What are the browser(s) and version(s) where you see this issue?
Chrome Version '96.0.4664.45'
What are the browser driver(s) and version(s) where you see this issue?
ChromeDriver 96.0.4664.45
Are you using Selenium Grid?
No response
@NickScottKortical, thank you for creating this issue. We will troubleshoot it as soon as we can.
Info for maintainers
Triage this issue by using labels.
If information is missing, add a helpful comment and then
I-issue-template
label.
If the issue is a question, add the
I-question
label.
If the issue is valid but there is no time to troubleshoot it, consider adding the
help wanted
label.
If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, W3C),
add the applicable
G-*
label, and it will provide the correct link and auto-close the
issue.
After troubleshooting the issue, please add the
R-awaiting answer
label.
Thank you!
@diemol
Wouldn't it be nice to do what the other find_element functions already do and translate the different By locators into By.CSS_SELECTOR versions? I'm not sure why shadow root is a special case e.g. this block is run when using find_element on a regular element:
if by == By.ID:
by = By.CSS_SELECTOR
value = '[id="%s"]' % value
elif by == By.TAG_NAME:
by = By.CSS_SELECTOR
elif by == By.CLASS_NAME:
by = By.CSS_SELECTOR
value = ".%s" % value
elif by == By.NAME:
by = By.CSS_SELECTOR
value = '[name="%s"]' % value
and its quite annoying to have to run that before any find_element that is running against a shadow root object.