Skip to content
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

[🚀 Feature]: Switch to remote driver using an environment variable #14451

Open
bonigarcia opened this issue Aug 28, 2024 · 5 comments
Open

Comments

@bonigarcia
Copy link
Member

bonigarcia commented Aug 28, 2024

Feature and motivation

It would be super helpful to have an easy way to switch to using a remote driver instance (RemoteWebDriver) instead of a local driver (for example, ChromeDriver) simply by honoring an environment variable, such as SE_REMOTE_URL or something similar.

Usage example

Imagine I have a Selenium script that uses local Chrome. For example, in Java:

WebDriver driver = new ChromeDriver();

// My logic

driver.quit();

This is how every developer starts using Selenium, and many Selenium tests are based. Now, suppose I want to reuse this script logic but use a remote driver. In that case, I would need to refactor my code to something like:

URL seleniumServerUrl = new URL("http://localhost:4444/");
ChromeOptions options = new ChromeOptions();
WebDriver driver = new RemoteWebDriver(seleniumServerUrl, options);

// My logic

driver.quit();

My vision is to avoid this code refactoring by an external configuration using an environmental variable. This way, a driver instance like WebDriver driver = new ChromeDriver(); but executed in a machine (e.g., a CI server) with an env like SE_REMOTE_URL=http://localhost:4444/ will use a remote browser (Chrome, in this example).

Pros

  • This feature can be a convenient way to remotize existing Selenium scripts/tests that use local browsers. This can be useful for moving tests to more comprehensive infrastructure than the local browsers that provide extra capabilities, such as Selenium Grid or cloud providers (e.g., Sauce Labs, BrowserStack, LambdaTest, etc.).
  • A related improvement is feature proposal [🚀 Feature]: Use self-managed browsers in Docker containers #14452.

Cons

  • This feature should be implemented in each binding, which can be quite a lot of work.
  • The binding I know better is Java. And for that, I am not sure if some changes in the class hierarchy should be done since RemoteWebDriver is a parent of ChromeDriver (and we want ChromeDriver to behave as a RemoteWebDriver in runtime).
@shs96c
Copy link
Member

shs96c commented Aug 28, 2024

var builder = RemoteWebDriver.builder().oneOf(new ChromeOptions());

if (System.getenv("SOME_VAR") != null) {
    builder.address(System.getenv("SOME_VAR"));
}

var driver = builder.build();

@shs96c
Copy link
Member

shs96c commented Aug 28, 2024

The RemoteWebDriverBuilder is the spot where you can implement this. You might want a configureFromEnv method on there?

@bonigarcia
Copy link
Member Author

@shs96c Yes, that approach using the RemoteWebDriver.builder() will definitively work. But my vision is not to touch any line of code and move an existing test (or a test suite) that uses local browsers (which is quite common, I believe) to remote browsers. And that change could be done with some external configuration, such as an env.

Is it worth it? Well, I'm not sure. As I tried to explain, I believe it will be helpful for the Selenium ecosystem since it will allow the reuse of existing tests (without refactoring) to use the extra capabilities provided by a remote infrastructure (such as Grid or cloud vendors).

But I'm aware this kind of change involves work from different people who maintain the bindings, and it can be difficult to do it. That's an idea I had in mind for some time and wanted to share.

@nvborisenko
Copy link
Member

Then configure instantiation of driver instance via json file (just to highlight env variables is not only way to configure something), or yaml, or toml. Given that each driver has own properties/options to be instantiated, then it makes configuration strategy hard. Even if it will be implemented and selenium will honor well-known configuration structure, it will require to write some code, and this code should be customizable.

Seems this is good feature, but the implementation is a candidate to be landed in Support module, which is kind of obsolete/unsupported.

@bonigarcia
Copy link
Member Author

My idea is to configure only the remote URL, not all the capabilities/options. I mean, for example, this piece of code:

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
WebDriver driver = new ChromeDriver();

If the env SE_REMOTE_URL is defined, then the previous code will behave as:

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
WebDriver driver = new RemoteWebDriver(new URL(System.getenv("SE_REMOTE_URL")), options);

Notice that we are reusing the options defined programmatically by the user and using the remote URL defined as an env.

With this approach, when the user does not use options in the driver instantiation (e.g., new ChromeDriver()), then the options will be empty (e.g., new ChromeOptions()) in the RemoteWebDriver object.

But in any case, configuring the capabilities/options in some external manner (e.g., a json or toml file) could also be interesting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants