This guide helps contributors write tests in the Selenium Java codebase.
JupiterTestBase.common/src/web/.pages field gets URLs from java/test/org/openqa/selenium/testing/Pages.java.class MyFeatureTest extends JupiterTestBase { @Test void testBasicFunctionality() { driver.get(pages.xhtmlTestPage); wait.until(ExpectedConditions.titleIs("XHTML Test Page")); // 10s timeout shortWait.until(ExpectedConditions.elementToBeClickable(element)); // 5s timeout assertThat(driver.getTitle()).isEqualTo("XHTML Test Page"); } @Test void testWithLocalDriver() { localDriver = new ChromeDriver(); localDriver.get(pages.xhtmlTestPage); wait(localDriver).until(ExpectedConditions.titleIs("XHTML Test Page")); // creates 10s wait } }
Bazel creates separate test targets for browsers and remote grid depending on what is supported in the BUILD.bazel file in that test's directory. Tests run in parallel by default.
bazel test //java/... # Run all Java tests bazel test //java/test/org/openqa/selenium/bidi/... # Run all tests in bidi directory bazel test //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest # Run a specific test # Test Filters bazel test //java/... --test_size_filters=small # unit tests only (no browser) bazel test //java/... --test_size_filters=large # all browser tests bazel test //java/... --test_tag_filters=chrome # chrome tests only bazel test //java/... --test_tag_filters=remote-browser # all browser tests that run on grid bazel test //java/... --test_tag_filters=-safari # no safari tests (use `-` to exclude a tag) # Additional Arguments bazel test //java/... --pin_browsers # Use pinned browser versions (recommended) bazel test //java/... --flaky_test_attempts=3 # Rerun failed tests up to 3 times bazel test //java/... --test_output=all # displays all test output at end of run bazel test //java/... --test_output=streamed # displays test output in real time (disables parallel execution)
Valid Browser values: CHROME, EDGE, FIREFOX, SAFARI, IE, ALL. (Default is ALL)
These accept parameters for value (browser name) and reason. Each browser on a separate line.
| Annotation | When to Use |
|---|---|
@Ignore | Test doesn't work for a browser. Also accepts issue (GitHub issue, e.g. "#1234") and gitHubActions (only skip on CI). |
@NotYetImplemented | Feature isn't implemented yet. Test always runs and passes if it fails, and fails if it unexpectedly passes so the annotation can be removed. |
The shared driver is reused across tests for efficiency. These annotations control that behavior. They accept value (browser) and reason.
| Annotation | When to Use |
|---|---|
@NeedsFreshDriver | Test needs clean browser state with default capabilities. Driver is restarted before the test. |
@NoDriverBeforeTest | Test needs custom capabilities or tests driver creation itself. Driver is destroyed, must use createNewDriver(capabilities) in the test to create one. |
@NoDriverAfterTest | Test leaves browser in a bad state. Driver is restarted after the test. Also accepts failedOnly. |
For tests needing two browsers simultaneously (e.g., multi-user scenarios), create a second instance with localDriver = new ChromeDriver(). This driver is automatically quit after the test.
If createNewDriver(capabilities) is called without an annotation, it closes the current driver and creates a new one.
Be careful with hard-coding the creation of new drivers since it may conflict with the current Bazel target.
| Annotation | When to Use |
|---|---|
@SwitchToTopAfterTest | Test navigates into frames. Automatically switches to default content after. |
@NeedsSecureServer | Class-level. All tests in the class need HTTPS. |
*Test.java file is in a directory that has a BUILD.bazel file with a java_selenium_test_suite declaration.