123456789_123456789_123456789_123456789_123456789_

Selenium

CI

Selenium

Selenium is an umbrella project encapsulating a variety of tools and libraries enabling web browser automation. Selenium specifically provides an infrastructure for the W3C WebDriver specification — a platform and language-neutral coding interface compatible with all major web browsers.

The project is made possible by volunteer contributors who've generously donated thousands of hours in code development and upkeep.

Selenium's source code is made available under the Apache 2.0 license.

Documentation

Narrative documentation:

API documentation:

Pull Requests

Please read [CONTRIBUTING.md]) before submitting your pull requests.

Requirements

Internet Explorer Driver

If you plan to compile the IE driver, you also need:

The build will work on any platform, but the tests for IE will be skipped silently if you are not building on Windows.

Building

Contribute with GitPod

GitPod provides a ready to use environment to develop.

Open in Gitpod

To configure and use your local machine, keep reading.

Bazel

Bazel was built by the fine folks at Google. Bazel manages dependency downloads, generates the Selenium binaries, executes tests, and does it all rather quickly.

More detailed instructions for getting Bazel running are below, but if you can successfully get the java and javascript folders to build without errors, you should be confident that you have the correct binaries on your system.

Before Building

Ensure that you have Firefox installed and the latest geckodriver on your $PATH. You may have to update this from time to time.

Common Build Targets

Java

Click to see Java Build Steps To build the most commonly-used modules of Selenium from source, execute this command from the root project folder: ```sh bazel build java/... ``` If you want to test you can run then you can do so by running the following command ```sh bazel test //java/... --test_size_filters=small,medium,large --test_tag_filters= ``` The test_size_filters argument takes small, medium, large. Small are akin to unit tests, medium is akin to integration tests, and large is akin to end-to-end tests. The test_tag_filters allow us to pass in browser names and a few different tags that we can find in the code base. To build the Grid deployment jar, run this command: ```sh bazel build grid ``` The log will show where the output jar is located.

JavaScript

Click to see JavaScript Build Steps If you want to build all the JavaScript code you can run: ```sh bazel build javascript/... ``` To build the NodeJS bindings you will need to run: ```sh bazel build //javascript/node/selenium-webdriver ``` To run the tests run: ```sh bazel test //javascript/node/selenium-webdriver:tests ``` You can pass in the environment variable SELENIUM_BROWSER with the name of the browser. To publish to NPM run: ```sh bazel run //javascript/node/selenium-webdriver:selenium-webdriver.publish ```

Python

Click to see Python Build Steps If you want to build the python bindings run: ```sh bazel build //py:selenium ``` To run the tests run: ```sh bazel test //py:test- ``` If you add --//common:pin_browsers it will download the browsers and drivers for you to use. To install locally run: ```sh bazel build //py:selenium-wheel pip install bazel-bin/py/selenium-*.whl ``` To publish run: ```sh bazel build //py:selenium-wheel //py:selenium-sdist twine upload bazel-bin/py/selenium-*.whl bazel-bin/py/selenium-*.tar.gz ```

Ruby

Click to see Ruby Build Steps Build targets: | Command | Description | |---------------------------------------------|---------------------------------------------------| | `bazel build //rb:selenium-devtools` | Build selenium-devtools Ruby gem | | `bazel build //rb:selenium-webdriver` | Build selenium-webdriver Ruby gem | | `bazel run //rb:selenium-devtools-release` | Build and push selenium-devtools gem to RubyGems | | `bazel run //rb:selenium-webdriver-release` | Build and push selenium-webdriver gem to RubyGems | | `bazel run //rb:console` | Start REPL with all gems loaded | | `bazel run //rb:docs` | Generate YARD docs | Test targets: | Command | Description | |--------------------------------------------------------------------------------------|------------------------------------------------| | `bazel test //rb/...` | Run unit, integration tests (Chrome) and lint | | `bazel test //rb:lint` | Run RuboCop linter | | `bazel test //rb/spec/...` | Run unit and integration tests (Chrome) | | `bazel test --test_size_filters large //rb/...` | Run integration tests using (Chrome) | | `bazel test //rb/spec/integration/...` | Run integration tests using (Chrome) | | `bazel test //rb/spec/integration/... --define browser=firefox` | Run integration tests using (Firefox) | | `bazel test //rb/spec/integration/... --define remote=true` | Run integration tests using (Chrome and Grid) | | `bazel test //rb/spec/integration/... --define browser=firefox --define remote=true` | Run integration tests using (Firefox and Grid) | | `bazel test --test_size_filters small //rb/...` | Run unit tests | | `bazel test //rb/spec/unit/...` | Run unit tests | Suffix ... tells Bazel to run all the test targets. They are conveniently named by test file name with _spec.rb removed so you can run them individually: | Test file | Test target | |----------------------------------------------------------------|----------------------------------------------------------| | rb/spec/integration/selenium/webdriver/chrome/driver_spec.rb | //rb/spec/integration/selenium/webdriver/chrome:driver | | rb/spec/unit/selenium/webdriver/proxy_spec.rb | //rb/spec/unit/selenium/webdriver:proxy | Supported browsers: * chrome * edge * firefox * ie * safari (cannot be run in parallel - use `--local_test_jobs 1`) * safari-preview (cannot be run in parallel - use `--local_test_jobs 1`) Useful command line options: * `--flaky_test_attempts 3` - re-run failed tests up to 3 times * `--local_test_jobs 1` - control parallelism of tests * --no-cache_test_results, -t- - disable caching of test results and re-runs all of them * `--test_arg "-tfocus"` - test only [focused specs](https://relishapp.com/rspec/rspec-core/v/3-12/docs/filtering/inclusion-filters) * `--test_arg "-eTimeouts"` - test only specs which name include "Timeouts" * `--test_arg ""` - pass any extra RSpec arguments (see `bazel run @bundle//:bin/rspec -- --help`) * `--test_env FOO=bar` - pass extra environment variable to test process (see below for supported variables) * `--test_output all` - print all output from the tests, not just errors * `--test_output streamed` - run all tests one by one and print its output immediately Supported environment variables: - WD_SPEC_DRIVER - the driver to test; either the browser name or 'remote' (gets set by Bazel) - WD_REMOTE_BROWSER - when WD_SPEC_DRIVER is `remote`; the name of the browser to test (gets set by Bazel) - WD_REMOTE_URL - URL of an already running server to use for remote tests - DOWNLOAD_SERVER - when WD_REMOTE_URL not set; whether to download and use most recently released server version for remote tests - DEBUG - turns on verbose debugging - HEADLESS - for chrome, edge and firefox; runs tests in headless mode - DISABLE_BUILD_CHECK - for chrome and edge; whether to ignore driver and browser version mismatches (allows testing Canary builds) - CHROME_BINARY - path to test specific Chrome browser - EDGE_BINARY - path to test specific Edge browser - FIREFOX_BINARY - path to test specific Firefox browser To run with a specific version of Ruby you can change the version in rb/ruby_version.bzl or from command line: ```sh echo 'RUBY_VERSION = ""' > rb/ruby_version.bzl ``` If you want to debug code in tests, you can do it via [`debug`](https://github.com/ruby/debug) gem: 1. Add binding.break to the code where you want the debugger to start. 2. Run tests with ruby_debug configuration: `bazel test --config ruby_debug `. 3. When debugger starts, run the following in a separate terminal to connect to debugger: ```sh bazel-selenium/external/bundle/bin/rdbg -A ``` If you want to use RubyMine for development, a bit of extra configuration is necessary to let the IDE know about Bazel toolchain and artifacts: 1. Run `bazel build @bundle//:bundle //rb:selenium-devtools //rb:selenium-webdriver` before configuring IDE. 2. Open rb/ as a main project directory. 3. In Settings / Languages & Frameworks / Ruby SDK and Gems add new Interpreter pointing to ../bazel-selenium/external/rules_ruby_dist/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 above.

.NET

Click to see .NET Build Steps Bazel can not build .NET, yet, but it can set up tests with: ```sh bazel build //dotnet/test/common:chrome ``` Tests can then be run with: ```sh cd dotnet dotnet test ``` More information about running Selenium's .NET tests can be found in this [README.md](file.README.html)

Rust

Click to see Rust Build Steps Targets: | Command | Description | |---------------------------------------|-------------------------------------| | `bazel build //rust:selenium-manager` | Build selenium-manager binary | | `bazel test //rust/...` | Run both unit and integration tests |

Build Details

Bazel files are called BUILD.bazel, and the order the modules are built is determined by the build system. If you want to build an individual module (assuming all dependent modules have previously been built), try the following:

bazel test javascript/atoms:test

In this case, javascript/atoms is the module directory, test is a target in that directory's BUILD.bazel file.

As you see build targets scroll past in the log, you may want to run them individually.

Build Output

bazel makes a top-level group of directories with the bazel- prefix on each directory.

Common Tasks (Bazel)

To build the bulk of the Selenium binaries from source, run the following command from the root folder:

bazel build java/... javascript/...

To run tests within a particular area of the project, use the "test" command, followed by the folder or target. Tests are tagged with "small", "medium", or "large", and can be filtered with the --test_size_filters option:

bazel test --test_size_filters=small,medium java/...

Bazel's "test" command will run all tests in the package, including integration tests. Expect the test java/... to launch browsers and consume a considerable amount of time and resources.

To bump the versions of the pinned browsers to their latest stable versions:

bazel run scripts:pinned_browsers > temp.bzl && mv temp.bzl common/repositories.bzl

Editing Code

Most of the team use either Intellij IDEA or VS.Code for their day-to-day editing. If you're working in IntelliJ, then we highly recommend installing the Bazel IJ plugin which is documented on its own site.

If you do use IntelliJ and the Bazel plugin, there is a project view checked into the tree in scripts/ij.bazelproject which will make it easier to get up running, and editing code :)

Tour

The codebase is generally segmented around the languages used to write the component. Selenium makes extensive use of JavaScript, so let's start there. First of all, start the development server:

bazel run debug-server

Now, navigate to http://localhost:2310/javascript. You'll find the contents of the javascript/ directory being shown. We use the Closure Library for developing much of the JavaScript, so now navigate to http://localhost:2310/javascript/atoms/test.

The tests in this directory are normal HTML files with names ending with _test.html. Click on one to load the page and run the test.

Help with go

More general, but basic, help for go

./go --help

go is a wrapper around Rake, so you can use the standard commands such as rake -T to get more information about available targets.

Maven per se

Selenium is not built with Maven. It is built with bazel, though that is invoked with go as outlined above, so you do not have to learn too much about that.

That said, it is possible to relatively quickly build Selenium pieces for Maven to use. You are only really going to want to do this when you are testing the cutting-edge of Selenium development (which we welcome) against your application. Here is the quickest way to build and deploy into your local maven repository (~/.m2/repository), while skipping Selenium's own tests.

./go maven-install

The maven jars should now be in your local ~/.m2/repository.

Updating Java dependencies

The coordinates (groupId:artifactId:version) of the Java dependencies are defined in the file maven_deps.bzl. The process to modify these dependencies is the following:

  1. (Optional) If we want to detect the dependencies which are not updated, we can use the following command for automatic discovery:
bazel run @maven//:outdated
  1. Modify maven_deps.bzl. For instance, we can bump the version of a given artifact detected in the step before.

  2. Repin dependencies. This process is required to update the file maven_install.json, which is used to manage the Maven dependencies tree (see rules_jvm_external for further details). The command to carry out this step is the following:

RULES_JVM_EXTERNAL_REPIN=1 bazel run @unpinned_maven//:pin
  1. (Optional) If we use IntelliJ with the Bazel plugin, we need to synchronize our project. To that aim, we click on BazelSyncSync Project with BUILD Files.

Running browser tests on Linux

In order to run Browser tests, you first need to install the browser-specific drivers, such as geckodriver, chromedriver, or edgedriver. These need to be on your PATH.

By default, Bazel runs these tests in your current X-server UI. If you prefer, you can alternatively run them in a virtual or nested X-server.

  1. Run the X server Xvfb :99 or Xnest :99
  2. Run a window manager, for example, DISPLAY=:99 jwm
  3. Run the tests you are interested in: sh bazel test --test_env=DISPLAY=:99 //java/... --test_tag_filters=chrome

An easy way to run tests in a virtual X-server is to use Bazel's --run_under functionality:

bazel test --run_under="xvfb-run -a" //java/... --test_tag_filters=chrome

Bazel Installation/Troubleshooting

Selenium Build Docker Image

If you're finding it hard to set up a development environment using bazel and you have access to Docker, then you can build a Docker image suitable for building and testing Selenium in from the Dockerfile in the dev image directory.

MacOS

bazelisk

Bazelisk is a Mac-friendly launcher for Bazel. To install, follow these steps:

brew tap bazelbuild/tap && \
brew uninstall bazel; \
brew install bazelbuild/tap/bazelisk

Xcode

If you're getting errors that mention Xcode, you'll need to install the command-line tools.

Bazel for Mac requires some additional steps to configure properly. First things first: use the Bazelisk project (courtesy of philwo), a pure golang implementation of Bazel. In order to install Bazelisk, first verify that your Xcode will cooperate: execute the following command:

xcode-select -p

If the value is /Applications/Xcode.app/Contents/Developer/, you can proceed with bazelisk installation. If, however, the return value is /Library/Developer/CommandLineTools/, you'll need to redirect the Xcode system to the correct value.

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer/
sudo xcodebuild -license

The first command will prompt you for a password. The second step requires you to read a new Xcode license, and then accept it by typing "agree".

(Thanks to this thread for these steps)