Remote WebDriver

Selenium lets you automate browsers on remote computers if there is a Selenium Grid running on them. The computer that executes the code is referred to as the client computer, and the computer with the browser and driver is referred to as the remote computer or sometimes as an end-node. To direct Selenium tests to the remote computer, you need to use a Remote WebDriver class and pass the URL including the port of the grid on that machine. Please see the grid documentation for all the various ways the grid can be configured.

Basic Example

The driver needs to know where to send commands to and which browser to start on the Remote computer. So an address and an options instance are both required.

    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
Show full example
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)
Show full example
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
Show full example
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
Show full example
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.get(:latest,
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end

Uploads

Uploading a file is more complicated for Remote WebDriver sessions because the file you want to upload is likely on the computer executing the code, but the driver on the remote computer is looking for the provided path on its local file system. The solution is to use a Local File Detector. When one is set, Selenium will bundle the file, and send it to the remote machine, so the driver can see the reference to it. Some bindings include a basic local file detector by default, and all of them allow for a custom file detector.

Java does not include a Local File Detector by default, so you must always add one to do uploads.
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
Show full example
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}

Python adds a local file detector to remote webdriver instances by default, but you can also create your own class.

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
Show full example
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
.NET adds a local file detector to remote webdriver instances by default, but you can also create your own class.
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
Show full example
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
Ruby adds a local file detector to remote webdriver instances by default, but you can also create your own lambda:
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
Show full example
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.get(:latest,
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end

Downloads

Chrome, Edge and Firefox each allow you to set the location of the download directory. When you do this on a remote computer, though, the location is on the remote computer’s local file system. Selenium allows you to enable downloads to get these files onto the client computer.

Enable Downloads in the Grid

Regardless of the client, when starting the grid in node or standalone mode, you must add the flag:

--enable-managed-downloads true

Enable Downloads in the Client

The grid uses the se:downloadsEnabled capability to toggle whether to be responsible for managing the browser location. Each of the bindings have a method in the options class to set this.

    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
Show full example
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
Show full example
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
Show full example
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
Show full example
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.get(:latest,
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end

List Downloadable Files

Be aware that Selenium is not waiting for files to finish downloading, so the list is an immediate snapshot of what file names are currently in the directory for the given session.

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
Show full example
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
    files = driver.get_downloadable_files()
Show full example
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
Show full example
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
    files = driver.downloadable_files
Show full example
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.get(:latest,
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end

Download a File

Selenium looks for the name of the provided file in the list and downloads it to the provided target directory.

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
Show full example
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
    driver.download_file(downloadable_file, target_directory)
Show full example
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
Show full example
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
    driver.download_file(downloadable_file, target_directory)
Show full example
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.get(:latest,
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end

Delete Downloaded Files

By default, the download directory is deleted at the end of the applicable session, but you can also delete all files during the session.

    ((HasDownloads) driver).deleteDownloadableFiles();
Show full example
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
    driver.delete_downloadable_files()
Show full example
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
Show full example
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
    driver.delete_downloadable_files
Show full example
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.get(:latest,
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end

Browser specific functionalities

Each browser has implemented special functionality that is available only to that browser. Each of the Selenium bindings has implemented a different way to use those features in a Remote Session

Java requires you to use the Augmenter class, which allows it to automatically pull in implementations for all interfaces that match the capabilities used with the RemoteWebDriver

    driver = new Augmenter().augment(driver);
Show full example
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}

Of interest, using the RemoteWebDriverBuilder automatically augments the driver, so it is a great way to get all the functionality by default:

        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
Show full example
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
.NET uses a custom command executor for executing commands that are valid for the given browser in the remote driver.
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
Show full example
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
Ruby uses mixins to add applicable browser specific methods to the Remote WebDriver session; the methods should always just work for you.

Tracing client requests

This feature is only available for Java client binding (Beta onwards). The Remote WebDriver client sends requests to the Selenium Grid server, which passes them to the WebDriver. Tracing should be enabled at the server and client-side to trace the HTTP requests end-to-end. Both ends should have a trace exporter setup pointing to the visualization framework. By default, tracing is enabled for both client and server. To set up the visualization framework Jaeger UI and Selenium Grid 4, please refer to Tracing Setup for the desired version.

For client-side setup, follow the steps below.

Add the required dependencies

Installation of external libraries for tracing exporter can be done using Maven. Add the opentelemetry-exporter-jaeger and grpc-netty dependency in your project pom.xml:

  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>

Add/pass the required system properties while running the client

System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();

  

Please refer to Tracing Setup for more information on external dependencies versions required for the desired Selenium version.

More information can be found at: