Selenium is a Bazel-built monorepo implementing the W3C WebDriver (and related) protocols, shipping multiple language bindings plus Grid and Selenium Manager. The repository README is aimed at contributors; end-user docs live elsewhere.
- The
.local/directory is available for customization, generated artifacts, scratch work, and temporary files. It is ignored by Git except for.local/README.md. - A contributor may create
.local/AGENTS.mdfor personal repo-specific instructions and preferences. Before beginning any task, check whether.local/AGENTS.mdexists; if it exists, read it with your file-reading tool and apply it as the contributor's local instruction overlay. - If
.local/agent/skills/exists, inspect its*/SKILL.mdfiles and treat them as additional user-defined skills.
- Maintain API/ABI compatibility - users upgrade by changing only version number
- Avoid repo-wide refactors/formatting; prefer small, reversible diffs
- The project uses Bazelisk with a hermetic Bazel toolset. Do not run tests or execute Selenium code assuming a language-specific local development environment is configured.
- Rakefile tasks are executed with a bundled jruby wrapped with
go/go.batand frequently used by CI jobs - Prefer targeted Bazel commands; use
bazel query ...to locate labels before build/test
- Use
bazel queryto explore build graph before reading files - Attempt to execute Bazel commands directly. If prevented due to network/toolchain restrictions within the sandbox, fall back to suggesting copy/paste commands for the user on a separate line.
- When the default output directory is restricted or when working in a git worktree, isolate build output with
--output_base. It is a startup flag, so it goes before the command, and anchor it to the worktree root so it resolves the same from any directory:bazel --output_base="$(git rev-parse --show-toplevel)/.local/output-base" build //...(not afterbuild/test/query).
Bindings (see AGENTS.md in each directory for language-specific details):
- Java:
java/ - Python:
py/ - Ruby:
rb/ - JavaScript:
javascript/selenium-webdriver/ - .NET:
dotnet/
Shared/high-risk areas:
rust/(Selenium Manager, seerust/AGENTS.md)common/(build/test wiring; affects multiple areas)common/src/(test HTML fixtures)javascript/atoms/(shared JS atoms; high blast radius)scripts/,rake_tasks/,.github/,Rakefile(tooling/build)third_party/treat as read-onlybazel-*/treat as generated output
When changing user-visible behavior, compare with at least one other binding:
- Example:
rg <term> java/ py/ rb/ dotnet/ javascript/selenium-webdriver/
If behavior is shared/low-level (protocol, serialization, "remote"/transport), suggest follow-up parity work or to file an issue
When implementing solutions prefer writing a test for it first Prefer small (unit) tests over browser tests for speed/reliability Avoid mocks—they can misrepresent API contracts
Useful flags:
--test_size_filters=small(unit tests only)--test_output=all(display console output)--cache_test_results=no(force re-run) See language-specific AGENTS.md for applicable testing usage
Add logging where users may need insight into what's happening See language-specific AGENTS.md for applicable logging usage
This project does not follow semantic versioning (semver); before removing public functionality, mark it as deprecated with a message pointing to the alternative. See language-specific AGENTS.md for applicable deprecation usage
- Comments should explain why, not what - prefer well-named methods over comments
- PRs should focus on one thing; we squash PRs to default
trunkbranch - Prefer copying files to deleting and recreating to maintain git history
- Avoid running
bazel clean --expunge - Formatting:
./scripts/format.shwithout arguments will run everything similar to running./go formatbut with failure information; With--pre-commitflag it only checks staged changes; With--pre-pushflag it only checks committed changes with trunk.- If
./scripts/format.shis already referenced in a pre-commit or pre-push hook, let the hooks handle formatting - If not, run or suggest
./scripts/format.sh --pre-pushbefore pushing to avoid CI formatter failures
- Everything referenced above as high risk
- WebDriver/BiDi semantics, capability parsing, wire-level behavior
- Dependency updates /
MODULE.bazel/ repin flows - Grid routing/distributor/queue logic
- Call out any high risk areas touched
- Note cross-binding impact and any follow-up issues needed
See .github/pr_review.md for agentic review priorities and scope.