-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Enhance Ruby Testing Guide with setup and execution details #16805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: testing_guides
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,24 @@ | ||
| # Ruby Testing Guide | ||
|
|
||
| This guide helps contributors write tests in the Selenium Ruby codebase. | ||
| This guide helps contributors write tests, maintain code style, and generate documentation for the Selenium Ruby bindings. | ||
|
|
||
| ## Local Development Setup | ||
|
|
||
| Before running tests, navigate to the `rb/` directory and install the required dependencies. | ||
|
|
||
| ```shell | ||
| cd rb | ||
| bundle install | ||
|
|
||
| ``` | ||
|
|
||
| ## Test Framework | ||
|
|
||
| * Tests use RSpec. | ||
| * Test HTML pages live in `common/src/web/`. | ||
| * `url_for("page.html")` gets test page URLs. | ||
| * Helper methods: `driver`, `wait`, `short_wait`, `long_wait`. | ||
| * **Runner:** Tests use RSpec. | ||
| * **Test Pages:** HTML files live in `common/src/web/`. | ||
| * **Helpers:** `driver`, `wait`, `short_wait`, `long_wait`, `url_for`. | ||
|
|
||
| ### Example Spec | ||
|
|
||
| ```ruby | ||
| module Selenium | ||
|
|
@@ -24,34 +35,81 @@ module Selenium | |
| end | ||
| end | ||
| end | ||
|
|
||
| ``` | ||
|
|
||
| ## Running Tests | ||
|
|
||
| Bazel creates test targets for each browser and remote variants. | ||
| There are two ways to run tests: **Bazel** (used in CI) and **RSpec** (preferred for local development). | ||
|
|
||
| ### 1. Using Bazel (CI Workflow) | ||
|
|
||
| Bazel creates isolated test targets for each browser and remote variants. | ||
|
|
||
| ```shell | ||
| bazel test //rb/spec/... # All tests | ||
| bazel test //rb/spec/unit/... # Unit tests | ||
| bazel test //rb/spec/... # All tests | ||
| bazel test //rb/spec/unit/... # Unit tests | ||
| bazel test //rb/spec/integration/... --test_tag_filters=chrome # Chrome tests | ||
| bazel test //rb/spec/integration/... --test_tag_filters=firefox # Firefox tests | ||
| bazel test //rb/spec/integration/... --test_tag_filters=chrome-remote # Chrome on Grid | ||
| bazel test //rb/spec/integration/... --test_tag_filters=firefox # Firefox tests | ||
| bazel test //rb/spec/integration/... --test_tag_filters=chrome-remote # Chrome on Grid | ||
|
|
||
| # Viewing Output | ||
| bazel test //rb/... --test_output=all # See console output at the end | ||
| bazel test //rb/... --test_output=streamed # See output in real-time (no parallel execution) | ||
|
|
||
| ``` | ||
|
|
||
| ### 2. Using RSpec (Local Workflow) | ||
|
|
||
| For rapid "edit-run" cycles, use RSpec directly. This bypasses the Bazel sandbox and is faster for local debugging. **Selenium Manager** automatically handles driver setup (chromedriver, geckodriver), so no manual path configuration is required. | ||
|
|
||
| ```shell | ||
| # Run a specific spec file | ||
| bundle exec rspec spec/integration/selenium/webdriver/chrome/driver_spec.rb | ||
|
|
||
| # Run all unit tests | ||
| bundle exec rspec spec/unit | ||
|
|
||
| # Run with specific environment variables | ||
| driver=firefox bundle exec rspec spec/integration/selenium/webdriver/firefox/driver_spec.rb | ||
|
|
||
| ``` | ||
|
|
||
| ### 3. Using Rake | ||
|
|
||
| The `Rakefile` provides shortcuts for common tasks: | ||
|
|
||
| ```shell | ||
| rake spec:unit # Run unit tests | ||
| rake spec:integration # Run integration tests (Chrome default) | ||
| rake docs # Generate docs | ||
| rake clean # Clean generated artifacts | ||
|
||
|
|
||
| # Additional Arguments | ||
| bazel test //rb/... --test_output=all # See console output at the end | ||
| bazel test //rb/... --test_output=streamed # See console output real-time (removes parallel execution) | ||
| ``` | ||
|
|
||
| ## Guards (Test Skipping) | ||
|
|
||
| Guards control when tests run. Add them as metadata on `describe`, `context`, or `it` blocks. | ||
|
|
||
| | Guard | When to Use | | ||
| |-------|-------------| | ||
| | `except` | Test is pending if conditions ARE met | | ||
| | `only` | Test is pending if conditions are NOT met | | ||
| | `exclusive` | Test is skipped entirely if conditions not met | | ||
| | `exclude` | Test is skipped (use for broken/unreliable tests) | | ||
| | --- | --- | | ||
| | `except` | Test is pending if conditions ARE met. | | ||
| | `only` | Test is pending if conditions are NOT met. | | ||
| | `exclusive` | Test is skipped entirely if conditions not met (not pending). | | ||
| | `exclude` | Test is skipped (use for broken/unreliable tests). | | ||
|
|
||
| ### Guard Conditions | ||
aguspe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| | Condition | Values | | ||
| | --- | --- | | ||
| | `browser` | `:chrome`, `:firefox`, `:edge`, `:safari`, `:safari_preview`, `:ie` | | ||
| | `driver` | `:remote` | | ||
| | `platform` | `:linux`, `:macos`, `:windows` | | ||
| | `headless` | `true`, `false` | | ||
| | `bidi` | `true`, `false` | | ||
| | `ci` | `true`, `false` | | ||
|
|
||
| ### Guard Examples | ||
|
|
||
| ```ruby | ||
| # Skip on Safari | ||
|
|
@@ -69,56 +127,57 @@ end | |
| # Multiple conditions | ||
| it 'something', exclude: [ | ||
| {browser: :safari}, | ||
| {browser: :firefox, reason: 'https://github.com/SeleniumHQ/selenium/issues/123'} | ||
| {browser: :firefox, reason: '[https://github.com/SeleniumHQ/selenium/issues/123](https://github.com/SeleniumHQ/selenium/issues/123)'} | ||
| ] do | ||
| end | ||
|
|
||
| ``` | ||
|
|
||
| ### Guard Conditions | ||
| ## Code Style & Linting | ||
|
|
||
| | Condition | Values | | ||
| |-----------|--------| | ||
| | `browser` | `:chrome`, `:firefox`, `:edge`, `:safari`, `:safari_preview`, `:ie` | | ||
| | `driver` | `:remote` | | ||
| | `platform` | `:linux`, `:macos`, `:windows` | | ||
| | `headless` | `true`, `false` | | ||
| | `bidi` | `true`, `false` | | ||
| | `ci` | `true`, `false` | | ||
| Selenium enforces strict code style using **Rubocop**. CI will fail if linting errors are present. | ||
aguspe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ## Helpers | ||
| ```shell | ||
| # Check code style | ||
| bundle exec rubocop | ||
|
|
||
| From `spec_support/helpers.rb`: | ||
| # Auto-correct simple offenses | ||
| bundle exec rubocop -A | ||
|
|
||
| | Helper | Description | | ||
| |--------|-------------| | ||
| | `driver` | Current WebDriver instance | | ||
| | `reset_driver!(...)` | Reset driver with new options | | ||
| | `url_for(filename)` | Get test page URL | | ||
| | `wait` / `short_wait` / `long_wait` | Wait instances (10s, 3s, 30s) | | ||
| | `wait_for_element(locator)` | Wait for element to appear | | ||
| | `wait_for_alert` | Wait for alert presence | | ||
| ``` | ||
|
|
||
| ## Test Organization | ||
| ## Documentation | ||
|
|
||
| We use **YARD** for inline documentation. Ensure your changes are documented and generate valid HTML. | ||
|
|
||
| ```shell | ||
| # Generate documentation | ||
| bundle exec yard doc | ||
|
|
||
| # Run a local documentation server (view at http://localhost:8808) | ||
| bundle exec yard server --reload | ||
|
|
||
| ``` | ||
| rb/spec/ | ||
| ├── unit/ # Unit tests (no browser) | ||
| │ └── selenium/webdriver/ | ||
| └── integration/ # Integration tests | ||
| └── selenium/webdriver/ | ||
| ├── chrome/ | ||
| ├── firefox/ | ||
| ├── safari/ | ||
| ├── bidi/ | ||
| └── spec_support/ # Test helpers | ||
| ``` | ||
|
|
||
| Test files end in `_spec.rb` (e.g., `driver_spec.rb`). | ||
| ## Helpers & Debugging | ||
|
|
||
| ## Build Files | ||
| From `spec_support/helpers.rb`: | ||
|
|
||
| * Adding tests shouldn't require Bazel changes—`rb_integration_test` uses glob patterns. | ||
| * Make sure `*_spec.rb` files are in a directory with a `BUILD.bazel` containing `rb_integration_test`. | ||
| | Helper | Description | | ||
| | --- | --- | | ||
| | `driver` | Current WebDriver instance. | | ||
| | `reset_driver!(...)` | Reset driver with new options. | | ||
| | `url_for(filename)` | Get test page URL (from `common/src/web`). | | ||
| | `wait` / `short_wait` / `long_wait` | Wait instances (10s, 3s, 30s). | | ||
| | `wait_for_element(locator)` | Wait for element to appear. | | ||
| | `wait_for_alert` | Wait for alert presence. | | ||
|
|
||
| ### Debugging | ||
|
|
||
| To debug tests locally (outside of Bazel), insert a breakpoint: | ||
|
|
||
| 1. Add `require 'pry'; binding.pry` in your code. | ||
| 2. Run the test using `bundle exec rspec`. | ||
|
|
||
| ## Environment Variables | ||
|
|
||
|
|
@@ -134,47 +193,41 @@ WD_REMOTE_BROWSER=chrome BIDI=true bazel test //rb/spec/integration/... | |
|
|
||
| # Run BiDi-specific tests | ||
| bazel test //rb/spec/integration/selenium/webdriver/bidi/... | ||
|
|
||
| ``` | ||
|
|
||
| ### Available Variables | ||
| ### Common Variables | ||
|
|
||
| | Variable | Purpose | Values | Example | | ||
| |----------|---------|--------|---------| | ||
| | --- | --- | --- | --- | | ||
| | `BIDI` | Enable BiDi protocol | `true`, `false` | `BIDI=true` | | ||
| | `WD_REMOTE_BROWSER` | Specify browser for remote tests | `chrome`, `firefox`, `edge`, `safari` | `WD_REMOTE_BROWSER=firefox` | | ||
| | `HEADLESS` | Run tests in headless mode | `true`, `false` | `HEADLESS=true` | | ||
| | `DEBUG` | Enable debug logging | `true`, `false` | `DEBUG=true` | | ||
|
|
||
| ### Examples | ||
|
|
||
| ```shell | ||
| # Run Chrome tests with BiDi enabled | ||
| BIDI=true bazel test //rb/spec/integration/... --test_tag_filters=chrome | ||
|
|
||
| # Run headless Firefox tests | ||
| HEADLESS=true bazel test //rb/spec/integration/... --test_tag_filters=firefox | ||
| ## Test Organization | ||
|
|
||
| # Run remote tests on Edge with BiDi | ||
| WD_REMOTE_BROWSER=edge BIDI=true bazel test //rb/spec/integration/... --test_tag_filters=remote | ||
| ```text | ||
| rb/spec/ | ||
| ├── unit/ # Unit tests (no browser) | ||
| │ └── selenium/webdriver/ | ||
| └── integration/ # Integration tests | ||
| └── selenium/webdriver/ | ||
| ├── chrome/ | ||
| ├── firefox/ | ||
| ├── safari/ | ||
| ├── bidi/ | ||
| └── spec_support/ # Test helpers | ||
|
|
||
| # Combine multiple variables | ||
| BIDI=true HEADLESS=true DEBUG=true bazel test //rb/spec/integration/selenium/webdriver/bidi/... | ||
| ``` | ||
|
|
||
| ### Testing Guard Behavior | ||
| Test files must end in `_spec.rb` (e.g., `driver_spec.rb`). | ||
|
|
||
| Environment variables interact with test guards. For example: | ||
| ## Build Files | ||
|
|
||
| ```ruby | ||
| # This test only runs when BiDi is enabled | ||
| it 'uses BiDi feature', only: {bidi: true} do | ||
| # Test code | ||
| end | ||
| * Adding tests shouldn't require Bazel changes—`rb_integration_test` uses glob patterns. | ||
| * Make sure `*_spec.rb` files are in a directory with a `BUILD.bazel` containing `rb_integration_test`. | ||
|
|
||
| # This test is excluded when BiDi is enabled | ||
| it 'classic WebDriver only', exclusive: {bidi: false} do | ||
| # Test code | ||
| end | ||
| ``` | ||
|
|
||
| Run with `BIDI=true` to see these guards in action. | ||
| ``` | ||
Uh oh!
There was an error while loading. Please reload this page.