|
| 1 | +# 17704. A static `install` method downloads the driver and browser |
| 2 | + |
| 3 | +- Status: Proposed |
| 4 | +- Discussion: https://github.com/SeleniumHQ/selenium/pull/17704 |
| 5 | + |
| 6 | +## Context |
| 7 | + |
| 8 | +By default Selenium Manager doesn't execute until a driver session is being started, so the |
| 9 | +first session pays the download cost for any missing driver or browser, and a missing or |
| 10 | +offline binary isn't discovered until then. |
| 11 | + |
| 12 | +Warming the cache ahead of time is useful whenever that cost or failure should happen at a |
| 13 | +controlled point rather than on first use: provisioning a CI image, a test suite's setup |
| 14 | +step, or simply confirming a binary is available before relying on it. It can be done today, |
| 15 | +but only through the internal `DriverFinder` resolution API, which is shaped differently in |
| 16 | +each binding and not meant as public surface: |
| 17 | + |
| 18 | +| Binding | Current way to trigger an early download | |
| 19 | +|------------|------------------------------------------| |
| 20 | +| Java | `new DriverFinder(service, options).getBrowserPath()` | |
| 21 | +| Python | `DriverFinder(service, options).get_browser_path()` | |
| 22 | +| Ruby | `DriverFinder.new(options, service).browser_path` | |
| 23 | +| .NET | `await new DriverFinder(options).GetBrowserPathAsync()` | |
| 24 | +| JavaScript | `driverFinder.getBinaryPaths(capabilities)` | |
| 25 | + |
| 26 | +This record proposes a convenient public method instead. It does not propose changing |
| 27 | +Selenium Manager behavior. |
| 28 | + |
| 29 | +## Decision |
| 30 | + |
| 31 | +Each binding adds a static `install`, idiomatic in spelling and async per language, on the |
| 32 | +classes whose binaries Selenium Manager can download: |
| 33 | + |
| 34 | +- **On the driver class** (e.g. `Chrome::Driver.install!`, `ChromeDriver.InstallAsync()`): |
| 35 | + downloads the browser and its driver. |
| 36 | +- The driver-class method **accepts an optional options instance**, so a caller can target a |
| 37 | + specific browser version or binary; environment variables alone can't express that. |
| 38 | +- **On the service class** (e.g. `Chrome::Service.install!`): downloads the driver. |
| 39 | + |
| 40 | +Calling it triggers Selenium Manager to download whatever is missing. Default behaviors apply |
| 41 | +and can be adjusted using existing defined environment variables for Selenium Manager (e.g., |
| 42 | +`SE_FORCE_BROWSER_DOWNLOAD`, `SE_SKIP_BROWSER_IN_PATH`, and `SE_SKIP_DRIVER_IN_PATH`). |
| 43 | + |
| 44 | +Returning the resolved paths is a permitted implementation choice, but not the intent: the |
| 45 | +method exists for its side effect, a warmed cache, not for a value callers should depend on. |
| 46 | + |
| 47 | +The method exists only where Selenium Manager downloads the binaries; browsers that use a |
| 48 | +system driver or browser (Safari, IE) don't get it. |
| 49 | + |
| 50 | +## Considered options |
| 51 | + |
| 52 | +- **No public method (Rejected).** Leaves callers reaching into internal APIs. |
| 53 | +- **An instance method (Rejected).** Warming happens before a session exists; a static is |
| 54 | + where users start one. |
| 55 | +- **Defaults only, no options instance (Rejected).** Environment variables can adjust |
| 56 | + download behavior but can't select a specific browser version or binary. |
| 57 | +- **A single method on only the driver or only the service class (Rejected).** Each is the |
| 58 | + natural entry point for the binaries it owns; offering only one makes a caller holding the |
| 59 | + other construct it first. |
| 60 | + |
| 61 | +## Consequences |
| 62 | + |
| 63 | +- Provisioning binaries ahead of a session becomes a supported, one-call operation. |
0 commit comments