1 - 浏览器选项
这些capabilities用于所有浏览器.
在 Selenium 3 中, capabilities是借助"Desired Capabilities"类定义于会话中的.
从 Selenium 4 开始, 您必须使用浏览器选项类.
对于远程驱动程序会话, 浏览器选项实例是必需的, 因为它确定将使用哪个浏览器.
这些选项在 Capabilities 的 w3c 规范中进行了描述.
每个浏览器都有 自定义选项 , 是规范定义之外的内容.
browserName
此功能用于设置既定会话的 browserName
.
如果未在远端安装指定的浏览器,
则会话创建将失败
browserVersion
此功能是可选的, 用于在远程端设置可用的浏览器版本.
例如, 如果在仅安装80版本的系统上询问75版本的Chrome,
则会话创建将失败
pageLoadStrategy
共有三种类型的页面加载策略.
页面加载策略可以在此链接查询
document.readyState ,
如下表所述:
策略 |
就绪状态 |
备注 |
normal |
complete |
默认值, 等待所有资源下载 |
eager |
interactive |
DOM 访问已准备就绪, 但诸如图像的其他资源可能仍在加载 |
none |
Any |
完全不会阻塞 WebDriver |
文档的 document.readyState
属性描述当前文档的加载状态.
当通过URL导航到新页面时,
默认情况下, WebDriver将暂缓完成导航方法
(例如, driver.navigate().get())直到文档就绪状态完成.
这 并非意味着该页面已完成加载,
特别是对于使用 JavaScript 在就绪状态返回完成后
动态加载内容单页应用程序的站点.
另请注意此行为不适用于单击元素或提交表单后出现的导航行为.
如果由于下载对自动化不重要的资源(例如, 图像、css、js)
而需要很长时间才能加载页面,
您可以将默认参数normal
更改为
eager
或 none
以加快会话加载速度.
此值适用于整个会话,
因此请确保您的 等待策略
足够普适.
normal (默认值)
WebDriver一直等到 load
事件触发并返回.
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
public class pageLoadStrategy {
public static void main(String[] args) {
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
WebDriver driver = new ChromeDriver(chromeOptions);
try {
// Navigate to Url
driver.get("https://google.com");
} finally {
driver.quit();
}
}
}
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.page_load_strategy = 'normal'
driver = webdriver.Chrome(options=options)
driver.get("http://www.google.com")
driver.quit()
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace pageLoadStrategy {
class pageLoadStrategy {
public static void Main(string[] args) {
var chromeOptions = new ChromeOptions();
chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
IWebDriver driver = new ChromeDriver(chromeOptions);
try {
driver.Navigate().GoToUrl("https://example.com");
} finally {
driver.Quit();
}
}
}
}
require 'selenium-webdriver'
options = Selenium::WebDriver::Options.chrome
options.page_load_strategy = :normal
driver = Selenium::WebDriver.for :chrome, options: options
driver.get('https://www.google.com')
it('Navigate using normal page loading strategy', async function () {
let driver = await env
.builder()
.setChromeOptions(options.setPageLoadStrategy('normal'))
.build();
await driver.get('https://www.google.com');
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
fun main() {
val chromeOptions = ChromeOptions()
chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
val driver = ChromeDriver(chromeOptions)
try {
driver.get("https://www.google.com")
}
finally {
driver.quit()
}
}
eager
WebDriver一直等到 DOMContentLoaded
事件触发并返回.
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
public class pageLoadStrategy {
public static void main(String[] args) {
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
WebDriver driver = new ChromeDriver(chromeOptions);
try {
// Navigate to Url
driver.get("https://google.com");
} finally {
driver.quit();
}
}
}
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.page_load_strategy = 'eager'
driver = webdriver.Chrome(options=options)
driver.get("http://www.google.com")
driver.quit()
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace pageLoadStrategy {
class pageLoadStrategy {
public static void Main(string[] args) {
var chromeOptions = new ChromeOptions();
chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
IWebDriver driver = new ChromeDriver(chromeOptions);
try {
driver.Navigate().GoToUrl("https://example.com");
} finally {
driver.Quit();
}
}
}
}
require 'selenium-webdriver'
options = Selenium::WebDriver::Options.chrome
options.page_load_strategy = :eager
driver = Selenium::WebDriver.for :chrome, options: options
driver.get('https://www.google.com')
it('Navigate using eager page loading strategy', async function () {
let driver = await env
.builder()
.setChromeOptions(options.setPageLoadStrategy('eager'))
.build();
await driver.get('https://www.google.com');
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
fun main() {
val chromeOptions = ChromeOptions()
chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
val driver = ChromeDriver(chromeOptions)
try {
driver.get("https://www.google.com")
}
finally {
driver.quit()
}
}
none
WebDriver 仅等待初始页面已下载.
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
public class pageLoadStrategy {
public static void main(String[] args) {
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
WebDriver driver = new ChromeDriver(chromeOptions);
try {
// Navigate to Url
driver.get("https://google.com");
} finally {
driver.quit();
}
}
}
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.page_load_strategy = 'none'
driver = webdriver.Chrome(options=options)
driver.get("http://www.google.com")
driver.quit()
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace pageLoadStrategy {
class pageLoadStrategy {
public static void Main(string[] args) {
var chromeOptions = new ChromeOptions();
chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
IWebDriver driver = new ChromeDriver(chromeOptions);
try {
driver.Navigate().GoToUrl("https://example.com");
} finally {
driver.Quit();
}
}
}
}
require 'selenium-webdriver'
options = Selenium::WebDriver::Options.chrome
options.page_load_strategy = :none
driver = Selenium::WebDriver.for :chrome, options: options
driver.get('https://www.google.com')
it('Navigate using none page loading strategy', async function () {
let driver = await env
.builder()
.setChromeOptions(options.setPageLoadStrategy('none'))
.build();
await driver.get('https://www.google.com');
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
fun main() {
val chromeOptions = ChromeOptions()
chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
val driver = ChromeDriver(chromeOptions)
try {
driver.get("https://www.google.com")
}
finally {
driver.quit()
}
}
这标识了远端的操作系统,
获取 platformName
将返回操作系统的名称.
在基于云的供应者中,
设置 platformName
将在远程端设置操作系统.
acceptInsecureCerts
此功能检查在会话期间导航时
是否使用了过期的 (或) 无效的 TLS Certificate
.
如果将功能设置为 false
,
则页面浏览遇到任何域证书问题时,
将返回insecure certificate error .
如果设置为 true
, 则浏览器将信任无效证书.
默认情况下, 此功能将信任所有自签名证书.
设置后, acceptInsecureCerts
功能将在整个会话中生效.
timeouts
WebDriver session
具有一定的 session timeout
间隔,
在此间隔内, 用户可以控制执行脚本或从浏览器检索信息的行为.
每个会话超时都配置有不同 timeouts
的组合,
如下所述:
Script Timeout:
指定在当前浏览上下文中, 中断正在执行脚本的时机.
WebDriver创建新会话时,
将设置默认的超时时间为 30,000 .
Page Load Timeout:
指定在当前浏览上下文中, 加载网页的时间间隔.
WebDriver创建新会话时,
默认设置超时时间为 300,000 .
如果页面加载限制了给定 (或默认) 的时间范围,
则该脚本将被 TimeoutException 停止.
Implicit Wait Timeout
指定在定位元素时, 等待隐式元素定位策略的时间.
WebDriver创建新会话时,
将设置默认超时时间为 0 .
unhandledPromptBehavior
指定当前会话 user prompt handler
的状态.
默认为 dismiss and notify state .
User Prompt Handler
这定义了在远端出现用户提示时必须采取的措施.
该行为由unhandledPromptBehavior
功能定义,
具有以下状态:
- dismiss
- accept
- dismiss and notify
- accept and notify
- ignore
setWindowRect
用于所有支持 调整大小和重新定位
命令 的远程终端.
strictFileInteractability
新功能用于是否对 类型为文件的输入(input type=file) 元素进行严格的交互性检查.
默认关闭严格性检查,
在将 元素的Send Keys 方法作用于隐藏的文件上传时,
会有控制方面的行为区别.
proxy
代理服务器充当客户端和服务器之间的请求中介.
简述而言, 流量将通过代理服务器流向您请求的地址, 然后返回.
使用代理服务器用于Selenium的自动化脚本,
可能对以下方面有益:
- 捕获网络流量
- 模拟网站后端响应
- 在复杂的网络拓扑结构或严格的公司限制/政策下访问目标站点.
如果您在公司环境中,
并且浏览器无法连接到URL,
则最有可能是因为环境, 需要借助代理进行访问.
Selenium WebDriver提供了如下设置代理的方法
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class proxyTest {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.setHttpProxy("<HOST:PORT>");
ChromeOptions options = new ChromeOptions();
options.setCapability("proxy", proxy);
WebDriver driver = new ChromeDriver(options);
driver.get("https://www.google.com/");
driver.manage().window().maximize();
driver.quit();
}
}
from selenium import webdriver
PROXY = "<HOST:PORT>"
webdriver.DesiredCapabilities.FIREFOX['proxy'] = {
"httpProxy": PROXY,
"ftpProxy": PROXY,
"sslProxy": PROXY,
"proxyType": "MANUAL",
}
with webdriver.Firefox() as driver:
# Open URL
driver.get("https://selenium.dev")
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
# this code was written with Selenium 4
proxy = Selenium::WebDriver::Proxy.new(http: '<HOST:PORT>')
cap = Selenium::WebDriver::Remote::Capabilities.chrome(proxy: proxy)
driver = Selenium::WebDriver.for(:chrome, capabilities: cap)
driver.get('http://google.com')
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();
(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
class proxyTest {
fun main() {
val proxy = Proxy()
proxy.setHttpProxy("<HOST:PORT>")
val options = ChromeOptions()
options.setCapability("proxy", proxy)
val driver: WebDriver = ChromeDriver(options)
driver["https://www.google.com/"]
driver.manage().window().maximize()
driver.quit()
}
}
5 - 远程WebDriver
您可以如本地一样, 使用远程WebDriver.
主要区别在于需要配置远程WebDriver, 以便可以在不同的计算机上运行测试.
远程WebDriver由两部分组成:客户端和服务端. 客户端是您的WebDriver测试,而服务端仅仅是可以被托管于任何现代Java EE应用服务器的Java Servlet.
要运行远程WebDriver客户端, 我们首先需要连接到RemoteWebDriver.
为此, 我们将URL指向运行测试的服务器的地址.
为了自定义我们的配置, 我们设置了既定的功能.
下面是一个实例化样例,
其指向我们的远程Web服务器 www.example.com 的远程WebDriver对象,
并在Firefox上运行测试.
FirefoxOptions firefoxOptions = new FirefoxOptions();
WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), firefoxOptions);
driver.get("http://www.google.com");
driver.quit();
from selenium import webdriver
firefox_options = webdriver.FirefoxOptions()
driver = webdriver.Remote(
command_executor='http://www.example.com',
options=firefox_options
)
driver.get("http://www.google.com")
driver.quit()
FirefoxOptions firefoxOptions = new FirefoxOptions();
IWebDriver driver = new RemoteWebDriver(new Uri("http://www.example.com"), firefoxOptions);
driver.Navigate().GoToUrl("http://www.google.com");
driver.Quit();
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :remote, url: "http://www.example.com", desired_capabilities: :firefox
driver.get "http://www.google.com"
driver.close
const { Builder, Capabilities } = require("selenium-webdriver");
var capabilities = Capabilities.firefox();
(async function helloSelenium() {
let driver = new Builder()
.usingServer("http://example.com")
.withCapabilities(capabilities)
.build();
try {
await driver.get('http://www.google.com');
} finally {
await driver.quit();
}
})();
firefoxOptions = FirefoxOptions()
driver: WebDriver = new RemoteWebDriver(new URL("http://www.example.com"), firefoxOptions)
driver.get("http://www.google.com")
driver.quit()
为了进一步自定义测试配置, 我们可以添加其他既定的功能.
浏览器选项
例如, 假设您想使用Chrome版本67
在Windows XP上运行Chrome:
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "67");
chromeOptions.setCapability("platformName", "Windows XP");
WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.set_capability("browserVersion", "67")
chrome_options.set_capability("platformName", "Windows XP")
driver = webdriver.Remote(
command_executor='http://www.example.com',
options=chrome_options
)
driver.get("http://www.google.com")
driver.quit()
var chromeOptions = new ChromeOptions();
chromeOptions.BrowserVersion = "67";
chromeOptions.PlatformName = "Windows XP";
IWebDriver driver = new RemoteWebDriver(new Uri("http://www.example.com"), chromeOptions);
driver.Navigate().GoToUrl("http://www.google.com");
driver.Quit();
caps = Selenium::WebDriver::Remote::Capabilities.chrome
caps.platform = Windows XP
caps.version = 67
driver = Selenium::WebDriver.for :remote, :url => "http://www.example.com", :desired_capabilities => caps
const { Builder } = require("selenium-webdriver");
const chrome = require("selenium-webdriver/chrome");
let opts = new chrome.Options();
opts.setAcceptInsecureCerts(true);
opts.setBrowserVersion('67');
opts.setPlatform('Windows XP');
(async function helloSelenium() {
let driver = new Builder()
.usingServer("http://example.com")
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get('http://www.google.com');
}
finally {
await driver.quit();
}
})();
val chromeOptions = ChromeOptions()
chromeOptions.setCapability("browserVersion", "67")
chromeOptions.setCapability("platformName", "Windows XP")
val driver: WebDriver = new RemoteWebDriver(new URL("http://www.example.com"), chromeOptions)
driver.get("http://www.google.com")
driver.quit()
本地文件检测器
本地文件检测器允许将文件从客户端计算机传输到远程服务器.
例如, 如果测试需要将文件上传到Web应用程序,
则远程WebDriver可以在运行时
将文件从本地计算机自动传输到远程Web服务器.
这允许从运行测试的远程计算机上载文件.
默认情况下未启用它, 可以通过以下方式启用:
driver.setFileDetector(new LocalFileDetector());
from selenium.webdriver.remote.file_detector import LocalFileDetector
driver.file_detector = LocalFileDetector()
var allowsDetection = this.driver as IAllowsFileDetection;
if (allowsDetection != null)
{
allowsDetection.FileDetector = new LocalFileDetector();
}
@driver.file_detector = lambda do |args|
# args => ["/path/to/file"]
str = args.first.to_s
str if File.exist?(str)
end
var remote = require('selenium-webdriver/remote');
driver.setFileDetector(new remote.FileDetector);
driver.fileDetector = LocalFileDetector()
定义上述代码后,
您可以通过以下方式在测试中上传文件:
driver.get("http://sso.dev.saucelabs.com/test/guinea-file-upload");
WebElement upload = driver.findElement(By.id("myfile"));
upload.sendKeys("/Users/sso/the/local/path/to/darkbulb.jpg");
driver.get("http://sso.dev.saucelabs.com/test/guinea-file-upload")
driver.find_element(By.ID, "myfile").send_keys("/Users/sso/the/local/path/to/darkbulb.jpg")
driver.Navigate().GoToUrl("http://sso.dev.saucelabs.com/test/guinea-file-upload");
IWebElement upload = driver.FindElement(By.Id("myfile"));
upload.SendKeys(@"/Users/sso/the/local/path/to/darkbulb.jpg");
@driver.navigate.to "http://sso.dev.saucelabs.com/test/guinea-file-upload"
element = @driver.find_element(:id, 'myfile')
element.send_keys "/Users/sso/SauceLabs/sauce/hostess/maitred/maitred/public/images/darkbulb.jpg"
driver.get("http://sso.dev.saucelabs.com/test/guinea-file-upload");
var upload = driver.findElement(By.id("myfile"));
upload.sendKeys("/Users/sso/the/local/path/to/darkbulb.jpg");
driver.get("http://sso.dev.saucelabs.com/test/guinea-file-upload")
val upload: WebElement = driver.findElement(By.id("myfile"))
upload.sendKeys("/Users/sso/the/local/path/to/darkbulb.jpg")
追踪客户端请求
此功能仅适用于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版本
及其外部依赖关系版本等更多信息,
请参阅追踪设置 .
更多信息请访问:
Browser specific functionalities
Some browser specific functionalities require workarounds as mentioned in this issue.