[py] Modularize Bazel build with per-module targets#17012
[py] Modularize Bazel build with per-module targets#17012titusfortner merged 12 commits intotrunkfrom
Conversation
User description🔗 Related IssuesFollows up on #16993 (lazy imports) Java's approach is to create a separate BUILD.bazel file for each directory. 💥 What does this PR do?Modularizes the Python Bazel build by creating separate Module targets added:
🔧 Implementation Notes
💡 Additional Considerations
🔄 Types of changes
PR TypeEnhancement Description
Diagram Walkthroughflowchart LR
exceptions["exceptions<br/>Base exceptions"]
remote["remote<br/>Wire protocol"]
bidi["bidi<br/>BiDi protocol"]
common["common<br/>Shared utilities"]
support["support<br/>Wait/listeners"]
chromium["chromium<br/>Chrome/Edge base"]
chrome["chrome<br/>Chrome driver"]
edge["edge<br/>Edge driver"]
firefox["firefox<br/>Firefox driver"]
safari["safari<br/>Safari driver"]
ie["ie<br/>IE driver"]
webkitgtk["webkitgtk<br/>WebKitGTK driver"]
wpewebkit["wpewebkit<br/>WPEWebKit driver"]
selenium["selenium<br/>Aggregate target"]
exceptions --> remote
exceptions --> bidi
exceptions --> common
exceptions --> support
remote --> common
bidi --> common
remote --> chromium
common --> chromium
chromium --> chrome
chromium --> edge
remote --> firefox
common --> firefox
remote --> safari
common --> safari
remote --> ie
common --> ie
remote --> webkitgtk
common --> webkitgtk
remote --> wpewebkit
common --> wpewebkit
exceptions --> selenium
remote --> selenium
bidi --> selenium
common --> selenium
support --> selenium
chromium --> selenium
chrome --> selenium
edge --> selenium
firefox --> selenium
safari --> selenium
ie --> selenium
webkitgtk --> selenium
wpewebkit --> selenium
|
| Relevant files | |||
|---|---|---|---|
| Enhancement |
|
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
|||||||||||||||||||||||
PR Code Suggestions ✨Latest suggestions up to 8ed92f0
Previous suggestionsSuggestions up to commit dcf479f
|
|||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
This PR modularizes the Python Bazel build by creating separate py_library targets for each module, following Ruby's modular pattern from the same monorepo. The goal is to enable users to depend on individual modules (like :chrome or :firefox) without pulling in the entire Selenium library, building on the lazy import mechanism added in PR #16993.
Changes:
- Creates 15 separate module targets:
:exceptions,:remote,:bidi,:common,:support,:chromium, and individual browser drivers (:chrome,:edge,:firefox,:safari,:ie,:webkitgtk,:wpewebkit) - Preserves the aggregate
:seleniumtarget for backwards compatibility - Updates test targets to depend on specific modules instead of the full aggregate
Add separate py_library targets for each module following Ruby's pattern: - exceptions: Base exception classes - remote: Wire protocol and WebDriver commands - bidi: BiDi protocol support - common: Shared utilities, actions, selenium-manager, devtools - support: Wait conditions, event listeners - chromium: Base for Chrome/Edge - chrome, edge, firefox, safari, ie, webkitgtk, wpewebkit: Browser drivers The aggregate :selenium target is preserved for backwards compatibility, depending on all module targets. This enables: - Faster incremental builds when editing a single module - Clear dependency graph between modules - Future ability for users to depend on subsets (with lazy imports) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update browser test targets to depend on specific modules instead of the aggregate :selenium target: - test-chrome → :chrome, :common, :support - test-firefox → :firefox, :common, :support - test-edge → :edge, :common, :support - etc. This enables faster incremental test builds when only one module is modified. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add missing deps identified in PR review: - :bidi needs :remote (imports websocket_connection) - :support needs :common (imports by, alert) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move selenium/__init__.py and selenium/webdriver/__init__.py to the :exceptions module so lazy imports (e.g., webdriver.ChromeOptions) work when depending on individual modules like :chrome instead of :selenium. This fixes integration test failures where tests use lazy import syntax. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes mypy error about incompatible types in assignment when handler is assigned different RemoteConnection subclasses. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move remote_firefox_profile_tests.py to firefox/ folder since it's Firefox-specific - Change remote_hub_connection.py to use ArgOptions instead of Firefox Options since the test is about SSL cert verification, not Firefox Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1283d8c to
6bca6e5
Compare
cgoldberg
left a comment
There was a problem hiding this comment.
Can you rename remote_hub_connection.py so it ends with _tests (remote_hub_connection_tests.py)? Otherwise, pytest won't find it when you run locally. It filters on ["test_*.py", "*_test.py", "*_tests.py"].
|
I think CI is failing because |
|
Generally speaking:
Based on that, a test about firefox profiles belongs in firefox directory, and if the test only applies when remote and not local, we need to generate targets based on that. |
Move remote_firefox_profile_tests.py back to remote/ folder where it belongs - it needs the server fixture which only exists in remote mode. Exclude it from chrome-remote tests since it's Firefox-specific. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The way the test is written in To support both, I think we can change the test to: ... and it will work with remote or local Firefox. If we make it worth both ways, the file should be renamed from We could also refactor the There are also some tests inside |
Use the Driver class from conftest to handle both local and remote execution. The test now works with both --remote flag and without it. Move test from remote/ to firefox/ folder since it's testing a Firefox-specific feature (profiles), not a remote-only feature. Rename from remote_firefox_profile_tests.py to firefox_profile_tests.py. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🔗 Related Issues
Follows up on #16993 (lazy imports)
Java's approach is to create a separate BUILD.bazel file for each directory.
Ruby defines everything from one file, and that's the one this copies.
💥 What does this PR do?
Modularizes the Python Bazel build by creating separate
py_librarytargets for each moduleModule targets added:
:exceptions- Base exception classes:remote- Wire protocol and WebDriver commands:bidi- BiDi protocol support:common- Shared utilities, actions, selenium-manager, devtools:support- Wait conditions, event listeners:chromium- Base for Chrome/Edge:chrome,:edge,:firefox,:safari,:ie,:webkitgtk,:wpewebkit- Browser drivers🔧 Implementation Notes
:seleniumtarget is preserved for backwards compatibility:seleniumaggregateimports = ["."]for proper Python path resolution:commonvia data attribute (same as before)💡 Additional Considerations
🔄 Types of changes