远程 WebDriver
如果远程计算机上运行着 Selenium Grid,Selenium 允许你在远程计算机上自动化浏览器。执行代码的计算机被称为客户端计算机,而具有浏览器和驱动程序的计算机被称为远程计算机,有时也称为终端节点。要将 Selenium 测试定向到远程计算机,你需要使用 Remote WebDriver 类,并传递包括该机器上 Grid 端口的 URL。请参阅 Grid 文档,了解配置 Grid 的各种方式。
基本示例
驱动程序需要知道将命令发送到哪里以及在远程计算机上启动哪个浏览器。因此,需要地址和选项实例。
ChromeOptions options = new ChromeOptions();
driver = new RemoteWebDriver(gridUrl, options);
options = webdriver.ChromeOptions()
driver = webdriver.Remote(command_executor=server, options=options)
var options = new ChromeOptions();
driver = new RemoteWebDriver(GridUrl, options);
options = Selenium::WebDriver::Options.chrome
driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
上传
对于远程 WebDriver 会话,上传文件更加复杂,因为你要上传的文件可能位于执行代码的计算机上,但远程计算机上的驱动程序在其本地文件系统中查找提供的路径。解决方案是使用本地文件检测器。当设置了本地文件检测器时,Selenium 会捆绑文件并将其发送到远程计算机,以便驱动程序可以看到对其的引用。某些绑定默认包含一个基本的本地文件检测器,并且所有绑定都允许自定义文件检测器。
((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();
Python 默认将本地文件检测器添加到远程 webdriver 实例,但你也可以创建自己的类。
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()
((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
fileInput.SendKeys(uploadFile);
driver.FindElement(By.Id("file-submit")).Click();
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
下载
Chrome、Edge 和 Firefox 都允许你设置下载目录的位置。但是,当你在远程计算机上执行此操作时,该位置位于远程计算机的本地文件系统上。Selenium 允许你启用下载,以将这些文件获取到客户端计算机上。
在 Grid 中启用下载
无论客户端如何,在节点或独立模式下启动 Grid 时,都必须添加标志
--enable-managed-downloads true
在客户端启用下载
Grid 使用 se:downloadsEnabled
功能来切换是否负责管理浏览器位置。每个绑定在 options 类中都有一个方法来设置此项。
ChromeOptions options = new ChromeOptions();
options.setEnableDownloads(true);
driver = new RemoteWebDriver(gridUrl, options);
options = webdriver.ChromeOptions()
options.enable_downloads = True
driver = webdriver.Remote(command_executor=server, options=options)
ChromeOptions options = new ChromeOptions
{
EnableDownloads = true
};
driver = new RemoteWebDriver(GridUrl, options);
options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
列出可下载的文件
请注意,Selenium 不会等待文件完成下载,因此该列表是给定会话的目录中当前文件名的即时快照。
List<String> files = ((HasDownloads) driver).getDownloadableFiles();
files = driver.get_downloadable_files()
IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
files = driver.downloadable_files
下载文件
Selenium 在列表中查找提供的文件名,并将其下载到提供的目标目录。
((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
driver.download_file(downloadable_file, target_directory)
((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
driver.download_file(downloadable_file, target_directory)
删除下载的文件
默认情况下,下载目录在适用的会话结束时删除,但你也可以在会话期间删除所有文件。
((HasDownloads) driver).deleteDownloadableFiles();
driver.delete_downloadable_files()
((RemoteWebDriver)driver).DeleteDownloadableFiles();
driver.delete_downloadable_files
特定于浏览器的功能
每个 浏览器 都实现了仅该浏览器可用的特殊功能。每个 Selenium 绑定都实现了不同的方法来在远程会话中使用这些功能
Java 需要你使用 Augmenter 类,该类允许它自动拉取与 RemoteWebDriver 使用的功能匹配的所有接口的实现
driver = new Augmenter().augment(driver);
值得注意的是,使用 RemoteWebDriverBuilder
会自动增强驱动程序,因此默认情况下它是获取所有功能的好方法
RemoteWebDriver.builder()
.address(gridUrl)
.oneOf(new ChromeOptions())
.setCapability("ext:options", Map.of("key", "value"))
.config(ClientConfig.defaultConfig())
.build();
var customCommandDriver = driver as ICustomDriverCommandExecutor;
customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);
var screenshotResponse = customCommandDriver
.ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
跟踪客户端请求
此功能仅适用于 Java 客户端绑定(Beta 版及更高版本)。远程 WebDriver 客户端向 Selenium Grid 服务器发送请求,该服务器将请求传递给 WebDriver。应在服务器端和客户端启用跟踪,以端到端跟踪 HTTP 请求。两端都应设置指向可视化框架的跟踪导出器。默认情况下,客户端和服务器都启用跟踪。要设置可视化框架 Jaeger UI 和 Selenium Grid 4,请参阅 跟踪设置,以获取所需版本。
对于客户端设置,请按照以下步骤操作。
添加所需的依赖项
可以使用 Maven 安装跟踪导出器的外部库。在你的项目 pom.xml 中添加 opentelemetry-exporter-jaeger 和 grpc-netty 依赖项
<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>
在运行客户端时添加/传递所需的系统属性
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();
请参阅 跟踪设置,了解所需 Selenium 版本所需的外部依赖项版本的更多信息。
更多信息可以在以下位置找到
- OpenTelemetry: https://opentelemetry.io
- 配置 OpenTelemetry: https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure
- Jaeger: https://jaeger.golang.ac.cn
- Selenium Grid 可观测性