远程WebDriver
如果远程计算机上正在运行 Selenium Grid, 则 Selenium 允许您自动化远程计算机上的浏览器. 执行代码的计算机称为客户端计算机, 具有浏览器和驱动程序的计算机称为远程计算机, 有时也称为终端节点. 要将 Selenium 测试指向到远程计算机, 您需要使用 Remote WebDriver 类并传递包含该机器上网格端口的URL. 请参阅网格文档, 了解配置网格的全部方式.
基本样例
驱动程序需要知道在远程计算机上向何处发送命令, 以及启动哪个浏览器. 所以地址和选项实例都是必需的.
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
上传
对于远程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();
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
((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);
}
}
}
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
下载
Chrome、Edge和Firefox都允许您设置下载目录的位置. 但是, 当您在远程计算机上执行此操作时, 位置在远程计算机的本地文件系统上. Selenium允许您启用下载功能, 将这些文件下载到客户端计算机上.
在网格中启用下载
当以节点或独立模式启动网格时, 你必须添加参数:
--enable-managed-downloads true
在客户端中启用下载
网格使用 se:downloadsEnabled
功能来切换是否负责管理浏览器位置.
每个实现在options类中都有一个方法来设置.
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
列出可下载文件
请注意, Selenium不会等待文件下载完成, 因此, 该列表是给定会话目录中当前文件名的即时快照.
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
下载文件
Selenium在列表中查找提供的文件的名称, 并将其下载到提供的目标目录.
((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
删除已下载的文件
默认情况下, 下载目录在可用会话结束时被删除, 但您也可以在会话期间删除所有文件.
((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
浏览器特定功能
每个浏览器 都实现了仅对该浏览器可用的特殊功能. 每种Selenium实现都实现了在远程会话中使用这些功能的不同方式
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);
}
}
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);
}
}
}
追踪客户端请求
此功能仅适用于Java客户端绑定 (Beta版以后). 远程WebDriver客户端向Selenium网格服务器发送请求, 后者将请求传递给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版本 及其外部依赖关系版本等更多信息, 请参阅追踪设置 .
更多信息请访问: