Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Always read AGENTS.md before answering
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,28 @@ javascript/selenium-webdriver/.vscode/settings.json
dotnet-bin
.metadata/
.npmrc

/.local/*
!/.local/.gitkeep

# Security
.env
.env.local

# AI agent local state (most common)
.claude/
.cursor/
.continue/
.cline/
.windsurf/
.zencoder/

# Common per-tool config/rules files people accidentally add
.cursorignore
.cursorrules
.windsurfrules
.continuerc.json

# Common generated transcripts
*_cline_transcript.json
.copilot-chat-history.json
1 change: 1 addition & 0 deletions .local/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

84 changes: 84 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!--
Guidance for AI agents working in the Selenium monorepo.
Language-specific details live in respective subdirectories.
-->

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.

## Invariants (don't violate unless explicitly asked)
- Maintain API/ABI compatibility - users upgrade by changing only version number
- Avoid repo-wide refactors/formatting; prefer small, reversible diffs

## Toolchain
- 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.bat` and frequently used by CI jobs
- Prefer targeted Bazel commands; use `bazel query ...` to locate labels before build/test

## Execution model
- Use `bazel query` to 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.
## Repo layout
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, see `rust/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-only
- `bazel-*/` treat as generated output

### Agent workspace
The `.local/` directory (gitignored) is available for generated artifacts or temporary files:
- Use `--output_base=.local/bazel-out` if bazel output directory restricted
- Check `.local/AGENTS.md` for additional user-specific instructions

## Cross-binding consistency checks
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

## Testing
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

## Logging
Add logging where users may need insight into what's happening
See language-specific AGENTS.md for applicable logging usage

## Deprecation policy
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

## General Guidelines
- Comments should explain *why*, not *what* - prefer well-named methods over comments
- PRs should focus on one thing; we squash PRs to default `trunk` branch
- Prefer copying files to deleting and recreating to maintain git history
- Avoid running `bazel clean --expunge`
- Run or suggest running `./scripts/format.sh` or `./go all:lint` before pushing to prevent CI failures

## High risk changes (request verification before modifying unless explicitly instructed)
- 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

## After making code changes
- Call out any high risk areas touched
- Note cross-binding impact and any follow-up issues needed
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ If you want to use [RubyMine](https://www.jetbrains.com/ruby/) for development,
you can configure it use Bazel artifacts:

1. Open `rb/` as a main project directory.
2. Run `bundle exec rake update` as necessary to create up-to-date artifacts. If this does not work, run `./go rb:update` from the `selenium` (parent) directory.
3. In <kbd>Settings / Languages & Frameworks / Ruby SDK and Gems</kbd> add new <kbd>Interpreter</kbd> pointing to `../bazel-selenium/external/rules_ruby_dist/dist/bin/ruby`.
2. From the `selenium` (parent) directory, run `./go rb:local_dev` to create up-to-date artifacts.
3. In <kbd>Settings / Languages & Frameworks / Ruby SDK and Gems</kbd> add new <kbd>Interpreter</kbd> pointing to `../bazel-selenium/external/rules_ruby++ruby+ruby/dist/bin/ruby`.
4. You should now be able to run and debug any spec. It uses Chrome by default, but you can alter it using environment variables specified in [Ruby Testing](#ruby-2) section below.

### Rust
Expand Down
44 changes: 44 additions & 0 deletions dotnet/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!-- Guidance for AI agents working in Selenium .NET Bindings -->

## Code location
- Core: `dotnet/src/webdriver/`
- Support: `dotnet/src/support/`
- Tests: `dotnet/test/common/`

## Common commands
- Build: `bazel build //dotnet/...`

## Testing
See `dotnet/TESTING.md`

## Code conventions

### Logging
```csharp
using OpenQA.Selenium.Internal.Logging;
private static readonly ILogger _logger = Log.GetLogger<MyClass>();

_logger.Warn("actionable: something needs attention");
_logger.Info("useful: driver started successfully");
_logger.Debug("diagnostic: request details for debugging");
```

### Deprecation
```csharp
[Obsolete("Use NewMethod instead")]
public void OldMethod() { }
```

### Async patterns
The codebase is migrating to async

### Documentation
Use XML documentation comments for public APIs:
```csharp
/// <summary>
/// Brief description.
/// </summary>
/// <param name="name">Description.</param>
/// <returns>Description.</returns>
/// <exception cref="ExceptionType">When condition.</exception>
```
42 changes: 42 additions & 0 deletions java/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!-- Guidance for AI agents working in Selenium Java Bindings and Grid. -->

## Code location
- Java Bindings: `java/src/`, `java/test/`
- Grid Server: `java/src/org/openqa/selenium/grid/`

## Common commands
- Build: `bazel build //java/...`
- Build Grid: `bazel build grid`

## Testing
See `java/TESTING.md`

## Code conventions

### Logging
```java
import java.util.logging.Logger;
private static final Logger LOG = Logger.getLogger(MyClass.class.getName());

LOG.warning("actionable: something needs attention");
LOG.info("useful: server started on port 4444");
LOG.fine("diagnostic: request details for debugging");
```

### Deprecation
```java
@Deprecated(forRemoval = true)
public void legacyMethod() { }
```

### Documentation
Use Javadoc for public APIs:
```java
/**
* Brief description.
*
* @param name description
* @return description
* @throws ExceptionType when condition
*/
```
49 changes: 49 additions & 0 deletions javascript/selenium-webdriver/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!-- Guidance for AI agents working in Selenium JavaScript Bindings -->

## Code location

- Library: `javascript/selenium-webdriver/lib/`
- Tests: `javascript/selenium-webdriver/test/`

## Common commands

- Build: `bazel build //javascript/selenium-webdriver/...`

## Testing

See `javascript/selenium-webdriver/TESTING.md`

## Code conventions

### Logging

```javascript
const logging = require('./logging')
const log_ = logging.getLogger('selenium.webdriver.mymodule')

log_.warning('actionable: something needs attention')
log_.info('useful: driver started successfully')
log_.finer('diagnostic: request details for debugging')
```

### Deprecation

Log a warning directing users to the alternative:

```javascript
log_.warning('oldMethod is deprecated, use newMethod instead')
```

### Documentation

Use JSDoc for public APIs:

```javascript
/**
* Brief description.
*
* @param {Type} name description
* @return {Type} description
* @throws {ErrorType} when condition
*/
```
51 changes: 51 additions & 0 deletions py/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!-- Guidance for AI agents working in Selenium Python Bindings -->

## Code location
- Package: `py/selenium/`
- Remote/transport: `py/selenium/webdriver/remote/`

## Common commands
- Build: `bazel build //py/...`

## Testing
See `py/TESTING.md`

## Code conventions

### Logging
```python
logger = logging.getLogger(__name__)

logger.warning("actionable: something needs attention")
logger.info("useful: driver started successfully")
logger.debug("diagnostic: request payload for debugging")
```

### Deprecation
```python
warnings.warn(
"old_method is deprecated, use new_method instead",
DeprecationWarning,
stacklevel=2
)
```

### Type hints
Type hints are used throughout; add type annotations to new code

### Documentation
Use Google-style docstrings:
```python
def method(param: str) -> bool:
"""Brief description.

Args:
param: Description of param.

Returns:
Description of return value.

Raises:
ValueError: When condition.
"""
```
51 changes: 51 additions & 0 deletions rb/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!-- Guidance for AI agents working in Selenium Ruby Bindings -->

## Code location
- Library: `rb/lib/selenium/webdriver`
- Tests: `rb/spec/unit/` and `rb/spec/integration/`
- Type signatures: `rb/sig/`

## Common commands
- Build: `bazel build //rb/...`

## Testing
See `rb/TESTING.md`

## Code conventions

### Logging
```ruby
WebDriver.logger.warn("actionable: something needs attention", id: :warning_id)
WebDriver.logger.info("useful: driver started successfully")
WebDriver.logger.debug("diagnostic: request details for debugging")
```

### Deprecation
```ruby
WebDriver.logger.deprecate(
'OldClass#old_method',
'NewClass#new_method',
id: :old_method
)
```

### Internal APIs
Mark internal APIs with `@api private` in YARD comments:
```ruby
# @api private
def internal_method
end
```

### Type signatures (steep/rbs)
When changing public API, update corresponding `.rbs` files in `rb/sig/`

### Documentation
Use YARD for public APIs:
```ruby
# Brief description.
#
# @param name [Type] description
# @return [Type] description
# @raise [ErrorClass] when condition
```
Loading