{"owner":"SeleniumHQ","repo":"selenium","hasSkills":true,"totalSkillsCount":13,"totalTokensCount":5511,"categories":["root-instruction","copilot-instructions","plugin-manifest","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","java/AGENTS.md",".github/copilot-instructions.md","py/AGENTS.md","rb/AGENTS.md","common/devtools/README.md","rust/AGENTS.md","common/extensions/webextensions-selenium-example/manifest.json","common/extensions/webextensions-selenium-example-signed/manifest.json","dotnet/src/webdriver/DevTools/README.md","dotnet/AGENTS.md","rb/lib/selenium/devtools/README.md","java/src/org/openqa/selenium/devtools/README.md"],"skills":{"AGENTS.md":"<!--\nGuidance for AI agents working in the Selenium monorepo.\nLanguage-specific details live in respective subdirectories.\n-->\n## Overview\n\nSelenium is a Bazel-built monorepo implementing the W3C WebDriver (and related) protocols,\nshipping multiple language bindings plus Grid and Selenium Manager.\nThe repository README is aimed at contributors; end-user docs live elsewhere.\n\n### Local contributor customization\n- The `.local/` directory is available for customization, generated artifacts, scratch work, and temporary files. It is ignored by Git except for `.local/README.md`.\n- A contributor may create `.local/AGENTS.md` for personal repo-specific instructions and preferences. Before beginning any task, check whether `.local/AGENTS.md` exists; if it exists, read it with your file-reading tool and apply it as the contributor's local instruction overlay.\n- If `.local/agent/skills/` exists, inspect its `*/SKILL.md` files and treat them as additional user-defined skills.\n\n## Invariants (don't violate unless explicitly asked)\n- Maintain API/ABI compatibility by default (users upgrade by changing only the version number); public functionality may be removed only after it has gone through the [Deprecation policy](#deprecation-policy) below\n- Avoid repo-wide refactors/formatting; prefer small, reversible diffs\n\n## Toolchain\n- 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.\n- Rakefile tasks are executed with a bundled jruby wrapped with `go`/`go.bat` and frequently used by CI jobs\n- Prefer targeted Bazel commands; use `bazel query ...` to locate labels before build/test\n\n## Execution model\n- Use `bazel query` to explore build graph before reading files\n- 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.\n- 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 after `build`/`test`/`query`).\n\n## Repo layout\nBindings (see `AGENTS.md` in each directory for language-specific details):\n- Java: `java/`\n- Python: `py/`\n- Ruby: `rb/`\n- JavaScript: `javascript/selenium-webdriver/`\n- .NET: `dotnet/`\n\nShared/high-risk areas:\n- `rust/` (Selenium Manager, see `rust/AGENTS.md`)\n- `common/` (build/test wiring; affects multiple areas)\n- `common/src/` (test HTML fixtures)\n- `javascript/atoms/` (shared JS atoms; high blast radius)\n- `scripts/`, `rake_tasks/`, `.github/`, `Rakefile` (tooling/build)\n- `third_party/` treat as read-only\n- `bazel-*/` treat as generated output\n\n## Cross-binding consistency checks\nWhen changing user-visible behavior, compare with at least one other binding:\n- Example: `rg <term> java/ py/ rb/ dotnet/ javascript/selenium-webdriver/`\n\nIf behavior is shared/low-level (protocol, serialization, \"remote\"/transport), suggest follow-up parity work or to file an issue\n\n## Testing\nWhen implementing solutions prefer writing a test for it first \nPrefer small (unit) tests over browser tests for speed/reliability\nAvoid mocks—they can misrepresent API contracts\n\nUseful flags:\n- `--test_size_filters=small` (unit tests only)\n- `--test_output=all` (display console output)\n- `--cache_test_results=no` (force re-run)\nSee language-specific AGENTS.md for applicable testing usage\n\n## Logging\nAdd logging where users may need insight into what's happening\nSee language-specific AGENTS.md for applicable logging usage\n\n## Deprecation policy\nThis project does not follow semantic versioning (semver); before removing public functionality, mark it as deprecated with a message pointing to the alternative.\nSee language-specific AGENTS.md for applicable deprecation usage\n\n## General Guidelines\n- Comments should explain *why*, not *what* - prefer well-named methods over comments\n- PRs should focus on one thing; we squash PRs to default `trunk` branch\n- Prefer copying files to deleting and recreating to maintain git history\n- Avoid running `bazel clean --expunge`\n- Formatting: \n  - `./scripts/format.sh` without arguments will run everything similar to running `./go format` but with failure information; With `--pre-commit` flag it only checks staged changes; With `--pre-push` flag it only checks committed changes with trunk.\n  - If `./scripts/format.sh` is already referenced in a pre-commit or pre-push hook, let the hooks handle formatting \n  - If not, run or suggest `./scripts/format.sh --pre-push` before pushing to avoid CI formatter failures\n\n## High risk changes (request verification before modifying unless explicitly instructed)\n- Everything referenced above as high risk\n- WebDriver/BiDi semantics, capability parsing, wire-level behavior\n- Dependency updates / `MODULE.bazel` / repin flows\n- Grid routing/distributor/queue logic\n\n## After making code changes\n- Call out any high risk areas touched\n- Note cross-binding impact and any follow-up issues needed\n\n## Reviewing pull requests\nSee `.github/pr_review.md` for agentic review priorities and scope.\n","java/AGENTS.md":"<!-- Guidance for AI agents working in Selenium Java Bindings and Grid. -->\n\n## Code location\n- Java Bindings: `java/src/`, `java/test/`\n- Grid Server: `java/src/org/openqa/selenium/grid/`\n\n## Common commands\n- Build: `bazel build //java/...`\n- Build Grid: `bazel build grid`\n\n## Testing\nSee `java/TESTING.md`\n\n## Code conventions\n### Interfaces\n- New methods added to existing interfaces must provide a default implementation, if possible.\n- Interfaces must not expose the native classes of their implementations.\n\n### Logging\n```java\nimport java.util.logging.Logger;\nprivate static final Logger LOG = Logger.getLogger(MyClass.class.getName());\n\nLOG.warning(\"actionable: something needs attention\");\nLOG.info(\"useful: server started on port 4444\");\nLOG.fine(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```java\n@Deprecated(forRemoval = true)\npublic void legacyMethod() { }\n```\n\n### Documentation\nUse Javadoc for public APIs:\n```java\n/**\n * Brief description.\n *\n * @param name description\n * @return description\n * @throws ExceptionType when condition\n */\n```\n",".github/copilot-instructions.md":"Always read AGENTS.md before answering\nWhen reviewing a pull request, also follow the guidelines in .github/pr_review.md\n","py/AGENTS.md":"<!-- Guidance for AI agents working in Selenium Python Bindings -->\n\n## Code location\n\n- Package: `py/selenium/`\n- Remote/transport: `py/selenium/webdriver/remote/`\n\n## Common commands\n\n- Build: `bazel build //py/...`\n\n## Testing\n\nRun tests via `bazel test //py/...`. See `/AGENTS.md` for toolchain details.\n\n## Testing\n\nRun tests via `bazel test //py:test-{browser}` or `bazel test //py:test-{browser}-bidi`, where `{browser}` is the target browser (e.g., `chrome`, `firefox`, `edge`). See `/AGENTS.md` for toolchain details.\n\n## Code conventions\n\n### Logging\n\n```python\nlogger = logging.getLogger(__name__)\n\nlogger.warning(\"actionable: something needs attention\")\nlogger.info(\"useful: driver started successfully\")\nlogger.debug(\"diagnostic: request payload for debugging\")\n```\n\n### Deprecation\n\n```python\nwarnings.warn(\n    \"old_method is deprecated, use new_method instead\",\n    DeprecationWarning,\n    stacklevel=2\n)\n```\n\n### Type hints\n\nType hints are used throughout; add type annotations to new code\n\nUse union notation (`|`) instead of `Optional`:\n\n```python\n# Preferred\ndef method(param: str | None) -> int | None:\n    pass\n\n# Avoid\ndef method(param: Optional[str]) -> Optional[int]:\n    pass\n```\n\n### Python version\n\nCode must work with Python 3.10 or later. Use modern syntax features available in 3.10+:\n\n- Use `|` for union types instead of `Union[]`\n- Use `X | None` instead of `Optional[X]`\n\nWhen running tests or code in the terminal, explicitly use `python3.10` or later:\n\n```bash\n# Use explicitly\npython3.10 -c \"...\"\npython3.11 -c \"...\"\n\n# Avoid relying on `python3` as it may be 3.9 or earlier\n```\n\n### Documentation\n\nUse Google-style docstrings:\n\n```python\ndef method(param: str) -> bool:\n    \"\"\"Brief description.\n\n    Args:\n        param: Description of param.\n\n    Returns:\n        Description of return value.\n\n    Raises:\n        ValueError: When condition.\n    \"\"\"\n```\n","rb/AGENTS.md":"<!-- Guidance for AI agents working in Selenium Ruby Bindings -->\n\n## Code location\n- Library: `rb/lib/selenium/webdriver`\n- Tests: `rb/spec/unit/` and `rb/spec/integration/`\n- Type signatures: `rb/sig/`\n\n## Common commands\n- Build: `bazel build //rb/...`\n\n## Testing\nSee `rb/TESTING.md`\n\n## Code conventions\n\n### Logging\n```ruby\nWebDriver.logger.warn(\"actionable: something needs attention\", id: :warning_id)\nWebDriver.logger.info(\"useful: driver started successfully\")\nWebDriver.logger.debug(\"diagnostic: request details for debugging\")\n```\n\n### Deprecation\n```ruby\nWebDriver.logger.deprecate(\n  'OldClass#old_method',\n  'NewClass#new_method',\n  id: :old_method\n)\n```\n\n### Internal APIs\nMark internal APIs with `@api private` in YARD comments:\n```ruby\n# @api private\ndef internal_method\nend\n```\n\n### Type signatures (steep/rbs)\nWhen changing public API, update corresponding `.rbs` files in `rb/sig/`\n\n### Documentation\nUse YARD for public APIs:\n```ruby\n# Brief description.\n#\n# @param name [Type] description\n# @return [Type] description\n# @raise [ErrorClass] when condition\n```\n\n## Integration test guards\n\nIntegration specs are guarded by RSpec metadata on `describe`/`context`/`it` (all enclosing\nguards combine). Use one of these five, and always include a `reason:`:\n\n- `skip_if:` — skip when config matches\n- `skip_unless:` — run only when config matches\n- `pending_if:` — expect failure when config matches\n- `pending_unless:` — expect failure unless config matches\n- `flaky:` — `skip_if` reserved for unreliable/intermittent tests\n\nMatching within one Hash = AND (every pair must match); an Array value within a key = OR (matches any\nlisted value). An Array of Hashes lists configs matched independently, and the combined effect depends\non the guard direction: for `skip_if`/`pending_if` the guard triggers if **any** Hash matches (OR); for\n`skip_unless`/`pending_unless` the example is kept only where **all** Hashes match (i.e. it is\nskipped/pended if any does not). The `reason:` is a String or an issue number. Conditions (`browser`,\n`driver`, `platform`, `ci`, etc.) are registered in\n[`spec_helper.rb`](spec/integration/selenium/webdriver/spec_helper.rb).\n\n```ruby\nskip_if: {browser: %i[chrome edge], headless: true, reason: '...'}                   # headless Chrome or Edge\npending_if: [{browser: :firefox, reason: 1234}, {platform: :macosx, reason: 5678}]   # Firefox OR macOS\nskip_unless: [{bidi: false, reason: '...'}, {driver: :remote, reason: '...'}]        # only when non-bidi AND remote\n```\n","common/devtools/README.md":"# Chrome Debugging Protocol\n\nWe keep multiple versions of the protocol in the tree in order to allow us to generate bindings as\nneeded.\n\nThey are typically downloaded from the [devtools source][]\n\nFortunately both Chrome and Edge are based off Chromium releases and those are OSS. In order to get\nthe versions of the protocol spoken by particular releases of Chrome:\n\n* Find out the latest version of [Stable Channel Update for Desktop][] (e.g., `96.0.4664.45`).\n* Create a `vXX` directory under `//common/devtools/chromium` (e.g. `v96` for `96.0.4664.45`)\n* Copy the `BUILD.bazel` file from the `vXX-1` directory.\n* Navigate to the [Chromium source][] and open the tag matching the release number.\n* Find `//third_party/blink/public/devtools_protocol/browser_protocol.pdl` and download the file\n  to `//common/devtools/chromium/vXX`.\n  * (Quick link:\n    `https://raw.githubusercontent.com/chromium/chromium/<LATEST_VERSION_NUMBER>/third_party/blink/public/devtools_protocol/browser_protocol.pdl`)\n* Now figure out the version of v8 used by the version of Chromium. In Chromium's source, navigate\n  to `//:DEPS` and search for `v8_revision`\n  * (Quick\n    link: `https://github.com/chromium/chromium/blob/<LATEST_VERSION_NUMBER>/DEPS#:~:text=the%20commit%20queue%20can%20handle%20cls%20rolling%20v8`)\n* Head over to the [v8 source](https://github.com/v8/v8) and switch to the indicated revision\n  * (e.g., `451d38b60be0a0f692b11815289cf8cbc9b1dc98`)\n* Find `//include/js_protocol.pdl` and download the file to `//common/devtools/chromium/vXX`.\n  (Quick link: `https://github.com/v8/v8/raw/<V8_REVISION_NUMBER>/include/js_protocol.pdl`)\n\nYou may also find the same information at the [OmahaProxy CSV Viewer][]\n\nWe have a modified form of the scripts used by Chromium to generate the protocol files. The\noriginals were in:\n\nhttps://github.com/chromium/chromium/blob/master/third_party/inspector_protocol/convert_protocol_to_json.py\n\n[devtools source]: https://github.com/ChromeDevTools/devtools-protocol/tree/master/json\n\n[Stable Channel Update for Desktop]: https://chromereleases.googleblog.com/search/label/Stable%20updates\n\n[Chromium source]: https://github.com/chromium/chromium/\n\n[OmahaProxy CSV Viewer]: https://omahaproxy.appspot.com\n","rust/AGENTS.md":"<!-- Guidance for AI agents working in Selenium Manager code -->\n\n## Code location\n- Source: `rust/src/`\n- Tests: `rust/tests/`\n\n## Common commands\n- Build: `bazel build //rust/...`\n\n## Testing\nSee `rust/TESTING.md`\n\n## Code conventions\n\n### Logging\n```rust\nuse log::{warn, info, debug};\n\nwarn!(\"actionable: something needs attention\");\ninfo!(\"useful: browser resolved successfully\");\ndebug!(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```rust\n#[deprecated(since = \"0.1.0\", note = \"Use new_function instead\")]\npub fn old_function() { }\n```\n\n### Documentation\nUse doc comments for public APIs:\n```rust\n/// Brief description.\n///\n/// # Arguments\n/// * `name` - description\n///\n/// # Returns\n/// Description of return value.\n///\n/// # Errors\n/// Returns `ErrorType` when condition.\n```\n","common/extensions/webextensions-selenium-example/manifest.json":"{\n  \"manifest_version\": 3,\n  \"name\": \"webextensions-selenium-example\",\n  \"description\": \"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium\",\n  \"version\": \"0.1\",\n  \"content_scripts\": [\n    {\n      \"matches\": [\n        \"https://*/*\",\n        \"http://*/*\"\n      ],\n      \"js\": [\n        \"inject.js\"\n      ]\n    }\n  ],\n  \"permissions\": [\n    \"storage\",\n    \"scripting\"\n  ],\n  \"host_permissions\": [\n    \"https://*/*\",\n    \"http://*/*\"\n  ],\n  \"browser_specific_settings\": {\n    \"gecko\": {\n      \"id\": \"webextensions-selenium-example-v3@example.com\"\n    }\n  }\n}\n","common/extensions/webextensions-selenium-example-signed/manifest.json":"{\n  \"manifest_version\": 3,\n  \"name\": \"webextensions-selenium-example\",\n  \"description\": \"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium\",\n  \"version\": \"0.1\",\n  \"content_scripts\": [\n    {\n      \"matches\": [\n        \"https://*/*\",\n        \"http://*/*\"\n      ],\n      \"js\": [\n        \"inject.js\"\n      ]\n    }\n  ],\n  \"browser_specific_settings\": {\n    \"gecko\": {\n      \"id\": \"webextensions-selenium-example-v3@example.com\"\n    }\n  }\n}","dotnet/src/webdriver/DevTools/README.md":"### Adding support for a new version of Chromium DevTools Protocol to the .NET bindings\n\nTo add support for a new version of the Chromium DevTools Protocol to the .NET bindings,\nperform the following steps, where `<N>` is the major version of the protocol:\n\n1. Add the new version string (`v<N>`) to the `SUPPORTED_DEVTOOLS_VERSIONS` list in\n[`//dotnet:version.bzl`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/version.bzl).\n2. Create a new directory at `//dotnet/src/webdriver/DevTools/v<N>`, and copy the\ncontents of the `//dotnet/src/webdriver/DevTools/v<N-1>` directory into it.\n3. Rename each of the `*.cs` files in `//dotnet/src/webdriver/DevTools/v<N>` so that\nthe file names start with `V<N>` instead of `V<N-1>`.\n4. In each of the `*.cs` files in `//dotnet/src/webdriver/DevTools/v<N>`, update all\noccurrences of `V<N-1>` to `V<N>`. **IMPORTANT:** Do _not_ change the case of `V<N>` in\neach `.cs` file.\n5. In [`//dotnet/src/webdriver/DevTools/DevToolsDomains.cs`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/DevTools/DevToolsDomains.cs),\nadd an entry for version `<N>` to the `SupportedDevToolsVersions` dictionary initialization.\n6. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.cmd`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.cmd),\nadd the following block (substituting the proper value for `<N>`):\n\n```bash\nif not exist  \"%1..\\..\\..\\bazel-bin\\dotnet\\src\\webdriver\\DevTools\\v<N>\\DevToolsSessionDomains.cs\" (\n  echo Generating CDP code for version <N>\n  pushd \"%1..\\..\\..\"\n  bazel build //dotnet/src/webdriver/DevTools:generate-v<N>\n  popd\n)\n```\n\n7. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.sh`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.sh),\nadd the following block (substituting the proper value for `<N>`):\n\n```bash\nif [[ ! -f \"$1../../../bazel-bin/dotnet/src/webdriver/DevTools/v<N>/DevToolsSessionDomains.cs\" ]]\nthen\n  echo \"Generating CDP code for version <N>\"\n  bazel build //dotnet/src/webdriver/DevTools:generate-v<N>\nfi\n```\n\n8. In each of the `*.cs` files in `//dotnet/test/common/DevTools/`, update all\n      occurrences of `V<N-2>` to `V<N-1>`. For now, due to issues with timeliness of CI tool\n      updates, we keep this one version behind the latest.\n9. Commit the changes.\n\n### Removing support for a version of Chromium DevTools Protocol from the .NET bindings\n\nTo remove support for a version of the Chromium DevTools Protocol from the .NET bindings,\nperform the following steps, where `<N>` is the major version of the protocol:\n\n1. Delete the contents of the `//dotnet/src/webdriver/DevTools/v<N>` directory.\n2. In [`//dotnet/src/webdriver/DevTools/DevToolsDomains.cs`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/DevTools/DevToolsDomains.cs),\nremove the entry for version `<N>` from the `SupportedDevToolsVersions` dictionary initialization.\n3. Remove the version string (`v<N>`) from the `SUPPORTED_DEVTOOLS_VERSIONS` list in\n[`//dotnet:version.bzl`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/version.bzl).\n4. Commit the changes.\n","dotnet/AGENTS.md":"<!-- Guidance for AI agents working in Selenium .NET Bindings -->\n\n## Code location\n- Core: `dotnet/src/webdriver/`\n- Support: `dotnet/src/support/`\n- Tests: `dotnet/test/common/`\n\n## Common commands\n- Build: `bazel build //dotnet/...`\n\n## Testing\nSee `dotnet/TESTING.md`\n\n## Code conventions\n\n### Logging\n```csharp\nusing OpenQA.Selenium.Internal.Logging;\nprivate static readonly ILogger _logger = Log.GetLogger<MyClass>();\n\n_logger.Warn(\"actionable: something needs attention\");\n_logger.Info(\"useful: driver started successfully\");\n_logger.Debug(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```csharp\n[Obsolete(\"Use NewMethod instead\")]\npublic void OldMethod() { }\n```\nWhen code inside the assembly must still reference an obsolete member (e.g. a field\nor method the obsolete API is built on), wrap just that usage to keep the build\nwarning-clean (see `UserPromptHandler.cs`):\n```csharp\n#pragma warning disable CS0618 // Type or member is obsolete\nthis.legacyThing.DoWork();\n#pragma warning restore CS0618 // Type or member is obsolete\n```\n\n### Async patterns\nThe codebase is migrating to async\n\n### Documentation\nUse XML documentation comments for public APIs:\n```csharp\n/// <summary>\n/// Brief description.\n/// </summary>\n/// <param name=\"name\">Description.</param>\n/// <returns>Description.</returns>\n/// <exception cref=\"ExceptionType\">When condition.</exception>\n```\n","rb/lib/selenium/devtools/README.md":"# devtools Documentation\n\nPath: `rb/lib/selenium/devtools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/rb/lib/selenium/devtools/README.md)","java/src/org/openqa/selenium/devtools/README.md":"# devtools Documentation\n\nPath: `java/src/org/openqa/selenium/devtools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/java/src/org/openqa/selenium/devtools/README.md)"},"files":{"AGENTS.md":"<!--\nGuidance for AI agents working in the Selenium monorepo.\nLanguage-specific details live in respective subdirectories.\n-->\n## Overview\n\nSelenium is a Bazel-built monorepo implementing the W3C WebDriver (and related) protocols,\nshipping multiple language bindings plus Grid and Selenium Manager.\nThe repository README is aimed at contributors; end-user docs live elsewhere.\n\n### Local contributor customization\n- The `.local/` directory is available for customization, generated artifacts, scratch work, and temporary files. It is ignored by Git except for `.local/README.md`.\n- A contributor may create `.local/AGENTS.md` for personal repo-specific instructions and preferences. Before beginning any task, check whether `.local/AGENTS.md` exists; if it exists, read it with your file-reading tool and apply it as the contributor's local instruction overlay.\n- If `.local/agent/skills/` exists, inspect its `*/SKILL.md` files and treat them as additional user-defined skills.\n\n## Invariants (don't violate unless explicitly asked)\n- Maintain API/ABI compatibility by default (users upgrade by changing only the version number); public functionality may be removed only after it has gone through the [Deprecation policy](#deprecation-policy) below\n- Avoid repo-wide refactors/formatting; prefer small, reversible diffs\n\n## Toolchain\n- 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.\n- Rakefile tasks are executed with a bundled jruby wrapped with `go`/`go.bat` and frequently used by CI jobs\n- Prefer targeted Bazel commands; use `bazel query ...` to locate labels before build/test\n\n## Execution model\n- Use `bazel query` to explore build graph before reading files\n- 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.\n- 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 after `build`/`test`/`query`).\n\n## Repo layout\nBindings (see `AGENTS.md` in each directory for language-specific details):\n- Java: `java/`\n- Python: `py/`\n- Ruby: `rb/`\n- JavaScript: `javascript/selenium-webdriver/`\n- .NET: `dotnet/`\n\nShared/high-risk areas:\n- `rust/` (Selenium Manager, see `rust/AGENTS.md`)\n- `common/` (build/test wiring; affects multiple areas)\n- `common/src/` (test HTML fixtures)\n- `javascript/atoms/` (shared JS atoms; high blast radius)\n- `scripts/`, `rake_tasks/`, `.github/`, `Rakefile` (tooling/build)\n- `third_party/` treat as read-only\n- `bazel-*/` treat as generated output\n\n## Cross-binding consistency checks\nWhen changing user-visible behavior, compare with at least one other binding:\n- Example: `rg <term> java/ py/ rb/ dotnet/ javascript/selenium-webdriver/`\n\nIf behavior is shared/low-level (protocol, serialization, \"remote\"/transport), suggest follow-up parity work or to file an issue\n\n## Testing\nWhen implementing solutions prefer writing a test for it first \nPrefer small (unit) tests over browser tests for speed/reliability\nAvoid mocks—they can misrepresent API contracts\n\nUseful flags:\n- `--test_size_filters=small` (unit tests only)\n- `--test_output=all` (display console output)\n- `--cache_test_results=no` (force re-run)\nSee language-specific AGENTS.md for applicable testing usage\n\n## Logging\nAdd logging where users may need insight into what's happening\nSee language-specific AGENTS.md for applicable logging usage\n\n## Deprecation policy\nThis project does not follow semantic versioning (semver); before removing public functionality, mark it as deprecated with a message pointing to the alternative.\nSee language-specific AGENTS.md for applicable deprecation usage\n\n## General Guidelines\n- Comments should explain *why*, not *what* - prefer well-named methods over comments\n- PRs should focus on one thing; we squash PRs to default `trunk` branch\n- Prefer copying files to deleting and recreating to maintain git history\n- Avoid running `bazel clean --expunge`\n- Formatting: \n  - `./scripts/format.sh` without arguments will run everything similar to running `./go format` but with failure information; With `--pre-commit` flag it only checks staged changes; With `--pre-push` flag it only checks committed changes with trunk.\n  - If `./scripts/format.sh` is already referenced in a pre-commit or pre-push hook, let the hooks handle formatting \n  - If not, run or suggest `./scripts/format.sh --pre-push` before pushing to avoid CI formatter failures\n\n## High risk changes (request verification before modifying unless explicitly instructed)\n- Everything referenced above as high risk\n- WebDriver/BiDi semantics, capability parsing, wire-level behavior\n- Dependency updates / `MODULE.bazel` / repin flows\n- Grid routing/distributor/queue logic\n\n## After making code changes\n- Call out any high risk areas touched\n- Note cross-binding impact and any follow-up issues needed\n\n## Reviewing pull requests\nSee `.github/pr_review.md` for agentic review priorities and scope.\n","java/AGENTS.md":"<!-- Guidance for AI agents working in Selenium Java Bindings and Grid. -->\n\n## Code location\n- Java Bindings: `java/src/`, `java/test/`\n- Grid Server: `java/src/org/openqa/selenium/grid/`\n\n## Common commands\n- Build: `bazel build //java/...`\n- Build Grid: `bazel build grid`\n\n## Testing\nSee `java/TESTING.md`\n\n## Code conventions\n### Interfaces\n- New methods added to existing interfaces must provide a default implementation, if possible.\n- Interfaces must not expose the native classes of their implementations.\n\n### Logging\n```java\nimport java.util.logging.Logger;\nprivate static final Logger LOG = Logger.getLogger(MyClass.class.getName());\n\nLOG.warning(\"actionable: something needs attention\");\nLOG.info(\"useful: server started on port 4444\");\nLOG.fine(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```java\n@Deprecated(forRemoval = true)\npublic void legacyMethod() { }\n```\n\n### Documentation\nUse Javadoc for public APIs:\n```java\n/**\n * Brief description.\n *\n * @param name description\n * @return description\n * @throws ExceptionType when condition\n */\n```\n",".github/copilot-instructions.md":"Always read AGENTS.md before answering\nWhen reviewing a pull request, also follow the guidelines in .github/pr_review.md\n","py/AGENTS.md":"<!-- Guidance for AI agents working in Selenium Python Bindings -->\n\n## Code location\n\n- Package: `py/selenium/`\n- Remote/transport: `py/selenium/webdriver/remote/`\n\n## Common commands\n\n- Build: `bazel build //py/...`\n\n## Testing\n\nRun tests via `bazel test //py/...`. See `/AGENTS.md` for toolchain details.\n\n## Testing\n\nRun tests via `bazel test //py:test-{browser}` or `bazel test //py:test-{browser}-bidi`, where `{browser}` is the target browser (e.g., `chrome`, `firefox`, `edge`). See `/AGENTS.md` for toolchain details.\n\n## Code conventions\n\n### Logging\n\n```python\nlogger = logging.getLogger(__name__)\n\nlogger.warning(\"actionable: something needs attention\")\nlogger.info(\"useful: driver started successfully\")\nlogger.debug(\"diagnostic: request payload for debugging\")\n```\n\n### Deprecation\n\n```python\nwarnings.warn(\n    \"old_method is deprecated, use new_method instead\",\n    DeprecationWarning,\n    stacklevel=2\n)\n```\n\n### Type hints\n\nType hints are used throughout; add type annotations to new code\n\nUse union notation (`|`) instead of `Optional`:\n\n```python\n# Preferred\ndef method(param: str | None) -> int | None:\n    pass\n\n# Avoid\ndef method(param: Optional[str]) -> Optional[int]:\n    pass\n```\n\n### Python version\n\nCode must work with Python 3.10 or later. Use modern syntax features available in 3.10+:\n\n- Use `|` for union types instead of `Union[]`\n- Use `X | None` instead of `Optional[X]`\n\nWhen running tests or code in the terminal, explicitly use `python3.10` or later:\n\n```bash\n# Use explicitly\npython3.10 -c \"...\"\npython3.11 -c \"...\"\n\n# Avoid relying on `python3` as it may be 3.9 or earlier\n```\n\n### Documentation\n\nUse Google-style docstrings:\n\n```python\ndef method(param: str) -> bool:\n    \"\"\"Brief description.\n\n    Args:\n        param: Description of param.\n\n    Returns:\n        Description of return value.\n\n    Raises:\n        ValueError: When condition.\n    \"\"\"\n```\n","rb/AGENTS.md":"<!-- Guidance for AI agents working in Selenium Ruby Bindings -->\n\n## Code location\n- Library: `rb/lib/selenium/webdriver`\n- Tests: `rb/spec/unit/` and `rb/spec/integration/`\n- Type signatures: `rb/sig/`\n\n## Common commands\n- Build: `bazel build //rb/...`\n\n## Testing\nSee `rb/TESTING.md`\n\n## Code conventions\n\n### Logging\n```ruby\nWebDriver.logger.warn(\"actionable: something needs attention\", id: :warning_id)\nWebDriver.logger.info(\"useful: driver started successfully\")\nWebDriver.logger.debug(\"diagnostic: request details for debugging\")\n```\n\n### Deprecation\n```ruby\nWebDriver.logger.deprecate(\n  'OldClass#old_method',\n  'NewClass#new_method',\n  id: :old_method\n)\n```\n\n### Internal APIs\nMark internal APIs with `@api private` in YARD comments:\n```ruby\n# @api private\ndef internal_method\nend\n```\n\n### Type signatures (steep/rbs)\nWhen changing public API, update corresponding `.rbs` files in `rb/sig/`\n\n### Documentation\nUse YARD for public APIs:\n```ruby\n# Brief description.\n#\n# @param name [Type] description\n# @return [Type] description\n# @raise [ErrorClass] when condition\n```\n\n## Integration test guards\n\nIntegration specs are guarded by RSpec metadata on `describe`/`context`/`it` (all enclosing\nguards combine). Use one of these five, and always include a `reason:`:\n\n- `skip_if:` — skip when config matches\n- `skip_unless:` — run only when config matches\n- `pending_if:` — expect failure when config matches\n- `pending_unless:` — expect failure unless config matches\n- `flaky:` — `skip_if` reserved for unreliable/intermittent tests\n\nMatching within one Hash = AND (every pair must match); an Array value within a key = OR (matches any\nlisted value). An Array of Hashes lists configs matched independently, and the combined effect depends\non the guard direction: for `skip_if`/`pending_if` the guard triggers if **any** Hash matches (OR); for\n`skip_unless`/`pending_unless` the example is kept only where **all** Hashes match (i.e. it is\nskipped/pended if any does not). The `reason:` is a String or an issue number. Conditions (`browser`,\n`driver`, `platform`, `ci`, etc.) are registered in\n[`spec_helper.rb`](spec/integration/selenium/webdriver/spec_helper.rb).\n\n```ruby\nskip_if: {browser: %i[chrome edge], headless: true, reason: '...'}                   # headless Chrome or Edge\npending_if: [{browser: :firefox, reason: 1234}, {platform: :macosx, reason: 5678}]   # Firefox OR macOS\nskip_unless: [{bidi: false, reason: '...'}, {driver: :remote, reason: '...'}]        # only when non-bidi AND remote\n```\n","common/devtools/README.md":"# Chrome Debugging Protocol\n\nWe keep multiple versions of the protocol in the tree in order to allow us to generate bindings as\nneeded.\n\nThey are typically downloaded from the [devtools source][]\n\nFortunately both Chrome and Edge are based off Chromium releases and those are OSS. In order to get\nthe versions of the protocol spoken by particular releases of Chrome:\n\n* Find out the latest version of [Stable Channel Update for Desktop][] (e.g., `96.0.4664.45`).\n* Create a `vXX` directory under `//common/devtools/chromium` (e.g. `v96` for `96.0.4664.45`)\n* Copy the `BUILD.bazel` file from the `vXX-1` directory.\n* Navigate to the [Chromium source][] and open the tag matching the release number.\n* Find `//third_party/blink/public/devtools_protocol/browser_protocol.pdl` and download the file\n  to `//common/devtools/chromium/vXX`.\n  * (Quick link:\n    `https://raw.githubusercontent.com/chromium/chromium/<LATEST_VERSION_NUMBER>/third_party/blink/public/devtools_protocol/browser_protocol.pdl`)\n* Now figure out the version of v8 used by the version of Chromium. In Chromium's source, navigate\n  to `//:DEPS` and search for `v8_revision`\n  * (Quick\n    link: `https://github.com/chromium/chromium/blob/<LATEST_VERSION_NUMBER>/DEPS#:~:text=the%20commit%20queue%20can%20handle%20cls%20rolling%20v8`)\n* Head over to the [v8 source](https://github.com/v8/v8) and switch to the indicated revision\n  * (e.g., `451d38b60be0a0f692b11815289cf8cbc9b1dc98`)\n* Find `//include/js_protocol.pdl` and download the file to `//common/devtools/chromium/vXX`.\n  (Quick link: `https://github.com/v8/v8/raw/<V8_REVISION_NUMBER>/include/js_protocol.pdl`)\n\nYou may also find the same information at the [OmahaProxy CSV Viewer][]\n\nWe have a modified form of the scripts used by Chromium to generate the protocol files. The\noriginals were in:\n\nhttps://github.com/chromium/chromium/blob/master/third_party/inspector_protocol/convert_protocol_to_json.py\n\n[devtools source]: https://github.com/ChromeDevTools/devtools-protocol/tree/master/json\n\n[Stable Channel Update for Desktop]: https://chromereleases.googleblog.com/search/label/Stable%20updates\n\n[Chromium source]: https://github.com/chromium/chromium/\n\n[OmahaProxy CSV Viewer]: https://omahaproxy.appspot.com\n","rust/AGENTS.md":"<!-- Guidance for AI agents working in Selenium Manager code -->\n\n## Code location\n- Source: `rust/src/`\n- Tests: `rust/tests/`\n\n## Common commands\n- Build: `bazel build //rust/...`\n\n## Testing\nSee `rust/TESTING.md`\n\n## Code conventions\n\n### Logging\n```rust\nuse log::{warn, info, debug};\n\nwarn!(\"actionable: something needs attention\");\ninfo!(\"useful: browser resolved successfully\");\ndebug!(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```rust\n#[deprecated(since = \"0.1.0\", note = \"Use new_function instead\")]\npub fn old_function() { }\n```\n\n### Documentation\nUse doc comments for public APIs:\n```rust\n/// Brief description.\n///\n/// # Arguments\n/// * `name` - description\n///\n/// # Returns\n/// Description of return value.\n///\n/// # Errors\n/// Returns `ErrorType` when condition.\n```\n","common/extensions/webextensions-selenium-example/manifest.json":"{\n  \"manifest_version\": 3,\n  \"name\": \"webextensions-selenium-example\",\n  \"description\": \"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium\",\n  \"version\": \"0.1\",\n  \"content_scripts\": [\n    {\n      \"matches\": [\n        \"https://*/*\",\n        \"http://*/*\"\n      ],\n      \"js\": [\n        \"inject.js\"\n      ]\n    }\n  ],\n  \"permissions\": [\n    \"storage\",\n    \"scripting\"\n  ],\n  \"host_permissions\": [\n    \"https://*/*\",\n    \"http://*/*\"\n  ],\n  \"browser_specific_settings\": {\n    \"gecko\": {\n      \"id\": \"webextensions-selenium-example-v3@example.com\"\n    }\n  }\n}\n","common/extensions/webextensions-selenium-example-signed/manifest.json":"{\n  \"manifest_version\": 3,\n  \"name\": \"webextensions-selenium-example\",\n  \"description\": \"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium\",\n  \"version\": \"0.1\",\n  \"content_scripts\": [\n    {\n      \"matches\": [\n        \"https://*/*\",\n        \"http://*/*\"\n      ],\n      \"js\": [\n        \"inject.js\"\n      ]\n    }\n  ],\n  \"browser_specific_settings\": {\n    \"gecko\": {\n      \"id\": \"webextensions-selenium-example-v3@example.com\"\n    }\n  }\n}","dotnet/src/webdriver/DevTools/README.md":"### Adding support for a new version of Chromium DevTools Protocol to the .NET bindings\n\nTo add support for a new version of the Chromium DevTools Protocol to the .NET bindings,\nperform the following steps, where `<N>` is the major version of the protocol:\n\n1. Add the new version string (`v<N>`) to the `SUPPORTED_DEVTOOLS_VERSIONS` list in\n[`//dotnet:version.bzl`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/version.bzl).\n2. Create a new directory at `//dotnet/src/webdriver/DevTools/v<N>`, and copy the\ncontents of the `//dotnet/src/webdriver/DevTools/v<N-1>` directory into it.\n3. Rename each of the `*.cs` files in `//dotnet/src/webdriver/DevTools/v<N>` so that\nthe file names start with `V<N>` instead of `V<N-1>`.\n4. In each of the `*.cs` files in `//dotnet/src/webdriver/DevTools/v<N>`, update all\noccurrences of `V<N-1>` to `V<N>`. **IMPORTANT:** Do _not_ change the case of `V<N>` in\neach `.cs` file.\n5. In [`//dotnet/src/webdriver/DevTools/DevToolsDomains.cs`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/DevTools/DevToolsDomains.cs),\nadd an entry for version `<N>` to the `SupportedDevToolsVersions` dictionary initialization.\n6. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.cmd`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.cmd),\nadd the following block (substituting the proper value for `<N>`):\n\n```bash\nif not exist  \"%1..\\..\\..\\bazel-bin\\dotnet\\src\\webdriver\\DevTools\\v<N>\\DevToolsSessionDomains.cs\" (\n  echo Generating CDP code for version <N>\n  pushd \"%1..\\..\\..\"\n  bazel build //dotnet/src/webdriver/DevTools:generate-v<N>\n  popd\n)\n```\n\n7. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.sh`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.sh),\nadd the following block (substituting the proper value for `<N>`):\n\n```bash\nif [[ ! -f \"$1../../../bazel-bin/dotnet/src/webdriver/DevTools/v<N>/DevToolsSessionDomains.cs\" ]]\nthen\n  echo \"Generating CDP code for version <N>\"\n  bazel build //dotnet/src/webdriver/DevTools:generate-v<N>\nfi\n```\n\n8. In each of the `*.cs` files in `//dotnet/test/common/DevTools/`, update all\n      occurrences of `V<N-2>` to `V<N-1>`. For now, due to issues with timeliness of CI tool\n      updates, we keep this one version behind the latest.\n9. Commit the changes.\n\n### Removing support for a version of Chromium DevTools Protocol from the .NET bindings\n\nTo remove support for a version of the Chromium DevTools Protocol from the .NET bindings,\nperform the following steps, where `<N>` is the major version of the protocol:\n\n1. Delete the contents of the `//dotnet/src/webdriver/DevTools/v<N>` directory.\n2. In [`//dotnet/src/webdriver/DevTools/DevToolsDomains.cs`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/DevTools/DevToolsDomains.cs),\nremove the entry for version `<N>` from the `SupportedDevToolsVersions` dictionary initialization.\n3. Remove the version string (`v<N>`) from the `SUPPORTED_DEVTOOLS_VERSIONS` list in\n[`//dotnet:version.bzl`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/version.bzl).\n4. Commit the changes.\n","dotnet/AGENTS.md":"<!-- Guidance for AI agents working in Selenium .NET Bindings -->\n\n## Code location\n- Core: `dotnet/src/webdriver/`\n- Support: `dotnet/src/support/`\n- Tests: `dotnet/test/common/`\n\n## Common commands\n- Build: `bazel build //dotnet/...`\n\n## Testing\nSee `dotnet/TESTING.md`\n\n## Code conventions\n\n### Logging\n```csharp\nusing OpenQA.Selenium.Internal.Logging;\nprivate static readonly ILogger _logger = Log.GetLogger<MyClass>();\n\n_logger.Warn(\"actionable: something needs attention\");\n_logger.Info(\"useful: driver started successfully\");\n_logger.Debug(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```csharp\n[Obsolete(\"Use NewMethod instead\")]\npublic void OldMethod() { }\n```\nWhen code inside the assembly must still reference an obsolete member (e.g. a field\nor method the obsolete API is built on), wrap just that usage to keep the build\nwarning-clean (see `UserPromptHandler.cs`):\n```csharp\n#pragma warning disable CS0618 // Type or member is obsolete\nthis.legacyThing.DoWork();\n#pragma warning restore CS0618 // Type or member is obsolete\n```\n\n### Async patterns\nThe codebase is migrating to async\n\n### Documentation\nUse XML documentation comments for public APIs:\n```csharp\n/// <summary>\n/// Brief description.\n/// </summary>\n/// <param name=\"name\">Description.</param>\n/// <returns>Description.</returns>\n/// <exception cref=\"ExceptionType\">When condition.</exception>\n```\n","rb/lib/selenium/devtools/README.md":"# devtools Documentation\n\nPath: `rb/lib/selenium/devtools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/rb/lib/selenium/devtools/README.md)","java/src/org/openqa/selenium/devtools/README.md":"# devtools Documentation\n\nPath: `java/src/org/openqa/selenium/devtools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/java/src/org/openqa/selenium/devtools/README.md)"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"<!--\nGuidance for AI agents working in the Selenium monorepo.\nLanguage-specific details live in respective subdirectories.\n-->\n## Overview\n\nSelenium is a Bazel-built monorepo implementing the W3C WebDriver (and related) protocols,\nshipping multiple language bindings plus Grid and Selenium Manager.\nThe repository README is aimed at contributors; end-user docs live elsewhere.\n\n### Local contributor customization\n- The `.local/` directory is available for customization, generated artifacts, scratch work, and temporary files. It is ignored by Git except for `.local/README.md`.\n- A contributor may create `.local/AGENTS.md` for personal repo-specific instructions and preferences. Before beginning any task, check whether `.local/AGENTS.md` exists; if it exists, read it with your file-reading tool and apply it as the contributor's local instruction overlay.\n- If `.local/agent/skills/` exists, inspect its `*/SKILL.md` files and treat them as additional user-defined skills.\n\n## Invariants (don't violate unless explicitly asked)\n- Maintain API/ABI compatibility by default (users upgrade by changing only the version number); public functionality may be removed only after it has gone through the [Deprecation policy](#deprecation-policy) below\n- Avoid repo-wide refactors/formatting; prefer small, reversible diffs\n\n## Toolchain\n- 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.\n- Rakefile tasks are executed with a bundled jruby wrapped with `go`/`go.bat` and frequently used by CI jobs\n- Prefer targeted Bazel commands; use `bazel query ...` to locate labels before build/test\n\n## Execution model\n- Use `bazel query` to explore build graph before reading files\n- 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.\n- 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 after `build`/`test`/`query`).\n\n## Repo layout\nBindings (see `AGENTS.md` in each directory for language-specific details):\n- Java: `java/`\n- Python: `py/`\n- Ruby: `rb/`\n- JavaScript: `javascript/selenium-webdriver/`\n- .NET: `dotnet/`\n\nShared/high-risk areas:\n- `rust/` (Selenium Manager, see `rust/AGENTS.md`)\n- `common/` (build/test wiring; affects multiple areas)\n- `common/src/` (test HTML fixtures)\n- `javascript/atoms/` (shared JS atoms; high blast radius)\n- `scripts/`, `rake_tasks/`, `.github/`, `Rakefile` (tooling/build)\n- `third_party/` treat as read-only\n- `bazel-*/` treat as generated output\n\n## Cross-binding consistency checks\nWhen changing user-visible behavior, compare with at least one other binding:\n- Example: `rg <term> java/ py/ rb/ dotnet/ javascript/selenium-webdriver/`\n\nIf behavior is shared/low-level (protocol, serialization, \"remote\"/transport), suggest follow-up parity work or to file an issue\n\n## Testing\nWhen implementing solutions prefer writing a test for it first \nPrefer small (unit) tests over browser tests for speed/reliability\nAvoid mocks—they can misrepresent API contracts\n\nUseful flags:\n- `--test_size_filters=small` (unit tests only)\n- `--test_output=all` (display console output)\n- `--cache_test_results=no` (force re-run)\nSee language-specific AGENTS.md for applicable testing usage\n\n## Logging\nAdd logging where users may need insight into what's happening\nSee language-specific AGENTS.md for applicable logging usage\n\n## Deprecation policy\nThis project does not follow semantic versioning (semver); before removing public functionality, mark it as deprecated with a message pointing to the alternative.\nSee language-specific AGENTS.md for applicable deprecation usage\n\n## General Guidelines\n- Comments should explain *why*, not *what* - prefer well-named methods over comments\n- PRs should focus on one thing; we squash PRs to default `trunk` branch\n- Prefer copying files to deleting and recreating to maintain git history\n- Avoid running `bazel clean --expunge`\n- Formatting: \n  - `./scripts/format.sh` without arguments will run everything similar to running `./go format` but with failure information; With `--pre-commit` flag it only checks staged changes; With `--pre-push` flag it only checks committed changes with trunk.\n  - If `./scripts/format.sh` is already referenced in a pre-commit or pre-push hook, let the hooks handle formatting \n  - If not, run or suggest `./scripts/format.sh --pre-push` before pushing to avoid CI formatter failures\n\n## High risk changes (request verification before modifying unless explicitly instructed)\n- Everything referenced above as high risk\n- WebDriver/BiDi semantics, capability parsing, wire-level behavior\n- Dependency updates / `MODULE.bazel` / repin flows\n- Grid routing/distributor/queue logic\n\n## After making code changes\n- Call out any high risk areas touched\n- Note cross-binding impact and any follow-up issues needed\n\n## Reviewing pull requests\nSee `.github/pr_review.md` for agentic review priorities and scope.\n","isInternal":false,"tokens":1209,"sizeBytes":5367},{"name":"AGENTS.md","path":"dotnet/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/dotnet/AGENTS.md","title":"dotnet - AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"<!-- Guidance for AI agents working in Selenium .NET Bindings -->\n\n## Code location\n- Core: `dotnet/src/webdriver/`\n- Support: `dotnet/src/support/`\n- Tests: `dotnet/test/common/`\n\n## Common commands\n- Build: `bazel build //dotnet/...`\n\n## Testing\nSee `dotnet/TESTING.md`\n\n## Code conventions\n\n### Logging\n```csharp\nusing OpenQA.Selenium.Internal.Logging;\nprivate static readonly ILogger _logger = Log.GetLogger<MyClass>();\n\n_logger.Warn(\"actionable: something needs attention\");\n_logger.Info(\"useful: driver started successfully\");\n_logger.Debug(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```csharp\n[Obsolete(\"Use NewMethod instead\")]\npublic void OldMethod() { }\n```\nWhen code inside the assembly must still reference an obsolete member (e.g. a field\nor method the obsolete API is built on), wrap just that usage to keep the build\nwarning-clean (see `UserPromptHandler.cs`):\n```csharp\n#pragma warning disable CS0618 // Type or member is obsolete\nthis.legacyThing.DoWork();\n#pragma warning restore CS0618 // Type or member is obsolete\n```\n\n### Async patterns\nThe codebase is migrating to async\n\n### Documentation\nUse XML documentation comments for public APIs:\n```csharp\n/// <summary>\n/// Brief description.\n/// </summary>\n/// <param name=\"name\">Description.</param>\n/// <returns>Description.</returns>\n/// <exception cref=\"ExceptionType\">When condition.</exception>\n```\n","isInternal":false,"tokens":325,"sizeBytes":1395},{"name":"AGENTS.md","path":"java/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/java/AGENTS.md","title":"java - AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"<!-- Guidance for AI agents working in Selenium Java Bindings and Grid. -->\n\n## Code location\n- Java Bindings: `java/src/`, `java/test/`\n- Grid Server: `java/src/org/openqa/selenium/grid/`\n\n## Common commands\n- Build: `bazel build //java/...`\n- Build Grid: `bazel build grid`\n\n## Testing\nSee `java/TESTING.md`\n\n## Code conventions\n### Interfaces\n- New methods added to existing interfaces must provide a default implementation, if possible.\n- Interfaces must not expose the native classes of their implementations.\n\n### Logging\n```java\nimport java.util.logging.Logger;\nprivate static final Logger LOG = Logger.getLogger(MyClass.class.getName());\n\nLOG.warning(\"actionable: something needs attention\");\nLOG.info(\"useful: server started on port 4444\");\nLOG.fine(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```java\n@Deprecated(forRemoval = true)\npublic void legacyMethod() { }\n```\n\n### Documentation\nUse Javadoc for public APIs:\n```java\n/**\n * Brief description.\n *\n * @param name description\n * @return description\n * @throws ExceptionType when condition\n */\n```\n","isInternal":false,"tokens":250,"sizeBytes":1083},{"name":"AGENTS.md","path":"py/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/py/AGENTS.md","title":"py - AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"<!-- Guidance for AI agents working in Selenium Python Bindings -->\n\n## Code location\n\n- Package: `py/selenium/`\n- Remote/transport: `py/selenium/webdriver/remote/`\n\n## Common commands\n\n- Build: `bazel build //py/...`\n\n## Testing\n\nRun tests via `bazel test //py/...`. See `/AGENTS.md` for toolchain details.\n\n## Testing\n\nRun tests via `bazel test //py:test-{browser}` or `bazel test //py:test-{browser}-bidi`, where `{browser}` is the target browser (e.g., `chrome`, `firefox`, `edge`). See `/AGENTS.md` for toolchain details.\n\n## Code conventions\n\n### Logging\n\n```python\nlogger = logging.getLogger(__name__)\n\nlogger.warning(\"actionable: something needs attention\")\nlogger.info(\"useful: driver started successfully\")\nlogger.debug(\"diagnostic: request payload for debugging\")\n```\n\n### Deprecation\n\n```python\nwarnings.warn(\n    \"old_method is deprecated, use new_method instead\",\n    DeprecationWarning,\n    stacklevel=2\n)\n```\n\n### Type hints\n\nType hints are used throughout; add type annotations to new code\n\nUse union notation (`|`) instead of `Optional`:\n\n```python\n# Preferred\ndef method(param: str | None) -> int | None:\n    pass\n\n# Avoid\ndef method(param: Optional[str]) -> Optional[int]:\n    pass\n```\n\n### Python version\n\nCode must work with Python 3.10 or later. Use modern syntax features available in 3.10+:\n\n- Use `|` for union types instead of `Union[]`\n- Use `X | None` instead of `Optional[X]`\n\nWhen running tests or code in the terminal, explicitly use `python3.10` or later:\n\n```bash\n# Use explicitly\npython3.10 -c \"...\"\npython3.11 -c \"...\"\n\n# Avoid relying on `python3` as it may be 3.9 or earlier\n```\n\n### Documentation\n\nUse Google-style docstrings:\n\n```python\ndef method(param: str) -> bool:\n    \"\"\"Brief description.\n\n    Args:\n        param: Description of param.\n\n    Returns:\n        Description of return value.\n\n    Raises:\n        ValueError: When condition.\n    \"\"\"\n```\n","isInternal":false,"tokens":480,"sizeBytes":1895},{"name":"AGENTS.md","path":"rb/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/rb/AGENTS.md","title":"rb - AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"<!-- Guidance for AI agents working in Selenium Ruby Bindings -->\n\n## Code location\n- Library: `rb/lib/selenium/webdriver`\n- Tests: `rb/spec/unit/` and `rb/spec/integration/`\n- Type signatures: `rb/sig/`\n\n## Common commands\n- Build: `bazel build //rb/...`\n\n## Testing\nSee `rb/TESTING.md`\n\n## Code conventions\n\n### Logging\n```ruby\nWebDriver.logger.warn(\"actionable: something needs attention\", id: :warning_id)\nWebDriver.logger.info(\"useful: driver started successfully\")\nWebDriver.logger.debug(\"diagnostic: request details for debugging\")\n```\n\n### Deprecation\n```ruby\nWebDriver.logger.deprecate(\n  'OldClass#old_method',\n  'NewClass#new_method',\n  id: :old_method\n)\n```\n\n### Internal APIs\nMark internal APIs with `@api private` in YARD comments:\n```ruby\n# @api private\ndef internal_method\nend\n```\n\n### Type signatures (steep/rbs)\nWhen changing public API, update corresponding `.rbs` files in `rb/sig/`\n\n### Documentation\nUse YARD for public APIs:\n```ruby\n# Brief description.\n#\n# @param name [Type] description\n# @return [Type] description\n# @raise [ErrorClass] when condition\n```\n\n## Integration test guards\n\nIntegration specs are guarded by RSpec metadata on `describe`/`context`/`it` (all enclosing\nguards combine). Use one of these five, and always include a `reason:`:\n\n- `skip_if:` — skip when config matches\n- `skip_unless:` — run only when config matches\n- `pending_if:` — expect failure when config matches\n- `pending_unless:` — expect failure unless config matches\n- `flaky:` — `skip_if` reserved for unreliable/intermittent tests\n\nMatching within one Hash = AND (every pair must match); an Array value within a key = OR (matches any\nlisted value). An Array of Hashes lists configs matched independently, and the combined effect depends\non the guard direction: for `skip_if`/`pending_if` the guard triggers if **any** Hash matches (OR); for\n`skip_unless`/`pending_unless` the example is kept only where **all** Hashes match (i.e. it is\nskipped/pended if any does not). The `reason:` is a String or an issue number. Conditions (`browser`,\n`driver`, `platform`, `ci`, etc.) are registered in\n[`spec_helper.rb`](spec/integration/selenium/webdriver/spec_helper.rb).\n\n```ruby\nskip_if: {browser: %i[chrome edge], headless: true, reason: '...'}                   # headless Chrome or Edge\npending_if: [{browser: :firefox, reason: 1234}, {platform: :macosx, reason: 5678}]   # Firefox OR macOS\nskip_unless: [{bidi: false, reason: '...'}, {driver: :remote, reason: '...'}]        # only when non-bidi AND remote\n```\n","isInternal":false,"tokens":661,"sizeBytes":2528},{"name":"AGENTS.md","path":"rust/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/rust/AGENTS.md","title":"rust - AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"<!-- Guidance for AI agents working in Selenium Manager code -->\n\n## Code location\n- Source: `rust/src/`\n- Tests: `rust/tests/`\n\n## Common commands\n- Build: `bazel build //rust/...`\n\n## Testing\nSee `rust/TESTING.md`\n\n## Code conventions\n\n### Logging\n```rust\nuse log::{warn, info, debug};\n\nwarn!(\"actionable: something needs attention\");\ninfo!(\"useful: browser resolved successfully\");\ndebug!(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```rust\n#[deprecated(since = \"0.1.0\", note = \"Use new_function instead\")]\npub fn old_function() { }\n```\n\n### Documentation\nUse doc comments for public APIs:\n```rust\n/// Brief description.\n///\n/// # Arguments\n/// * `name` - description\n///\n/// # Returns\n/// Description of return value.\n///\n/// # Errors\n/// Returns `ErrorType` when condition.\n```\n","isInternal":false,"tokens":201,"sizeBytes":806},{"name":"manifest.json","path":"common/extensions/webextensions-selenium-example-signed/manifest.json","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/common/extensions/webextensions-selenium-example-signed/manifest.json","title":"webextensions-selenium-example","category":"anthropic-skill","format":"json","content":"{\n  \"manifest_version\": 3,\n  \"name\": \"webextensions-selenium-example\",\n  \"description\": \"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium\",\n  \"version\": \"0.1\",\n  \"content_scripts\": [\n    {\n      \"matches\": [\n        \"https://*/*\",\n        \"http://*/*\"\n      ],\n      \"js\": [\n        \"inject.js\"\n      ]\n    }\n  ],\n  \"browser_specific_settings\": {\n    \"gecko\": {\n      \"id\": \"webextensions-selenium-example-v3@example.com\"\n    }\n  }\n}","frontmatter":{"manifest_version":3,"name":"webextensions-selenium-example","description":"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium","version":"0.1","content_scripts":[{"matches":["https://*/*","http://*/*"],"js":["inject.js"]}],"browser_specific_settings":{"gecko":{"id":"webextensions-selenium-example-v3@example.com"}}},"isInternal":false,"tokens":133,"sizeBytes":490},{"name":"manifest.json","path":"common/extensions/webextensions-selenium-example/manifest.json","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/common/extensions/webextensions-selenium-example/manifest.json","title":"webextensions-selenium-example","category":"anthropic-skill","format":"json","content":"{\n  \"manifest_version\": 3,\n  \"name\": \"webextensions-selenium-example\",\n  \"description\": \"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium\",\n  \"version\": \"0.1\",\n  \"content_scripts\": [\n    {\n      \"matches\": [\n        \"https://*/*\",\n        \"http://*/*\"\n      ],\n      \"js\": [\n        \"inject.js\"\n      ]\n    }\n  ],\n  \"permissions\": [\n    \"storage\",\n    \"scripting\"\n  ],\n  \"host_permissions\": [\n    \"https://*/*\",\n    \"http://*/*\"\n  ],\n  \"browser_specific_settings\": {\n    \"gecko\": {\n      \"id\": \"webextensions-selenium-example-v3@example.com\"\n    }\n  }\n}\n","frontmatter":{"manifest_version":3,"name":"webextensions-selenium-example","description":"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium","version":"0.1","content_scripts":[{"matches":["https://*/*","http://*/*"],"js":["inject.js"]}],"permissions":["storage","scripting"],"host_permissions":["https://*/*","http://*/*"],"browser_specific_settings":{"gecko":{"id":"webextensions-selenium-example-v3@example.com"}}},"isInternal":false,"tokens":171,"sizeBytes":611},{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/.github/copilot-instructions.md","title":"GitHub Copilot Instructions","category":"copilot-instructions","format":"markdown","content":"Always read AGENTS.md before answering\nWhen reviewing a pull request, also follow the guidelines in .github/pr_review.md\n","isInternal":false,"tokens":25,"sizeBytes":121},{"name":"README.md","path":"common/devtools/README.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/common/devtools/README.md","title":"devtools Documentation","category":"plugin-manifest","format":"markdown","content":"# Chrome Debugging Protocol\n\nWe keep multiple versions of the protocol in the tree in order to allow us to generate bindings as\nneeded.\n\nThey are typically downloaded from the [devtools source][]\n\nFortunately both Chrome and Edge are based off Chromium releases and those are OSS. In order to get\nthe versions of the protocol spoken by particular releases of Chrome:\n\n* Find out the latest version of [Stable Channel Update for Desktop][] (e.g., `96.0.4664.45`).\n* Create a `vXX` directory under `//common/devtools/chromium` (e.g. `v96` for `96.0.4664.45`)\n* Copy the `BUILD.bazel` file from the `vXX-1` directory.\n* Navigate to the [Chromium source][] and open the tag matching the release number.\n* Find `//third_party/blink/public/devtools_protocol/browser_protocol.pdl` and download the file\n  to `//common/devtools/chromium/vXX`.\n  * (Quick link:\n    `https://raw.githubusercontent.com/chromium/chromium/<LATEST_VERSION_NUMBER>/third_party/blink/public/devtools_protocol/browser_protocol.pdl`)\n* Now figure out the version of v8 used by the version of Chromium. In Chromium's source, navigate\n  to `//:DEPS` and search for `v8_revision`\n  * (Quick\n    link: `https://github.com/chromium/chromium/blob/<LATEST_VERSION_NUMBER>/DEPS#:~:text=the%20commit%20queue%20can%20handle%20cls%20rolling%20v8`)\n* Head over to the [v8 source](https://github.com/v8/v8) and switch to the indicated revision\n  * (e.g., `451d38b60be0a0f692b11815289cf8cbc9b1dc98`)\n* Find `//include/js_protocol.pdl` and download the file to `//common/devtools/chromium/vXX`.\n  (Quick link: `https://github.com/v8/v8/raw/<V8_REVISION_NUMBER>/include/js_protocol.pdl`)\n\nYou may also find the same information at the [OmahaProxy CSV Viewer][]\n\nWe have a modified form of the scripts used by Chromium to generate the protocol files. The\noriginals were in:\n\nhttps://github.com/chromium/chromium/blob/master/third_party/inspector_protocol/convert_protocol_to_json.py\n\n[devtools source]: https://github.com/ChromeDevTools/devtools-protocol/tree/master/json\n\n[Stable Channel Update for Desktop]: https://chromereleases.googleblog.com/search/label/Stable%20updates\n\n[Chromium source]: https://github.com/chromium/chromium/\n\n[OmahaProxy CSV Viewer]: https://omahaproxy.appspot.com\n","isInternal":false,"tokens":590,"sizeBytes":2241},{"name":"README.md","path":"dotnet/src/webdriver/DevTools/README.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/dotnet/src/webdriver/DevTools/README.md","title":"DevTools Documentation","category":"plugin-manifest","format":"markdown","content":"### Adding support for a new version of Chromium DevTools Protocol to the .NET bindings\n\nTo add support for a new version of the Chromium DevTools Protocol to the .NET bindings,\nperform the following steps, where `<N>` is the major version of the protocol:\n\n1. Add the new version string (`v<N>`) to the `SUPPORTED_DEVTOOLS_VERSIONS` list in\n[`//dotnet:version.bzl`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/version.bzl).\n2. Create a new directory at `//dotnet/src/webdriver/DevTools/v<N>`, and copy the\ncontents of the `//dotnet/src/webdriver/DevTools/v<N-1>` directory into it.\n3. Rename each of the `*.cs` files in `//dotnet/src/webdriver/DevTools/v<N>` so that\nthe file names start with `V<N>` instead of `V<N-1>`.\n4. In each of the `*.cs` files in `//dotnet/src/webdriver/DevTools/v<N>`, update all\noccurrences of `V<N-1>` to `V<N>`. **IMPORTANT:** Do _not_ change the case of `V<N>` in\neach `.cs` file.\n5. In [`//dotnet/src/webdriver/DevTools/DevToolsDomains.cs`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/DevTools/DevToolsDomains.cs),\nadd an entry for version `<N>` to the `SupportedDevToolsVersions` dictionary initialization.\n6. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.cmd`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.cmd),\nadd the following block (substituting the proper value for `<N>`):\n\n```bash\nif not exist  \"%1..\\..\\..\\bazel-bin\\dotnet\\src\\webdriver\\DevTools\\v<N>\\DevToolsSessionDomains.cs\" (\n  echo Generating CDP code for version <N>\n  pushd \"%1..\\..\\..\"\n  bazel build //dotnet/src/webdriver/DevTools:generate-v<N>\n  popd\n)\n```\n\n7. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.sh`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.sh),\nadd the following block (substituting the proper value for `<N>`):\n\n```bash\nif [[ ! -f \"$1../../../bazel-bin/dotnet/src/webdriver/DevTools/v<N>/DevToolsSessionDomains.cs\" ]]\nthen\n  echo \"Generating CDP code for version <N>\"\n  bazel build //dotnet/src/webdriver/DevTools:generate-v<N>\nfi\n```\n\n8. In each of the `*.cs` files in `//dotnet/test/common/DevTools/`, update all\n      occurrences of `V<N-2>` to `V<N-1>`. For now, due to issues with timeliness of CI tool\n      updates, we keep this one version behind the latest.\n9. Commit the changes.\n\n### Removing support for a version of Chromium DevTools Protocol from the .NET bindings\n\nTo remove support for a version of the Chromium DevTools Protocol from the .NET bindings,\nperform the following steps, where `<N>` is the major version of the protocol:\n\n1. Delete the contents of the `//dotnet/src/webdriver/DevTools/v<N>` directory.\n2. In [`//dotnet/src/webdriver/DevTools/DevToolsDomains.cs`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/DevTools/DevToolsDomains.cs),\nremove the entry for version `<N>` from the `SupportedDevToolsVersions` dictionary initialization.\n3. Remove the version string (`v<N>`) from the `SUPPORTED_DEVTOOLS_VERSIONS` list in\n[`//dotnet:version.bzl`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/version.bzl).\n4. Commit the changes.\n","isInternal":false,"tokens":866,"sizeBytes":3175},{"name":"README.md","path":"java/src/org/openqa/selenium/devtools/README.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/java/src/org/openqa/selenium/devtools/README.md","title":"devtools Documentation","category":"plugin-manifest","format":"markdown","content":"# devtools Documentation\n\nPath: `java/src/org/openqa/selenium/devtools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/java/src/org/openqa/selenium/devtools/README.md)","tokens":300,"sizeBytes":219},{"name":"README.md","path":"rb/lib/selenium/devtools/README.md","rawUrl":"https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/rb/lib/selenium/devtools/README.md","title":"devtools Documentation","category":"plugin-manifest","format":"markdown","content":"# devtools Documentation\n\nPath: `rb/lib/selenium/devtools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/rb/lib/selenium/devtools/README.md)","tokens":300,"sizeBytes":193}],"systemPromptSnippet":"<yakaai_skills repo=\"SeleniumHQ/selenium\">\n<!-- File: AGENTS.md (Tokens: ~1209 | Category: root-instruction) -->\n<!--\nGuidance for AI agents working in the Selenium monorepo.\nLanguage-specific details live in respective subdirectories.\n-->\n## Overview\n\nSelenium is a Bazel-built monorepo implementing the W3C WebDriver (and related) protocols,\nshipping multiple language bindings plus Grid and Selenium Manager.\nThe repository README is aimed at contributors; end-user docs live elsewhere.\n\n### Local contributor customization\n- The `.local/` directory is available for customization, generated artifacts, scratch work, and temporary files. It is ignored by Git except for `.local/README.md`.\n- A contributor may create `.local/AGENTS.md` for personal repo-specific instructions and preferences. Before beginning any task, check whether `.local/AGENTS.md` exists; if it exists, read it with your file-reading tool and apply it as the contributor's local instruction overlay.\n- If `.local/agent/skills/` exists, inspect its `*/SKILL.md` files and treat them as additional user-defined skills.\n\n## Invariants (don't violate unless explicitly asked)\n- Maintain API/ABI compatibility by default (users upgrade by changing only the version number); public functionality may be removed only after it has gone through the [Deprecation policy](#deprecation-policy) below\n- Avoid repo-wide refactors/formatting; prefer small, reversible diffs\n\n## Toolchain\n- 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.\n- Rakefile tasks are executed with a bundled jruby wrapped with `go`/`go.bat` and frequently used by CI jobs\n- Prefer targeted Bazel commands; use `bazel query ...` to locate labels before build/test\n\n## Execution model\n- Use `bazel query` to explore build graph before reading files\n- 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.\n- 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 after `build`/`test`/`query`).\n\n## Repo layout\nBindings (see `AGENTS.md` in each directory for language-specific details):\n- Java: `java/`\n- Python: `py/`\n- Ruby: `rb/`\n- JavaScript: `javascript/selenium-webdriver/`\n- .NET: `dotnet/`\n\nShared/high-risk areas:\n- `rust/` (Selenium Manager, see `rust/AGENTS.md`)\n- `common/` (build/test wiring; affects multiple areas)\n- `common/src/` (test HTML fixtures)\n- `javascript/atoms/` (shared JS atoms; high blast radius)\n- `scripts/`, `rake_tasks/`, `.github/`, `Rakefile` (tooling/build)\n- `third_party/` treat as read-only\n- `bazel-*/` treat as generated output\n\n## Cross-binding consistency checks\nWhen changing user-visible behavior, compare with at least one other binding:\n- Example: `rg <term> java/ py/ rb/ dotnet/ javascript/selenium-webdriver/`\n\nIf behavior is shared/low-level (protocol, serialization, \"remote\"/transport), suggest follow-up parity work or to file an issue\n\n## Testing\nWhen implementing solutions prefer writing a test for it first \nPrefer small (unit) tests over browser tests for speed/reliability\nAvoid mocks—they can misrepresent API contracts\n\nUseful flags:\n- `--test_size_filters=small` (unit tests only)\n- `--test_output=all` (display console output)\n- `--cache_test_results=no` (force re-run)\nSee language-specific AGENTS.md for applicable testing usage\n\n## Logging\nAdd logging where users may need insight into what's happening\nSee language-specific AGENTS.md for applicable logging usage\n\n## Deprecation policy\nThis project does not follow semantic versioning (semver); before removing public functionality, mark it as deprecated with a message pointing to the alternative.\nSee language-specific AGENTS.md for applicable deprecation usage\n\n## General Guidelines\n- Comments should explain *why*, not *what* - prefer well-named methods over comments\n- PRs should focus on one thing; we squash PRs to default `trunk` branch\n- Prefer copying files to deleting and recreating to maintain git history\n- Avoid running `bazel clean --expunge`\n- Formatting: \n  - `./scripts/format.sh` without arguments will run everything similar to running `./go format` but with failure information; With `--pre-commit` flag it only checks staged changes; With `--pre-push` flag it only checks committed changes with trunk.\n  - If `./scripts/format.sh` is already referenced in a pre-commit or pre-push hook, let the hooks handle formatting \n  - If not, run or suggest `./scripts/format.sh --pre-push` before pushing to avoid CI formatter failures\n\n## High risk changes (request verification before modifying unless explicitly instructed)\n- Everything referenced above as high risk\n- WebDriver/BiDi semantics, capability parsing, wire-level behavior\n- Dependency updates / `MODULE.bazel` / repin flows\n- Grid routing/distributor/queue logic\n\n## After making code changes\n- Call out any high risk areas touched\n- Note cross-binding impact and any follow-up issues needed\n\n## Reviewing pull requests\nSee `.github/pr_review.md` for agentic review priorities and scope.\n\n<!-- File: dotnet/AGENTS.md (Tokens: ~325 | Category: root-instruction) -->\n<!-- Guidance for AI agents working in Selenium .NET Bindings -->\n\n## Code location\n- Core: `dotnet/src/webdriver/`\n- Support: `dotnet/src/support/`\n- Tests: `dotnet/test/common/`\n\n## Common commands\n- Build: `bazel build //dotnet/...`\n\n## Testing\nSee `dotnet/TESTING.md`\n\n## Code conventions\n\n### Logging\n```csharp\nusing OpenQA.Selenium.Internal.Logging;\nprivate static readonly ILogger _logger = Log.GetLogger<MyClass>();\n\n_logger.Warn(\"actionable: something needs attention\");\n_logger.Info(\"useful: driver started successfully\");\n_logger.Debug(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```csharp\n[Obsolete(\"Use NewMethod instead\")]\npublic void OldMethod() { }\n```\nWhen code inside the assembly must still reference an obsolete member (e.g. a field\nor method the obsolete API is built on), wrap just that usage to keep the build\nwarning-clean (see `UserPromptHandler.cs`):\n```csharp\n#pragma warning disable CS0618 // Type or member is obsolete\nthis.legacyThing.DoWork();\n#pragma warning restore CS0618 // Type or member is obsolete\n```\n\n### Async patterns\nThe codebase is migrating to async\n\n### Documentation\nUse XML documentation comments for public APIs:\n```csharp\n/// <summary>\n/// Brief description.\n/// </summary>\n/// <param name=\"name\">Description.</param>\n/// <returns>Description.</returns>\n/// <exception cref=\"ExceptionType\">When condition.</exception>\n```\n\n<!-- File: java/AGENTS.md (Tokens: ~250 | Category: root-instruction) -->\n<!-- Guidance for AI agents working in Selenium Java Bindings and Grid. -->\n\n## Code location\n- Java Bindings: `java/src/`, `java/test/`\n- Grid Server: `java/src/org/openqa/selenium/grid/`\n\n## Common commands\n- Build: `bazel build //java/...`\n- Build Grid: `bazel build grid`\n\n## Testing\nSee `java/TESTING.md`\n\n## Code conventions\n### Interfaces\n- New methods added to existing interfaces must provide a default implementation, if possible.\n- Interfaces must not expose the native classes of their implementations.\n\n### Logging\n```java\nimport java.util.logging.Logger;\nprivate static final Logger LOG = Logger.getLogger(MyClass.class.getName());\n\nLOG.warning(\"actionable: something needs attention\");\nLOG.info(\"useful: server started on port 4444\");\nLOG.fine(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```java\n@Deprecated(forRemoval = true)\npublic void legacyMethod() { }\n```\n\n### Documentation\nUse Javadoc for public APIs:\n```java\n/**\n * Brief description.\n *\n * @param name description\n * @return description\n * @throws ExceptionType when condition\n */\n```\n\n<!-- File: py/AGENTS.md (Tokens: ~480 | Category: root-instruction) -->\n<!-- Guidance for AI agents working in Selenium Python Bindings -->\n\n## Code location\n\n- Package: `py/selenium/`\n- Remote/transport: `py/selenium/webdriver/remote/`\n\n## Common commands\n\n- Build: `bazel build //py/...`\n\n## Testing\n\nRun tests via `bazel test //py/...`. See `/AGENTS.md` for toolchain details.\n\n## Testing\n\nRun tests via `bazel test //py:test-{browser}` or `bazel test //py:test-{browser}-bidi`, where `{browser}` is the target browser (e.g., `chrome`, `firefox`, `edge`). See `/AGENTS.md` for toolchain details.\n\n## Code conventions\n\n### Logging\n\n```python\nlogger = logging.getLogger(__name__)\n\nlogger.warning(\"actionable: something needs attention\")\nlogger.info(\"useful: driver started successfully\")\nlogger.debug(\"diagnostic: request payload for debugging\")\n```\n\n### Deprecation\n\n```python\nwarnings.warn(\n    \"old_method is deprecated, use new_method instead\",\n    DeprecationWarning,\n    stacklevel=2\n)\n```\n\n### Type hints\n\nType hints are used throughout; add type annotations to new code\n\nUse union notation (`|`) instead of `Optional`:\n\n```python\n# Preferred\ndef method(param: str | None) -> int | None:\n    pass\n\n# Avoid\ndef method(param: Optional[str]) -> Optional[int]:\n    pass\n```\n\n### Python version\n\nCode must work with Python 3.10 or later. Use modern syntax features available in 3.10+:\n\n- Use `|` for union types instead of `Union[]`\n- Use `X | None` instead of `Optional[X]`\n\nWhen running tests or code in the terminal, explicitly use `python3.10` or later:\n\n```bash\n# Use explicitly\npython3.10 -c \"...\"\npython3.11 -c \"...\"\n\n# Avoid relying on `python3` as it may be 3.9 or earlier\n```\n\n### Documentation\n\nUse Google-style docstrings:\n\n```python\ndef method(param: str) -> bool:\n    \"\"\"Brief description.\n\n    Args:\n        param: Description of param.\n\n    Returns:\n        Description of return value.\n\n    Raises:\n        ValueError: When condition.\n    \"\"\"\n```\n\n<!-- File: rb/AGENTS.md (Tokens: ~661 | Category: root-instruction) -->\n<!-- Guidance for AI agents working in Selenium Ruby Bindings -->\n\n## Code location\n- Library: `rb/lib/selenium/webdriver`\n- Tests: `rb/spec/unit/` and `rb/spec/integration/`\n- Type signatures: `rb/sig/`\n\n## Common commands\n- Build: `bazel build //rb/...`\n\n## Testing\nSee `rb/TESTING.md`\n\n## Code conventions\n\n### Logging\n```ruby\nWebDriver.logger.warn(\"actionable: something needs attention\", id: :warning_id)\nWebDriver.logger.info(\"useful: driver started successfully\")\nWebDriver.logger.debug(\"diagnostic: request details for debugging\")\n```\n\n### Deprecation\n```ruby\nWebDriver.logger.deprecate(\n  'OldClass#old_method',\n  'NewClass#new_method',\n  id: :old_method\n)\n```\n\n### Internal APIs\nMark internal APIs with `@api private` in YARD comments:\n```ruby\n# @api private\ndef internal_method\nend\n```\n\n### Type signatures (steep/rbs)\nWhen changing public API, update corresponding `.rbs` files in `rb/sig/`\n\n### Documentation\nUse YARD for public APIs:\n```ruby\n# Brief description.\n#\n# @param name [Type] description\n# @return [Type] description\n# @raise [ErrorClass] when condition\n```\n\n## Integration test guards\n\nIntegration specs are guarded by RSpec metadata on `describe`/`context`/`it` (all enclosing\nguards combine). Use one of these five, and always include a `reason:`:\n\n- `skip_if:` — skip when config matches\n- `skip_unless:` — run only when config matches\n- `pending_if:` — expect failure when config matches\n- `pending_unless:` — expect failure unless config matches\n- `flaky:` — `skip_if` reserved for unreliable/intermittent tests\n\nMatching within one Hash = AND (every pair must match); an Array value within a key = OR (matches any\nlisted value). An Array of Hashes lists configs matched independently, and the combined effect depends\non the guard direction: for `skip_if`/`pending_if` the guard triggers if **any** Hash matches (OR); for\n`skip_unless`/`pending_unless` the example is kept only where **all** Hashes match (i.e. it is\nskipped/pended if any does not). The `reason:` is a String or an issue number. Conditions (`browser`,\n`driver`, `platform`, `ci`, etc.) are registered in\n[`spec_helper.rb`](spec/integration/selenium/webdriver/spec_helper.rb).\n\n```ruby\nskip_if: {browser: %i[chrome edge], headless: true, reason: '...'}                   # headless Chrome or Edge\npending_if: [{browser: :firefox, reason: 1234}, {platform: :macosx, reason: 5678}]   # Firefox OR macOS\nskip_unless: [{bidi: false, reason: '...'}, {driver: :remote, reason: '...'}]        # only when non-bidi AND remote\n```\n\n<!-- File: rust/AGENTS.md (Tokens: ~201 | Category: root-instruction) -->\n<!-- Guidance for AI agents working in Selenium Manager code -->\n\n## Code location\n- Source: `rust/src/`\n- Tests: `rust/tests/`\n\n## Common commands\n- Build: `bazel build //rust/...`\n\n## Testing\nSee `rust/TESTING.md`\n\n## Code conventions\n\n### Logging\n```rust\nuse log::{warn, info, debug};\n\nwarn!(\"actionable: something needs attention\");\ninfo!(\"useful: browser resolved successfully\");\ndebug!(\"diagnostic: request details for debugging\");\n```\n\n### Deprecation\n```rust\n#[deprecated(since = \"0.1.0\", note = \"Use new_function instead\")]\npub fn old_function() { }\n```\n\n### Documentation\nUse doc comments for public APIs:\n```rust\n/// Brief description.\n///\n/// # Arguments\n/// * `name` - description\n///\n/// # Returns\n/// Description of return value.\n///\n/// # Errors\n/// Returns `ErrorType` when condition.\n```\n\n<!-- File: common/extensions/webextensions-selenium-example-signed/manifest.json (Tokens: ~133 | Category: anthropic-skill) -->\n{\n  \"manifest_version\": 3,\n  \"name\": \"webextensions-selenium-example\",\n  \"description\": \"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium\",\n  \"version\": \"0.1\",\n  \"content_scripts\": [\n    {\n      \"matches\": [\n        \"https://*/*\",\n        \"http://*/*\"\n      ],\n      \"js\": [\n        \"inject.js\"\n      ]\n    }\n  ],\n  \"browser_specific_settings\": {\n    \"gecko\": {\n      \"id\": \"webextensions-selenium-example-v3@example.com\"\n    }\n  }\n}\n\n<!-- File: common/extensions/webextensions-selenium-example/manifest.json (Tokens: ~171 | Category: anthropic-skill) -->\n{\n  \"manifest_version\": 3,\n  \"name\": \"webextensions-selenium-example\",\n  \"description\": \"Inject a div with id webextensions-selenium-example to verify that WebExtensions work in Firefox/Selenium\",\n  \"version\": \"0.1\",\n  \"content_scripts\": [\n    {\n      \"matches\": [\n        \"https://*/*\",\n        \"http://*/*\"\n      ],\n      \"js\": [\n        \"inject.js\"\n      ]\n    }\n  ],\n  \"permissions\": [\n    \"storage\",\n    \"scripting\"\n  ],\n  \"host_permissions\": [\n    \"https://*/*\",\n    \"http://*/*\"\n  ],\n  \"browser_specific_settings\": {\n    \"gecko\": {\n      \"id\": \"webextensions-selenium-example-v3@example.com\"\n    }\n  }\n}\n\n<!-- File: .github/copilot-instructions.md (Tokens: ~25 | Category: copilot-instructions) -->\nAlways read AGENTS.md before answering\nWhen reviewing a pull request, also follow the guidelines in .github/pr_review.md\n\n<!-- File: common/devtools/README.md (Tokens: ~590 | Category: plugin-manifest) -->\n# Chrome Debugging Protocol\n\nWe keep multiple versions of the protocol in the tree in order to allow us to generate bindings as\nneeded.\n\nThey are typically downloaded from the [devtools source][]\n\nFortunately both Chrome and Edge are based off Chromium releases and those are OSS. In order to get\nthe versions of the protocol spoken by particular releases of Chrome:\n\n* Find out the latest version of [Stable Channel Update for Desktop][] (e.g., `96.0.4664.45`).\n* Create a `vXX` directory under `//common/devtools/chromium` (e.g. `v96` for `96.0.4664.45`)\n* Copy the `BUILD.bazel` file from the `vXX-1` directory.\n* Navigate to the [Chromium source][] and open the tag matching the release number.\n* Find `//third_party/blink/public/devtools_protocol/browser_protocol.pdl` and download the file\n  to `//common/devtools/chromium/vXX`.\n  * (Quick link:\n    `https://raw.githubusercontent.com/chromium/chromium/<LATEST_VERSION_NUMBER>/third_party/blink/public/devtools_protocol/browser_protocol.pdl`)\n* Now figure out the version of v8 used by the version of Chromium. In Chromium's source, navigate\n  to `//:DEPS` and search for `v8_revision`\n  * (Quick\n    link: `https://github.com/chromium/chromium/blob/<LATEST_VERSION_NUMBER>/DEPS#:~:text=the%20commit%20queue%20can%20handle%20cls%20rolling%20v8`)\n* Head over to the [v8 source](https://github.com/v8/v8) and switch to the indicated revision\n  * (e.g., `451d38b60be0a0f692b11815289cf8cbc9b1dc98`)\n* Find `//include/js_protocol.pdl` and download the file to `//common/devtools/chromium/vXX`.\n  (Quick link: `https://github.com/v8/v8/raw/<V8_REVISION_NUMBER>/include/js_protocol.pdl`)\n\nYou may also find the same information at the [OmahaProxy CSV Viewer][]\n\nWe have a modified form of the scripts used by Chromium to generate the protocol files. The\noriginals were in:\n\nhttps://github.com/chromium/chromium/blob/master/third_party/inspector_protocol/convert_protocol_to_json.py\n\n[devtools source]: https://github.com/ChromeDevTools/devtools-protocol/tree/master/json\n\n[Stable Channel Update for Desktop]: https://chromereleases.googleblog.com/search/label/Stable%20updates\n\n[Chromium source]: https://github.com/chromium/chromium/\n\n[OmahaProxy CSV Viewer]: https://omahaproxy.appspot.com\n\n<!-- File: dotnet/src/webdriver/DevTools/README.md (Tokens: ~866 | Category: plugin-manifest) -->\n### Adding support for a new version of Chromium DevTools Protocol to the .NET bindings\n\nTo add support for a new version of the Chromium DevTools Protocol to the .NET bindings,\nperform the following steps, where `<N>` is the major version of the protocol:\n\n1. Add the new version string (`v<N>`) to the `SUPPORTED_DEVTOOLS_VERSIONS` list in\n[`//dotnet:version.bzl`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/version.bzl).\n2. Create a new directory at `//dotnet/src/webdriver/DevTools/v<N>`, and copy the\ncontents of the `//dotnet/src/webdriver/DevTools/v<N-1>` directory into it.\n3. Rename each of the `*.cs` files in `//dotnet/src/webdriver/DevTools/v<N>` so that\nthe file names start with `V<N>` instead of `V<N-1>`.\n4. In each of the `*.cs` files in `//dotnet/src/webdriver/DevTools/v<N>`, update all\noccurrences of `V<N-1>` to `V<N>`. **IMPORTANT:** Do _not_ change the case of `V<N>` in\neach `.cs` file.\n5. In [`//dotnet/src/webdriver/DevTools/DevToolsDomains.cs`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/DevTools/DevToolsDomains.cs),\nadd an entry for version `<N>` to the `SupportedDevToolsVersions` dictionary initialization.\n6. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.cmd`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.cmd),\nadd the following block (substituting the proper value for `<N>`):\n\n```bash\nif not exist  \"%1..\\..\\..\\bazel-bin\\dotnet\\src\\webdriver\\DevTools\\v<N>\\DevToolsSessionDomains.cs\" (\n  echo Generating CDP code for version <N>\n  pushd \"%1..\\..\\..\"\n  bazel build //dotnet/src/webdriver/DevTools:generate-v<N>\n  popd\n)\n```\n\n7. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.sh`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.sh),\nadd the following block (substituting the proper value for `<N>`):\n\n```bash\nif [[ ! -f \"$1../../../bazel-bin/dotnet/src/webdriver/DevTools/v<N>/DevToolsSessionDomains.cs\" ]]\nthen\n  echo \"Generating CDP code for version <N>\"\n  bazel build //dotnet/src/webdriver/DevTools:generate-v<N>\nfi\n```\n\n8. In each of the `*.cs` files in `//dotnet/test/common/DevTools/`, update all\n      occurrences of `V<N-2>` to `V<N-1>`. For now, due to issues with timeliness of CI tool\n      updates, we keep this one version behind the latest.\n9. Commit the changes.\n\n### Removing support for a version of Chromium DevTools Protocol from the .NET bindings\n\nTo remove support for a version of the Chromium DevTools Protocol from the .NET bindings,\nperform the following steps, where `<N>` is the major version of the protocol:\n\n1. Delete the contents of the `//dotnet/src/webdriver/DevTools/v<N>` directory.\n2. In [`//dotnet/src/webdriver/DevTools/DevToolsDomains.cs`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/DevTools/DevToolsDomains.cs),\nremove the entry for version `<N>` from the `SupportedDevToolsVersions` dictionary initialization.\n3. Remove the version string (`v<N>`) from the `SUPPORTED_DEVTOOLS_VERSIONS` list in\n[`//dotnet:version.bzl`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/version.bzl).\n4. Commit the changes.\n\n<!-- File: java/src/org/openqa/selenium/devtools/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# devtools Documentation\n\nPath: `java/src/org/openqa/selenium/devtools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/java/src/org/openqa/selenium/devtools/README.md)\n\n<!-- File: rb/lib/selenium/devtools/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# devtools Documentation\n\nPath: `rb/lib/selenium/devtools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/SeleniumHQ/selenium/HEAD/rb/lib/selenium/devtools/README.md)\n</yakaai_skills>"}