这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

WebDriver

WebDriver以原生的方式驱动浏览器; 在此了解更多内容.

WebDriver 以本地化方式驱动浏览器,就像用户在本地或使用 Selenium 服务器的远程机器上所做的那样,这标志着浏览器自动化的飞跃。

Selenium WebDriver 指的是语言绑定和各个浏览器控制代码的实现。 这通常被称为 WebDriver

Selenium WebDriver 是 W3C 推荐标准

  • WebDriver 被设计成一个简单和简洁的编程接口。

  • WebDriver 是一个简洁的面向对象 API。

  • 它能有效地驱动浏览器。

1 - 入门指南

如果你是Selenium的新手, 我们有一些资源帮助你快速入门.

Selenium 通过使用 WebDriver 支持市场上所有主流浏览器的自动化。 WebDriver 是一个 API 和协议,它定义了一个语言中立的接口,用于控制 web 浏览器的行为。 每个浏览器都有一个特定的 WebDriver 实现,称为驱动程序。 驱动程序是负责委派给浏览器的组件,并处理与 Selenium 和浏览器之间的通信。

这种分离是有意识地努力让浏览器供应商为其浏览器的实现负责的一部分。 Selenium 在可能的情况下使用这些第三方驱动程序, 但是在这些驱动程序不存在的情况下,它也提供了由项目自己维护的驱动程序。

Selenium 框架通过一个面向用户的界面将所有这些部分连接在一起, 该界面允许透明地使用不同的浏览器后端, 从而实现跨浏览器和跨平台自动化。

Selenium的设置与其他商业工具有很大不同. 在开始编写 Selenium 代码之前, 您必须安装所选语言的相关类库, 目标浏览器的驱动程序.

请点击以下链接,开始使用 Selenium WebDriver.

如果您希望从低代码/录制和播放工具开始,请查看 Selenium IDE

开始工作后,如果想扩展您的测试,请查看 Selenium Grid.

1.1 - 安装Selenium类库

配置自动化的浏览器.

首先,您需要为自动化项目安装 Selenium 绑定库。 库的安装过程取决于您选择使用的语言。

请求对应的程序语言

查看该库所支持java的最低版本 here.

应熟练掌握build tool以安装支持java的Selenium库

Maven

具体的依赖位于项目中的 pom.xml 文件:

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>

Gradle

具体的依赖位于项目中的 build.gradle 文件中的 testImplementation:

    testImplementation 'org.seleniumhq.selenium:selenium-java:4.27.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.11.3'

该库所支持的Python版本最低版本可以在 支持的Python版本 章节中找到 PyPi

这里提供了几种不同的方式来安装 Selenium .

Pip

pip install selenium

下载

此外你可以从这里下载 PyPI source archive (selenium-x.x.x.tar.gz) 并通过: setup.py 文件安装:

python setup.py install

在项目中使用

为了在项目中使用它,需要将它添加到 requirements.txt 文件中:

selenium==4.27.1

Selenium 所支持的所有平台的列表一览 见诸于 Nuget

该处阐述了一些安装Selenium的选项.

包管理器

Install-Package Selenium.WebDriver

.NET CLI

dotnet add package Selenium.WebDriver

CSProj

csproj 文件里, 具体的依赖 PackageReference(包参数) 位于 ItemGroup (项目组)中:

      <PackageReference Include="Selenium.WebDriver" Version="4.27.0" />

其他附加思虑事项

更多的注意事项,适用于使用 Visual Studio Code (vscode) 和 C#

安装兼容的 .NET SDK 作为章节的先决条件 同时安装 vscode 的扩展 (Ctrl-Shift-X)以适配 C# 和 NuGet 可以遵照此处进行 操作指南 创建 C# 控制台项目并运行 “Hello World”. 你也可以用命令行 dotnet new NUnit 创建NUnit初阶项目. 确保文件 %appdata%\NuGet\nuget.config 已经配置完成,就像某位开发者报告的问题一样,它可能因为某种因素被自动清空. 如果 nuget.config 是空的,或者未配置的,那么 .NET 创建的Selenium项目可能失败. 加入如下章节到文件 nuget.config 如果出现清空的情况:

<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...

更多关于 nuget.config 的信息 点击. 你可能需要按照自己的需求配置 nuget.config .

现在,返回 vscode ,按下 Ctrl-Shift-P, 然后键入 “NuGet Add Package”, 并选择自己需要的 Selenium 包,例如 Selenium.WebDriver. 按下回车并选择版本. 现在你可以使用说明文档中关于 C# vscode下的案例了.

你可以查看 Selenium 对 Ruby 版本支持和最低支持. 具体位于 rubygems.org

Selenium 可以使用两种不同方法安装.

手动安装

gem install selenium-webdriver

加入项目的 gemfile

gem 'selenium-devtools', '= 0.131.0'

You can find the minimum required version of Node for any given version of Selenium in the 你可以在此查看 Selenium 对 Node 的版本支持情况 位于 Node Support Policy 中的相关章节 npmjs

Selenium is typically installed using npm.

本地安装

npm install selenium-webdriver

加入项目

在你的项目 package.json, 必须加入到 dependencies:

        "mocha": "10.8.2"
Use the Java bindings for Kotlin.

下一步

创建你的第一个Selenium脚本

1.2 - 编写第一个Selenium脚本

逐步构建一个Selenium脚本的说明

当你完成 Selenium安装 后, 便可以开始书写Selenium脚本了.

八个基本组成部分

Selenium所做的一切, 就是发送给浏览器命令, 用以执行某些操作或为信息发送请求. 您将使用Selenium执行的大部分操作, 都是以下基本命令的组合

点击 “View full example on GitHub” 的链接以查看上下文中的代码.

1. 使用驱动实例开启会话

关于如何启动会话,请浏览我们的文档 驱动会话

        WebDriver driver = new ChromeDriver();
driver = webdriver.Chrome()
        IWebDriver driver = new ChromeDriver();
driver = Selenium::WebDriver.for :chrome
    driver = await new Builder().forBrowser(Browser.CHROME).build();
        driver = ChromeDriver()

2. 在浏览器上执行操作

在本例中, 我们 导航 到一个网页.

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

3. 请求 浏览器信息

您可以请求一系列关于浏览器的信息 , 包括窗口句柄、浏览器尺寸/位置、cookie、警报等.

        driver.getTitle();
title = driver.title
        var title = driver.Title;
    let title = await driver.getTitle();
        val title = driver.title

4. 建立等待策略

将代码与浏览器的当前状态同步 是Selenium面临的最大挑战之一, 做好它是一个高级主题.

基本上, 您希望在尝试定位元素之前, 确保该元素位于页面上, 并且在尝试与该元素交互之前, 该元素处于可交互状态.

隐式等待很少是最好的解决方案, 但在这里最容易演示, 所以我们将使用它作为占位符.

阅读更多关于等待策略 的信息.

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
driver.implicitly_wait(0.5)
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
driver.manage.timeouts.implicit_wait = 500
    await driver.manage().setTimeouts({implicit: 500});
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

5. 发送命令 查找元素

大多数Selenium会话中的主要命令都与元素相关, 如果不先找到元素, 就无法与之交互.

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

6. 操作元素

对于一个元素, 只有少数几个操作可以执行, 但您将经常使用它们.

        textBox.sendKeys("Selenium");
        submitButton.click();
text_box.send_keys("Selenium")
submit_button.click()
        textBox.SendKeys("Selenium");
        submitButton.Click();
text_box.send_keys('Selenium')
submit_button.click
    await textBox.sendKeys('Selenium');
    await submitButton.click();
        textBox.sendKeys("Selenium")
        submitButton.click()

7. 获取元素信息

元素存储了很多被请求的信息.

        message.getText();
text = message.text
        var value = message.Text;
    let value = await message.getText();
        val value = message.getText()

8. 结束会话

这将结束驱动程序进程, 默认情况下, 该进程也会关闭浏览器. 无法向此驱动程序实例发送更多命令.

详见 Quitting Sessions.

运行 Selenium 文件

mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
pytest path/to/test_script.py
ruby example_script.rb
node example_script.spec.js

接下来的步骤

大多数 Selenium 用户执行许多会话, 需要组织它们以最大限度地减少重复并维持代码更易于维护. 请继续阅读,了解如何将此代码放入您用例的上下文中 使用 Selenium.

1.3 - 组织和执行Selenium代码

使用IDE和Test Runner库组织Selenium的执行

如果你不仅仅只是想执行一小撮的一次性脚本,你需要能组织和安排好你的代码。这一页会启发你如何真正地使用 Selenium 代码做高效的事情。

常见用法

大部分人使用 Selenium 执行针对 Web 应用的自动化测试,但是 Selenium 其实可以支持任何场景的浏览器自动化。

重复性任务

有时候你需要往网站记录日志或者下载一些东西,或者提交一个表单,你可以在预设的时间创建一个 Selenium 脚本去执行一个服务。

网页爬虫

你是否期望从一个不提供 API 的网站收集数据?Selenium 可以满足你,但是请确保你了解该网站的服务条例,因为有些网站不允许你这样做,甚至有些网站会屏蔽 Selenium。

测试

使用 Selenium 做测试需要在 Selenium 执行操作后进行断言,所以一个好的断言类库是很有必要的。至于组织测试用例结构的一些额外特性则需要Test Runner来完成。

IDEs

不管你要用 Selenium 来做什么,没有一个好的集成开发环境,你的工作肯定不会高效。以下是一些常见的 IDE 选择:

Test Runner

即使不使用 Selenium 做测试,如果你有高级用例,使用一个 test runner 去更好地组织你的代码是很有意义的。学会使用 before/after hooks 和分组执行或者并行执行将会非常有用。

待选

有非常多不同的 test runner 可供选择。

这个教程中所有使用到 test runner 的代码示例都可以在我们的示例目录中找到(或者正在被迁移过去),而且这些示例在每一次发版都会被执行,以确保代码是正确的和最新的。下面是一份包含对应链接的 test runner 清单,其中第一项是被这个仓库和本页所有用例所使用的。

  • JUnit - A widely-used testing framework for Java-based Selenium tests.
  • TestNG - Offers extra features like parallel test execution and parameterized tests.
  • pytest - A preferred choice for many, thanks to its simplicity and powerful plugins.
  • unittest - Python’s standard library testing framework.
  • NUnit - A popular unit-testing framework for .NET.
  • MS Test - Microsoft’s own unit testing framework.
  • RSpec - The most widely used testing library for running Selenium tests in Ruby.
  • Minitest - A lightweight testing framework that comes with Ruby standard library.
  • Jest - Primarily known as a testing framework for React, it can also be used for Selenium tests.
  • Mocha - The most common JS library for running Selenium tests.

安装

安装 Selenium 类库一节中详细说明了需要哪些东西。这里的代码只展示在我们的文档示例项目中用到的示例。

Maven

Gradle

To use it in a project, add it to the requirements.txt file:

in the project’s csproj file, specify the dependency as a PackageReference in ItemGroup:

Add to project’s gemfile

In your project’s package.json, add requirement to dependencies:

断言

		String title = driver.getTitle();
		assertEquals("Web form", title);
    title = driver.title
    assert title == "Web form"
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
    title = @driver.title
    expect(title).to eq('Web form')
    let title = await driver.getTitle();
    assert.equal("Web form", title);

Setting Up and Tearing Down

Set Up

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

Tear Down

	@AfterEach
	public void teardown() {
		driver.quit();
	}

Set Up

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

Tear Down

def teardown(driver):
    driver.quit()

Set Up

  before do
    @driver = Selenium::WebDriver.for :chrome
  end

Tear Down

  config.after { @driver&.quit }
### Set Up
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
### Tear Down
  after(async () => await driver.quit());

执行

Maven

mvn clean test

Gradle

gradle clean test
pytest path/to/test_script.py

Mocha

mocha runningTests.spec.js

npx

npx mocha runningTests.spec.js

示例

第一个脚本一节中,我们了解了 Selenium 脚本的每一个组件。这里是使用 test runner 重新组织那个脚本的一个示例:

package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public void teardown() {
		driver.quit();
	}

}
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
# frozen_string_literal: true
require 'spec_helper'
require 'selenium-webdriver'


RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});

下一步

使用你目前所学到的知识建立你自己的 Selenium 代码吧!

想要了解更多的功能特性,请继续阅读我们接下来的WebDriver 教程

2 - 驱动会话

启动和停止会话, 用于打开和关闭浏览器.

创建会话

创建会话对应于W3C的命令 新建会话

会话是通过初始化新的驱动类对象自动创建的.

每种语言都允许使用来自这些类 (或等效类) 之一的参数创建会话:

本地驱动

启动本地驱动的首要唯一参数 包括在本地计算机上有关启动所需驱动服务的信息.

  • 服务 对象仅适用于本地驱动,并提供有关浏览器驱动的信息
    WebDriver driver = new ChromeDriver(chromeOptions);
    driver = webdriver.Chrome(options=options)
            driver = new ChromeDriver(options);
      driver = Selenium::WebDriver.for :chrome, options: options
    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .setChromeOptions(options)
        .setChromeService(service)
        .build();

远程驱动

用于启动远程驱动的首要唯一参数包括有关在何处执行代码的信息. 请浏览 远程驱动章节中的详细信息

退出会话

退出会话对应于W3C的命令 删除会话.

重要提示: quit 方法与 close 方法不同, 建议始终使用 quit 来结束会话

2.1 - 浏览器选项

这些capabilities用于所有浏览器.

在 Selenium 3 中, capabilities是借助"Desired Capabilities"类定义于会话中的. 从 Selenium 4 开始, 您必须使用浏览器选项类. 对于远程驱动程序会话, 浏览器选项实例是必需的, 因为它确定将使用哪个浏览器.

这些选项在 Capabilities 的 w3c 规范中进行了描述.

每个浏览器都有 自定义选项 , 是规范定义之外的内容.

browserName

默认情况下,使用 Options 类实例时会设置浏览器名称.

	ChromeOptions chromeOptions = new ChromeOptions();
	String name = chromeOptions.getBrowserName();
    options = webdriver.ChromeOptions()
    assert options.capabilities['browserName'] == 'chrome'
      options = Selenium::WebDriver::Options.chrome

browserVersion

此功能是可选的,用于在远程端设置可用的浏览器版本. 在最新版本的 Selenium 中,如果在系统上找不到该版本, 它将被 Selenium Manager 自动下载

	ChromeOptions chromeOptions = new ChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
    options = webdriver.ChromeOptions()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
      options.browser_version = 'latest'

pageLoadStrategy

共有三种类型的页面加载策略.

页面加载策略可以在此链接查询 document.readyState , 如下表所述:

策略就绪状态备注
normalcomplete默认值, 等待所有资源下载
eagerinteractiveDOM 访问已准备就绪, 但诸如图像的其他资源可能仍在加载
noneAny完全不会阻塞 WebDriver

文档的 document.readyState 属性描述当前文档的加载状态.

当通过URL导航到新页面时, 默认情况下, WebDriver将暂缓完成导航方法 (例如, driver.navigate().get())直到文档就绪状态完成. 这 并非意味着该页面已完成加载, 特别是对于使用 JavaScript 在就绪状态返回完成后 动态加载内容单页应用程序的站点. 另请注意此行为不适用于单击元素或提交表单后出现的导航行为.

如果由于下载对自动化不重要的资源(例如, 图像、css、js) 而需要很长时间才能加载页面, 您可以将默认参数normal更改为 eagernone 以加快会话加载速度. 此值适用于整个会话, 因此请确保您的 等待策略 足够普适.

normal (默认值)

WebDriver一直等到 load 事件触发并返回.

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    options = webdriver.ChromeOptions()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
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();
      }
    }
  }
}
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
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 事件触发并返回.

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    options = webdriver.ChromeOptions()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
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();
      }
    }
  }
}
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
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 仅等待初始页面已下载.

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    options = webdriver.ChromeOptions()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
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();
      }
    }
  }
}
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
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 将返回操作系统的名称.

在基于云的供应者中, 设置 platformName 将在远程端设置操作系统.

	ChromeOptions chromeOptions = new ChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
    options = webdriver.ChromeOptions()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'

acceptInsecureCerts

此功能检查在会话期间导航时 是否使用了过期的 (或) 无效的 TLS Certificate .

如果将功能设置为 false, 则页面浏览遇到任何域证书问题时, 将返回insecure certificate error . 如果设置为 true, 则浏览器将信任无效证书.

默认情况下, 此功能将信任所有自签名证书. 设置后, acceptInsecureCerts 功能将在整个会话中生效.

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    options = webdriver.ChromeOptions()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

timeouts

WebDriver session 具有一定的 session timeout 间隔, 在此间隔内, 用户可以控制执行脚本或从浏览器检索信息的行为.

每个会话超时都配置有不同 timeouts 的组合, 如下所述:

Script Timeout:

指定在当前浏览上下文中, 中断正在执行脚本的时机. WebDriver创建新会话时, 将设置默认的超时时间为 30,000 .

	ChromeOptions chromeOptions = new ChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
    options = webdriver.ChromeOptions()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

Page Load Timeout:

指定在当前浏览上下文中, 加载网页的时间间隔. WebDriver创建新会话时, 默认设置超时时间为 300,000 . 如果页面加载限制了给定 (或默认) 的时间范围, 则该脚本将被 TimeoutException 停止.

	ChromeOptions chromeOptions = new ChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
    options = webdriver.ChromeOptions()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

Implicit Wait Timeout

指定在定位元素时, 等待隐式元素定位策略的时间. WebDriver创建新会话时, 将设置默认超时时间为 0 .

	ChromeOptions chromeOptions = new ChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
    options = webdriver.ChromeOptions()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

unhandledPromptBehavior

指定当前会话 user prompt handler 的状态. 默认为 dismiss and notify state .

User Prompt Handler

这定义了在远端出现用户提示时必须采取的措施. 该行为由unhandledPromptBehavior 功能定义, 具有以下状态:

  • dismiss
  • accept
  • dismiss and notify
  • accept and notify
  • ignore
	ChromeOptions chromeOptions = new ChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
    options = webdriver.ChromeOptions()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

setWindowRect

用于所有支持 调整大小和重新定位 命令 的远程终端.

   	ChromeOptions chromeOptions = new ChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

strictFileInteractability

新功能用于是否对 类型为文件的输入(input type=file) 元素进行严格的交互性检查. 默认关闭严格性检查, 在将 元素的Send Keys 方法作用于隐藏的文件上传时, 会有控制方面的行为区别.

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
    options = webdriver.ChromeOptions()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

proxy

代理服务器充当客户端和服务器之间的请求中介. 简述而言, 流量将通过代理服务器流向您请求的地址, 然后返回.

使用代理服务器用于Selenium的自动化脚本, 可能对以下方面有益:

  • 捕获网络流量
  • 模拟网站后端响应
  • 在复杂的网络拓扑结构或严格的公司限制/政策下访问目标站点.

如果您在公司环境中, 并且浏览器无法连接到URL, 则最有可能是因为环境, 需要借助代理进行访问.

Selenium WebDriver提供了如下设置代理的方法

Move Code

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();
  }
}
    options = webdriver.ChromeOptions()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
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/");
}
}
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
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()
    }
}

2.2 - HTTP Client Configuration

允许您为HTTP库设置各种参数.

package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

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

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = new ChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
        driver.quit();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = new ChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
        driver.quit();
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = webdriver.ChromeOptions()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = webdriver.ChromeOptions()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30

2.3 - 驱动服务类

服务类用于管理驱动程序的启动和停止. 它们不能与远程 WebDriver 会话一起使用.

服务类允许您指定有关驱动程序的信息, 诸如位置和要使用的端口. 它们还允许您指定传递哪些参数到命令行. 大多数有用的参数都与日志记录有关.

默认服务实例

使用默认服务实例启动驱动程序:

    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);

Selenium v4.11

    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service

驱动程序位置

注意: 如果您使用的是 Selenium 4.6 或更高版本, 则无需设置驱动程序位置. 如果您无法更新 Selenium 或有高阶用法需求, 以下是指定驱动程序位置的方法:

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

Selenium v4.11

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

Selenium v4.9

            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

Selenium v4.8

    service.executable_path = driver_path

驱动程序端口

如果希望驱动程序在特定端口上运行, 您可以在启动时指定端口号, 如下所示:

    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

Selenium v4.11

    service = webdriver.ChromeService(port=1234)
            service.Port = 1234;

日志

日志记录功能因浏览器而异. 大多数浏览器都允许您指定日志的位置和级别. 请查看相应的浏览器页面:

2.4 - 远程WebDriver

如果远程计算机上正在运行 Selenium Grid, 则 Selenium 允许您自动化远程计算机上的浏览器. 执行代码的计算机称为客户端计算机, 具有浏览器和驱动程序的计算机称为远程计算机, 有时也称为终端节点. 要将 Selenium 测试指向到远程计算机, 您需要使用 Remote WebDriver 类并传递包含该机器上网格端口的URL. 请参阅网格文档, 了解配置网格的全部方式.

基本样例

驱动程序需要知道在远程计算机上向何处发送命令, 以及启动哪个浏览器. 所以地址和选项实例都是必需的.

    ChromeOptions options = new ChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    options = webdriver.ChromeOptions()
    driver = webdriver.Remote(command_executor=server, options=options)
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

上传

对于远程WebDriver会话, 上传文件 更为复杂, 因为要上传的文件可能在执行代码的计算机上, 但远程计算机上的驱动程序正在其本地文件系统上查找提供的路径. 解决方案是使用本地文件检测器. 设置一个后, Selenium将捆绑文件, 并将其发送到远程计算机, 以便驱动程序可以看到对它的引用. 默认情况下, 某些实现包含一个基本的本地文件检测器, 并且所有这些实现都允许自定义文件检测器.

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

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()
.NET adds a local file detector to remote webdriver instances by default, but you can also create your own class.
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
Ruby adds a local file detector to remote webdriver instances by default, but you can also create your own lambda:
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

下载

Chrome、Edge和Firefox都允许您设置下载目录的位置. 但是, 当您在远程计算机上执行此操作时, 位置在远程计算机的本地文件系统上. Selenium允许您启用下载功能, 将这些文件下载到客户端计算机上.

在网格中启用下载

当以节点或独立模式启动网格时, 你必须添加参数:

--enable-managed-downloads true

在客户端中启用下载

网格使用 se:downloadsEnabled 功能来切换是否负责管理浏览器位置. 每个实现在options类中都有一个方法来设置.

    ChromeOptions options = new ChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
    options = webdriver.ChromeOptions()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

列出可下载文件

请注意, Selenium不会等待文件下载完成, 因此, 该列表是给定会话目录中当前文件名的即时快照.

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
    files = driver.get_downloadable_files()
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
    files = driver.downloadable_files

下载文件

Selenium在列表中查找提供的文件的名称, 并将其下载到提供的目标目录.

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
    driver.download_file(downloadable_file, target_directory)
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
    driver.download_file(downloadable_file, target_directory)

删除已下载的文件

默认情况下, 下载目录在可用会话结束时被删除, 但您也可以在会话期间删除所有文件.

    ((HasDownloads) driver).deleteDownloadableFiles();
    driver.delete_downloadable_files()
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
    driver.delete_downloadable_files

浏览器特定功能

每个浏览器 都实现了仅对该浏览器可用的特殊功能. 每种Selenium实现都实现了在远程会话中使用这些功能的不同方式

Java 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);

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(new ChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
.NET uses a custom command executor for executing commands that are valid for the given browser in the remote driver.
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
Ruby uses mixins to add applicable browser specific methods to the Remote WebDriver session; the methods should always just work for you.

追踪客户端请求

此功能仅适用于Java客户端绑定 (Beta版以后). 远程WebDriver客户端向Selenium网格服务器发送请求, 后者将请求传递给WebDriver. 应该在服务器端和客户端启用跟踪, 以便端到端地追踪HTTP请求. 两端都应该有一个指向可视化框架的追踪导出器设置. 默认情况下, 对客户端和服务器都启用追踪. 若设置可视化框架Jaeger UI及Selenium Grid 4, 请参阅所需版本的追踪设置 .

对于客户端设置, 请执行以下步骤.

添加所需依赖

可以使用Maven安装追踪导出器的外部库. 在项目pom.xml中添加 opentelemetry-exporter-jaegergrpc-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版本 及其外部依赖关系版本等更多信息, 请参阅追踪设置 .

更多信息请访问:

3 - 支持的浏览器列表

每个浏览器都有定制和特有的功能。

3.1 - Chrome 特定功能

特定于 Google Chrome 浏览器的功能和特性.

默认情况下,Selenium 4与Chrome v75及更高版本兼容. 但是请注意Chrome浏览器的版本与chromedriver的主版本需要匹配.

Options

所有浏览器的通用功能请看这 Options page.

Chrome浏览器的特有功能可以在谷歌的页面找到: Capabilities & ChromeOptions

基于默认选项的Chrome浏览器会话看起来是这样:

    ChromeOptions options = new ChromeOptions();
    driver = new ChromeDriver(options);
    options = webdriver.ChromeOptions()
    driver = webdriver.Chrome(options=options)
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

下面是一些不同功能的常见示例:

参数

args 参数用于启动浏览器时要使用的命令行开关列表. 有两个很好的资源可以用于研究这些参数:

常用的参数包括 --start-maximized, --headless=new 以及 --user-data-dir=...

向选项添加参数:

    options.addArguments("--start-maximized");
    options.add_argument("--start-maximized")
            options.AddArgument("--start-maximized");
      options.args << '--start-maximized'
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

从指定位置启动浏览器

binary 参数接收一个使用浏览器的备用路径,通过这个参数你可以使用chromedriver 去驱动各种基于Chromium 内核的浏览器.

添加一个浏览器地址到选项中:

    options.setBinary(getChromeLocation());
    options.binary_location = chrome_bin
            options.BinaryLocation = GetChromeLocation();
      options.binary = chrome_location
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

添加扩展程序

extensions 参数接受crx文件. 至于解压的目录, 请使用 load-extension 参数代替, 正如 这篇文章 所示.

添加一个扩展程序到选项中:

    options.addExtensions(extensionFilePath);
    options.add_extension(extension_file_path)
            options.AddExtension(extensionFilePath);
      options.add_extension(extension_file_path)
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

保持浏览器的打开状态

detach 参数设置为true将在驱动过程结束后保持浏览器的打开状态.

添加一个布尔值到选项中:

Note: This is already the default behavior in Java.

    options.add_experimental_option("detach", True)

Note: This is already the default behavior in .NET.

      options.detach = true
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

排除的参数

Chrome 添加了各种参数,如果你不希望添加某些参数,可以将其传入 excludeSwitches. 一个常见的例子是重新打开弹出窗口阻止程序. 默认参数的完整列表可以参考 Chromium 源码

设置排除参数至选项中:

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));
    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
            options.AddExcludedArgument("disable-popup-blocking");
      options.exclude_switches << 'disable-popup-blocking'
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

服务

创建默认 Service 对象的示例, 以及用于设置驱动程序位置和端口 可以参考 驱动服务 页面.

日志输出

获取驱动程序日志有助于调试问题. 使用 Service 类, 可以指明日志的路径. 除非用户将其定向到某个位置, 否则将忽略日志记录输出.

文件输出

更改日志记录输出以保存到特定文件:

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

注意: Java 还允许通过系统属性设置文件输出:
属性键: ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY
属性值: 表示日志文件路径的字符串

Selenium v4.11

    service = webdriver.ChromeService(log_output=log_path)
            service.LogPath = GetLogLocation();

命令行输出

更改日志记录输出以在控制台中显示为标准输出:

Selenium v4.10

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

注意: Java 还允许通过系统属性设置控制台输出;
属性键: ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY
属性值: DriverService.LOG_STDOUTDriverService.LOG_STDERR

Selenium v4.11

    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

$stdout and $stderr are both valid values

Selenium v4.10

      service.log = $stdout

日志级别

共有六种日志级别: ALL, DEBUG, INFO, WARNING, SEVERE, 以及 OFF. 注意 --verbose 等效于 --log-level=ALL 以及 --silent 等效于 --log-level=OFF, 因此, 此示例只是通用地设置日志级别:

Selenium v4.8

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

注意: Java 还允许通过系统属性设置日志级别:
属性键: ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY
属性值: ChromiumDriverLogLevel 枚举的字面值

Selenium v4.11

    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

Selenium v4.10

      service.args << '--log-level=DEBUG'

日志文件功能

有 2 个功能仅在写入文件时可用:

  • 追加日志
  • 可读时间戳

要使用它们, 您还需要显式指定日志路径和日志级别. 日志输出将由驱动程序管理, 而不是由进程管理, 因此可能会看到细微的差异.

Selenium v4.8

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

注意: Java 还允许通过系统属性切换这些功能:
属性键: ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY 以及 ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP
属性值: "true""false"

    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

Selenium v4.8

      service.args << '--append-log'
      service.args << '--readable-timestamp'

禁用构建检查

Chromedriver 和 Chrome 浏览器版本应该匹配, 如果它们不匹配, 驱动程序将出错. 如果您停用构建检查功能, 则可以强制将驱动程序与任何版本的 Chrome 一起使用. 请注意, 这是一项不受支持的功能, 并且不会调查 bug.

Selenium v4.8

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

注意: Java 还允许通过系统属性禁用构建检查:
属性键: ChromeDriverService.CHROME_DRIVER_DISABLE_BUILD_CHECK
属性值: "true""false"

Selenium v4.11

    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
            service.DisableBuildCheck = true;

Selenium v4.8

      service.args << '--disable-build-check'

特殊功能

Casting

你可以驱动 Chrome Cast 设备,包括共享选项卡

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end

网络条件

您可以模拟各种网络条件.

以下示例适用于本地 webdrivers. 针对远程 webdrivers, 请参考 Remote WebDriver 页面.

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}

日志

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);
    logs = driver.get_log("browser")
      logs = @driver.logs.get(:browser)

权限

    driver.setPermission("camera", "denied");
    driver.set_permissions('camera', 'denied')
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')

DevTools

详见 Chrome DevTools 部分以获取有关使用Chrome DevTools的更多信息

3.2 - Edge 特定功能

这些是特定于微软Edge浏览器的功能和特性.

微软Edge是用Chromium实现的,最早支持版本是v79. 与Chrome类似, Edge驱动的主版本号必须与Edge浏览器的主要版本匹配.

Chrome 页面 上找到的所有capabilities和选项也适用于Edge.

选项

Capabilities common to all browsers are described on the Options page.

Capabilities unique to Chromium are documented at Google’s page for Capabilities & ChromeOptions

使用基本定义的选项启动 Edge 会话如下所示:

  public void basicOptions() {
    EdgeOptions options = new EdgeOptions();
    options = webdriver.EdgeOptions()
    driver = webdriver.Edge(options=options)
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();

Arguments

The args parameter is for a list of command line switches to be used when starting the browser. There are two excellent resources for investigating these arguments:

Commonly used args include --start-maximized and --headless=new and --user-data-dir=...

Add an argument to options:

    options.add_argument("--start-maximized")
            options.AddArgument("--start-maximized");
      options.args << '--start-maximized'
      .setEdgeOptions(options.addArguments('--headless=new'))

Start browser in a specified location

The binary parameter takes the path of an alternate location of browser to use. With this parameter you can use chromedriver to drive various Chromium based browsers.

Add a browser location to options:

    options.binary_location = edge_bin
            options.BinaryLocation = GetEdgeLocation();
      options.binary = edge_location

Add extensions

The extensions parameter accepts crx files. As for unpacked directories, please use the load-extension argument instead, as mentioned in this post.

Add an extension to options:

    options.add_extension(extension_file_path)
            options.AddExtension(extensionFilePath);
      options.add_extension(extension_file_path)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))

Keeping browser open

Setting the detach parameter to true will keep the browser open after the process has ended, so long as the quit command is not sent to the driver.

Note: This is already the default behavior in Java.

    options.add_experimental_option("detach", True)

Note: This is already the default behavior in .NET.

      options.detach = true
      .setEdgeOptions(options.detachDriver(true))

Excluding arguments

MSEdgedriver has several default arguments it uses to start the browser. If you do not want those arguments added, pass them into excludeSwitches. A common example is to turn the popup blocker back on. A full list of default arguments can be parsed from the Chromium Source Code

Set excluded arguments on options:

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
            options.AddExcludedArgument("disable-popup-blocking");
      options.exclude_switches << 'disable-popup-blocking'
      .setEdgeOptions(options.excludeSwitches('enable-automation'))

Service

Examples for creating a default Service object, and for setting driver location and port can be found on the Driver Service page.

Log output

Getting driver logs can be helpful for debugging issues. The Service class lets you direct where the logs will go. Logging output is ignored unless the user directs it somewhere.

File output

To change the logging output to save to a specific file:

Selenium v4.10

    File logLocation = getTempFile("logsToFile", ".log");

Note: Java also allows setting file output by System Property:
Property key: EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY
Property value: String representing path to log file

    service = webdriver.EdgeService(log_output=log_path)
            service.LogPath = GetLogLocation();

Console output

To change the logging output to display in the console as STDOUT:

Selenium v4.10

Note: Java also allows setting console output by System Property;
Property key: EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY
Property value: DriverService.LOG_STDOUT or DriverService.LOG_STDERR

Selenium v4.11

    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

$stdout and $stderr are both valid values

Selenium v4.10

      service.log = $stdout

Log level

There are 6 available log levels: ALL, DEBUG, INFO, WARNING, SEVERE, and OFF. Note that --verbose is equivalent to --log-level=ALL and --silent is equivalent to --log-level=OFF, so this example is just setting the log level generically:

Selenium v4.8


    EdgeDriverService service =

Note: Java also allows setting log level by System Property:
Property key: EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY
Property value: String representation of ChromiumDriverLogLevel enum

    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

Selenium v4.10

      service.args << '--log-level=DEBUG'

Log file features

There are 2 features that are only available when logging to a file:

  • append log
  • readable timestamps

To use them, you need to also explicitly specify the log path and log level. The log output will be managed by the driver, not the process, so minor differences may be seen.

Selenium v4.8


    EdgeDriverService service =

Note: Java also allows toggling these features by System Property:
Property keys: EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY and EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP
Property value: "true" or "false"

    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

Selenium v4.8

      service.args << '--append-log'
      service.args << '--readable-timestamp'

Disabling build check

Edge browser and msedgedriver versions should match, and if they don’t the driver will error. If you disable the build check, you can force the driver to be used with any version of Edge. Note that this is an unsupported feature, and bugs will not be investigated.

Selenium v4.8


    EdgeDriverService service =

Note: Java also allows disabling build checks by System Property:
Property key: EdgeDriverService.EDGE_DRIVER_DISABLE_BUILD_CHECK
Property value: "true" or "false"

    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)
            service.DisableBuildCheck = true;

Selenium v4.8

      service.args << '--disable-build-check'

Internet Explorer 兼容模式

微软Edge可以被"Internet Explorer兼容模式"驱动, 该模式使用Internet Explorer驱动类与微软Edge结合使用. 阅读 Internet Explorer 页面 了解更多详情.

Special Features

Some browsers have implemented additional features that are unique to them.

Casting

You can drive Chrome Cast devices with Edge, including sharing tabs

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception

Network conditions

You can simulate various network conditions.


    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}

Logs

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);
    logs = driver.get_log("browser")
      logs = @driver.logs.get(:browser)

Permissions

    driver.set_permissions('camera', 'denied')
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')

DevTools

See the [Chrome DevTools] section for more information about using DevTools in Edge

3.3 - Firefox specific functionality

These are capabilities and features specific to Mozilla Firefox browsers.

Selenium 4 requires Firefox 78 or greater. It is recommended to always use the latest version of geckodriver.

Options

Capabilities common to all browsers are described on the Options page.

Capabilities unique to Firefox can be found at Mozilla’s page for firefoxOptions

Starting a Firefox session with basic defined options looks like this:

    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();

Here are a few common use cases with different capabilities:

Arguments

The args parameter is for a list of Command line switches used when starting the browser.
Commonly used args include -headless and "-profile", "/path/to/profile"

Add an argument to options:

    options.addArguments("-headless");
    options.add_argument("-headless")
            options.AddArgument("-headless");
      options.args << '-headless'
      .setFirefoxOptions(options.addArguments('--headless'))

Start browser in a specified location

The binary parameter takes the path of an alternate location of browser to use. For example, with this parameter you can use geckodriver to drive Firefox Nightly instead of the production version when both are present on your computer.

Add a browser location to options:

    options.setBinary(getFirefoxLocation());
    options.binary_location = firefox_bin
            options.BinaryLocation = GetFirefoxLocation();
      options.binary = firefox_location

Profiles

There are several ways to work with Firefox profiles

    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)
var options = new FirefoxOptions();
var profile = new FirefoxProfile();
options.Profile = profile;
var driver = new RemoteWebDriver(options);
  
      profile = Selenium::WebDriver::Firefox::Profile.new
          profile['browser.download.dir'] = '/tmp/webdriver-downloads'
          options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
const { Builder } = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options();
let profile = '/path to custom profile';
options.setProfile(profile);
const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();
  
val options = FirefoxOptions()
options.profile = FirefoxProfile()
driver = RemoteWebDriver(options)
  

Service

Service settings common to all browsers are described on the Service page.

Log output

Getting driver logs can be helpful for debugging various issues. The Service class lets you direct where the logs will go. Logging output is ignored unless the user directs it somewhere.

File output

To change the logging output to save to a specific file:

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

Note: Java also allows setting file output by System Property:
Property key: GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY
Property value: String representing path to log file

Selenium v4.11

    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

Console output

To change the logging output to display in the console:

Selenium v4.10

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

Note: Java also allows setting console output by System Property;
Property key: GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY
Property value: DriverService.LOG_STDOUT or DriverService.LOG_STDERR

Selenium v4.11

    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

Log level

There are 7 available log levels: fatal, error, warn, info, config, debug, trace. If logging is specified the level defaults to info.

Note that -v is equivalent to -log debug and -vv is equivalent to log trace, so this examples is just for setting the log level generically:

Selenium v4.10

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

Note: Java also allows setting log level by System Property:
Property key: GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY
Property value: String representation of FirefoxDriverLogLevel enum

Selenium v4.11

    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

Selenium v4.10

      service.args += %w[--log debug]

Truncated Logs

The driver logs everything that gets sent to it, including string representations of large binaries, so Firefox truncates lines by default. To turn off truncation:

Selenium v4.10

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

Note: Java also allows setting log level by System Property:
Property key: GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE
Property value: "true" or "false"

Selenium v4.11

    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

Selenium v4.10

      service.args << '--log-no-truncate'

Profile Root

The default directory for profiles is the system temporary directory. If you do not have access to that directory, or want profiles to be created some place specific, you can change the profile root directory:

Selenium v4.10

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

Note: Java also allows setting log level by System Property:
Property key: GeckoDriverService.GECKO_DRIVER_PROFILE_ROOT
Property value: String representing path to profile root directory

    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

Selenium v4.8

      service.args += ['--profile-root', root_directory]

Special Features

Add-ons

Unlike Chrome, Firefox extensions are not added as part of capabilities as mentioned in this issue, they are created after starting the driver.

The following examples are for local webdrivers. For remote webdrivers, please refer to the Remote WebDriver page.

Installation

A signed xpi file you would get from Mozilla Addon page

    driver.installExtension(xpiPath);
    driver.install_addon(addon_path_xpi)
            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));
      driver.install_addon(extension_file_path)
    let id = await driver.installAddon(xpiPath);

Uninstallation

Uninstalling an addon requires knowing its id. The id can be obtained from the return value when installing the add-on.

    driver.uninstallExtension(id);
    driver.uninstall_addon(id)

Selenium v4.5

            driver.UninstallAddOn(extensionId);
      driver.uninstall_addon(extension_id)
    await driver.uninstallAddon(id);

Unsigned installation

When working with an unfinished or unpublished extension, it will likely not be signed. As such, it can only be installed as “temporary.” This can be done by passing in either a zip file or a directory, here’s an example with a directory:

    driver.installExtension(path, true);
    driver.install_addon(addon_path_dir, temporary=True)

Selenium v4.5

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

Selenium v4.5

      driver.install_addon(extension_dir_path, true)
    let id = await driver.installAddon(xpiPath, true);

Full page screenshots

The following examples are for local webdrivers. For remote webdrivers, please refer to the Remote WebDriver page.

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);
    driver.save_full_page_screenshot("full_page_screenshot.png")
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

Context

The following examples are for local webdrivers. For remote webdrivers, please refer to the Remote WebDriver page.

    ((HasContext) driver).setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");
    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")
      driver.context = 'content'

3.4 - IE specific functionality

These are capabilities and features specific to Microsoft Internet Explorer browsers.

As of June 2022, Selenium officially no longer supports standalone Internet Explorer. The Internet Explorer driver still supports running Microsoft Edge in “IE Compatibility Mode.”

Special considerations

The IE Driver is the only driver maintained by the Selenium Project directly. While binaries for both the 32-bit and 64-bit versions of Internet Explorer are available, there are some known limitations with the 64-bit driver. As such it is recommended to use the 32-bit driver.

Additional information about using Internet Explorer can be found on the IE Driver Server page

Options

Starting a Microsoft Edge browser in Internet Explorer Compatibility mode with basic defined options looks like this:

        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options

As of Internet Explorer Driver v4.5.0:

  • If IE is not present on the system (default in Windows 11), you do not need to use the two parameters above. IE Driver will use Edge and will automatically locate it.
  • If IE and Edge are both present on the system, you only need to set attaching to Edge, IE Driver will automatically locate Edge on your system.

So, if IE is not on the system, you only need:

        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
let driver = await new Builder()
.forBrowser('internet explorer')
.setIEOptions(options)
.build();
<p><a href=/documentation/about/contributing/#moving-examples>
<span class="selenium-badge-code" data-bs-toggle="tooltip" data-bs-placement="right"
      title="One or more of these examples need to be implemented in the examples directory; click for details in the contribution guide">Move Code</span></a></p>


val options = InternetExplorerOptions()
val driver = InternetExplorerDriver(options)

Here are a few common use cases with different capabilities:

fileUploadDialogTimeout

在某些环境中, 当打开文件上传对话框时, Internet Explorer可能会超时. IEDriver的默认超时为1000毫秒, 但您可以使用fileUploadDialogTimeout功能来增加超时时间.

InternetExplorerOptions options = new InternetExplorerOptions();
options.waitForUploadDialogUpTo(Duration.ofSeconds(2));
WebDriver driver = new RemoteWebDriver(options); 
  
from selenium import webdriver

options = webdriver.IeOptions()
options.file_upload_dialog_timeout = 2000
driver = webdriver.Ie(options=options)

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

driver.quit()
  
var options = new InternetExplorerOptions();
options.FileUploadDialogTimeout = TimeSpan.FromMilliseconds(2000);
var driver = new RemoteWebDriver(options);
  
      @options.file_upload_dialog_timeout = 2000
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().fileUploadDialogTimeout(2000);
let driver = await Builder()
          .setIeOptions(options)
          .build();  
  
val options = InternetExplorerOptions()
options.waitForUploadDialogUpTo(Duration.ofSeconds(2))
val driver = RemoteWebDriver(options)
  

ensureCleanSession

设置为 true时, 此功能将清除InternetExplorer所有正在运行实例的 缓存, 浏览器历史记录和Cookies (包括手动启动或由驱动程序启动的实例) . 默认情况下,此设置为 false.

使用此功能将导致启动浏览器时性能下降, 因为驱动程序将等待直到缓存清除后再启动IE浏览器.

此功能接受一个布尔值作为参数.

InternetExplorerOptions options = new InternetExplorerOptions();
options.destructivelyEnsureCleanSession();
WebDriver driver = new RemoteWebDriver(options);
  
from selenium import webdriver

options = webdriver.IeOptions()
options.ensure_clean_session = True
driver = webdriver.Ie(options=options)

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

driver.quit()
  
var options = new InternetExplorerOptions();
options.EnsureCleanSession = true;
var driver = new RemoteWebDriver(options);
  
      @options.ensure_clean_session = true
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ensureCleanSession(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
val options = InternetExplorerOptions()
options.destructivelyEnsureCleanSession()
val driver = RemoteWebDriver(options)
  

ignoreZoomSetting

InternetExplorer驱动程序期望浏览器的缩放级别为100%, 否则驱动程序将可能抛出异常. 通过将 ignoreZoomSetting 设置为 true, 可以禁用此默认行为.

此功能接受一个布尔值作为参数.

InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings();
WebDriver driver = new RemoteWebDriver(options);
  
from selenium import webdriver

options = webdriver.IeOptions()
options.ignore_zoom_level = True
driver = webdriver.Ie(options=options)

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

driver.quit()
  
var options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
var driver = new RemoteWebDriver(options);
  
      @options.ignore_zoom_level = true
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ignoreZoomSetting(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
val options = InternetExplorerOptions()
options.ignoreZoomSettings()
val driver = RemoteWebDriver(options)
  

ignoreProtectedModeSettings

启动新的IE会话时是否跳过 保护模式 检查.

如果未设置, 并且所有区域的 保护模式 设置都不同, 则驱动程序将可能引发异常.

如果将功能设置为 true, 则测试可能会变得不稳定, 无响应, 或者浏览器可能会挂起. 但是, 到目前为止, 这仍然是第二好的选择, 并且第一选择应该 始终 是手动实际设置每个区域的保护模式设置. 如果用户正在使用此属性, 则只会给予 “尽力而为” 的支持.

此功能接受一个布尔值作为参数.

InternetExplorerOptions options = new InternetExplorerOptions();
options.introduceFlakinessByIgnoringSecurityDomains();
WebDriver driver = new RemoteWebDriver(options);
  
from selenium import webdriver

options = webdriver.IeOptions()
options.ignore_protected_mode_settings = True
driver = webdriver.Ie(options=options)

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

driver.quit()
  
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
var driver = new RemoteWebDriver(options);
  
      @options.ignore_protected_mode_settings = true
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().introduceFlakinessByIgnoringProtectedModeSettings(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
val options = InternetExplorerOptions()
options.introduceFlakinessByIgnoringSecurityDomains()
val driver = RemoteWebDriver(options)
  

silent

设置为 true时, 此功能将禁止IEDriverServer的诊断输出.

此功能接受一个布尔值作为参数.

InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("silent", true);
WebDriver driver = new InternetExplorerDriver(options);
  
from selenium import webdriver

options = webdriver.IeOptions()
options.set_capability("silent", True)
driver = webdriver.Ie(options=options)

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

driver.quit()
  
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalInternetExplorerOption("silent", true);
IWebDriver driver = new InternetExplorerDriver(options);
  
      @options.silent = true
const {Builder,By, Capabilities} = require('selenium-webdriver');
let caps = Capabilities.ie();
caps.set('silent', true);

(async function example() {
    let driver = await new Builder()
        .forBrowser('internet explorer')
        .withCapabilities(caps)
        .build();
    try {
        await driver.get('http://www.google.com/ncr');
    }
    finally {
        await driver.quit();
    }
})();
  
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.setCapability("silent", true)
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  

IE 命令行选项

Internet Explorer包含几个命令行选项, 使您可以进行故障排除和配置浏览器.

下面介绍了一些受支持的命令行选项

  • -private : 用于在私有浏览模式下启动IE. 这适用于IE 8和更高版本.

  • -k : 在kiosk模式下启动Internet Explorer. 浏览器在一个最大化的窗口中打开, 该窗口不显示地址栏, 导航按钮或状态栏.

  • -extoff : 在无附加模式下启动IE. 此选项专门用于解决浏览器加载项问题. 在IE 7和更高版本中均可使用.

注意: forceCreateProcessApi 应该启用命令行参数才能正常工作.

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        options.addCommandSwitches("-k");
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
from selenium import webdriver

options = webdriver.IeOptions()
options.add_argument('-private')
options.force_create_process_api = True
driver = webdriver.Ie(options=options)

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

driver.quit()
  
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   options.BrowserCommandLineArguments = "-k";
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
      @options.add_argument('-k')
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.addBrowserCommandSwitches('-k');
options.addBrowserCommandSwitches('-private');
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    options.addCommandSwitches("-k")
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  

forceCreateProcessApi

强制使用CreateProcess API启动Internet Explorer. 默认值为false.

对于IE 8及更高版本, 此选项要求将 “TabProcGrowth” 注册表值设置为0.

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
from selenium import webdriver

options = webdriver.IeOptions()
options.force_create_process_api = True
driver = webdriver.Ie(options=options)

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

driver.quit()
  
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
      @options.force_create_process_api = true
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  

Service

Service settings common to all browsers are described on the Service page.

Log output

Getting driver logs can be helpful for debugging various issues. The Service class lets you direct where the logs will go. Logging output is ignored unless the user directs it somewhere.

File output

To change the logging output to save to a specific file:

Selenium v4.10

                .withLogFile(getLogLocation())

Note: Java also allows setting file output by System Property:
Property key: InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY
Property value: String representing path to log file

    service = webdriver.IeService(log_output=log_path, log_level='INFO')

Console output

To change the logging output to display in the console as STDOUT:

Selenium v4.10

                .withLogOutput(System.out)

Note: Java also allows setting console output by System Property;
Property key: InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY
Property value: DriverService.LOG_STDOUT or DriverService.LOG_STDERR

Selenium v4.11

    service = webdriver.IeService(log_output=subprocess.STDOUT)

Log Level

There are 6 available log levels: FATAL, ERROR, WARN, INFO, DEBUG, and TRACE If logging output is specified, the default level is FATAL

                .withLogLevel(InternetExplorerDriverLogLevel.WARN)

Note: Java also allows setting log level by System Property:
Property key: InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY
Property value: String representation of InternetExplorerDriverLogLevel.DEBUG.toString() enum

    service = webdriver.IeService(log_output=log_path, log_level='WARN')

Selenium v4.10

      service.args << '-log-level=WARN'

Supporting Files Path

                .withExtractPath(getTempDirectory())
**Note**: Java also allows setting log level by System Property:\ Property key: `InternetExplorerDriverService.IE_DRIVER_EXTRACT_PATH_PROPERTY`\ Property value: String representing path to supporting files directory

Selenium v4.11

    service = webdriver.IeService(service_args=["–extract-path="+temp_dir])

Selenium v4.8

      service.</