Repository navigation
Conversation
find_element/find_elements on a WebElement or ShadowRoot sent the RelativeBy object straight to the find-child commands, which failed with "Object of type RelativeBy is not JSON serializable". Run the findElements atom with the element or shadow root as its root instead, matching the Java binding. Fixes SeleniumHQ#13634
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
Thank you, @gjreddy for this code suggestion. The support packages contain example code that many users find helpful, but they do not necessarily represent After reviewing the change, unless it is a critical fix or a feature that is needed for Selenium We actively encourage people to add the wrapper and helper code that makes sense for them to their own frameworks. |
There was a problem hiding this comment.
Instead of introducing a function-local import, I think you can adjust existing imports to prevent the circular import:
-
py/selenium/webdriver/support/relative_locator.py- Add
from __future__ import annotations. - Move the
WebElementimport underif TYPE_CHECKING:to avoid the runtime dependency.
- Add
-
py/selenium/webdriver/remote/webelement.py- Move the
RelativeByimport fromTYPE_CHECKINGto module level. - Remove the function-local import from
find_element().
- Move the
This eliminates the circular import while preserving the runtime isinstance() check.
relative_locator only needs WebElement for annotations, so import it under TYPE_CHECKING. That removes the circular import, and webelement and shadowroot can import RelativeBy at module level.
|
Thanks @cgoldberg, that's cleaner. Done in 3ea7027:
Each of |
🔗 Related Issues
Fixes #13634
Python follow-up to #17907, which made the findElements atom accept a
ShadowRootas its root and added this for Java.💥 What does this PR do?
Relative locators now work from a
WebElementand from aShadowRootin the Python binding, and the search stays inside that element or shadow root:Before, both calls passed the
RelativeByobject to the find-child commands and failed withTypeError: Object of type RelativeBy is not JSON serializable. The only workaround was a document-wide search from the driver, which cannot see inside a shadow root.🔧 Implementation Notes
WebDriver._find_elements_relative(by, root=None). The driver passes no root, so its behaviour does not change.WebElementandShadowRootcall the helper with themselves as the root. The atom receives the element or shadow root reference as its second argument, the same way the Java binding does it.find_elementwith a relative locator returns the first match, or raisesNoSuchElementException, the same asWebDriver.find_element.RelativeByis imported inside the methods:relative_locatorimportswebelement, so a module-level import would be circular.🧪 Tests
New tests in
relative_by_tests.py, mirroring the Java tests from #17907:test_should_only_search_within_the_context_elementtest_should_find_first_relative_element_within_the_context_elementtest_should_only_search_within_the_shadow_roottest_should_find_relative_element_in_shadow_root_by_anchor_locatorResults in Chrome (headless):
Object of type RelativeBy is not JSON serializable.I ran them locally with pytest, against the 4.51.0 package with this patch applied, rather than with Bazel: building the generated BiDi modules was not possible in my environment.
ruff formatandruff checkpass on the changed files.🤖 AI assistance
💡 Additional Considerations
Other bindings: Java has this since #17907. I have not checked Ruby, .NET or JavaScript.
🔄 Types of changes