添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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.