Selenium 是一个伞式项目,封装了各种支持 Web 浏览器自动化的工具和库。 Selenium 专门为 W3C WebDriver 规范提供了基础设施——与所有主要 Web 浏览器兼容的平台和语言中立的编码接口。
该项目是由志愿者贡献者实现的,他们慷慨地贡献了数千个小时的代码开发和维护时间。
Selenium 的源代码在 Apache 2.0 许可证下提供。
本自述文件适用于有兴趣为该项目做出贡献的开发人员。对于想要开始使用 Selenium 的人,请查看我们的用户手册以获取详细的示例和说明,如果您遇到困难,可以通过多种方式获取帮助。
请在提交拉取请求之前阅读 CONTRIBUTING.md。
这些是创建您自己的本地开发环境以对 Selenium 做出贡献的要求。
Bazelisk,一个 Bazel 包装器,它自动下载.bazelversion
文件中指定的 Bazel 版本,并透明地将所有命令行参数传递给真正的 Bazel 二进制文件。
Java JDK 版本 17 或更高版本(例如 Java 17 Temurin)
将JAVA_HOME
环境变量设置为 Java 可执行文件的位置(JDK 而不是 JRE)
要测试这一点,请尝试运行命令javac
。如果您只安装了 JRE,则此命令将不存在。如果您遇到命令行选项列表,则说明您正确引用了 JDK。
Xcode 包括命令行工具。使用以下命令安装最新版本: xcode-select --install
适用于 Apple Silicon Mac 的 Rosetta。将build --host_platform=//:rosetta
添加到.bazelrc.local
文件中。我们正在努力确保从长远来看不需要这样做。
几年前,Jim Evans 发表了一篇关于为 Selenium .NET 语言绑定设置 Windows 开发环境的精彩文章;本文已过时,但其中包含更详细的描述和屏幕截图,某些人可能会觉得有用。
该脚本将确保开发人员环境完全准备好执行。 (除非另有提示,否则不会安装或设置已存在的任何内容)
以管理员身份打开 Powershell
执行: Set-ExecutionPolicy Bypass -Scope Process -Force
允许在进程中运行脚本
导航到要在其中克隆 Selenium 的目录,或已克隆的 Selenium 存储库的父目录
在 powershell 终端中下载并执行此脚本:[scripts/dev-environment-setup.ps1]`
一般允许在 Selenium 中运行脚本:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
启用开发者模式:
reg add "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionAppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
安装 MSYS2,这是一个提供类 Unix 命令的替代 shell 环境
将 bin 目录添加到PATH
环境变量(例如"C:toolsmsys64usrbin"
)
将bash.exe
位置添加为BAZEL_SH
环境变量(例如, "C:toolsmsys64usrbinbash.exe"
)
安装最新版本的 Visual Studio Community
使用 Visual Studio 安装程序修改并添加“使用 C++ 进行桌面开发”工作负载
将 Visual C++ 构建工具安装目录位置添加到BAZEL_VC
环境变量(例如"C:Program FilesMicrosoft Visual Studio2022CommunityVC"
)
将 Visual C++ 构建工具版本添加到BAZEL_VC_FULL_VERSION
环境变量(可以从"$BAZEL_VCToolsMSVC
中的目录名称找到)
添加对长文件名的支持(bazel 有很多嵌套目录,可能超出 Windows 中的默认限制)
reg add "HKEY_LOCAL_MACHINESOFTWAREMicrosoftCommand Processor" /t REG_DWORD /f /v "DisableUNCCheck" /d "1"reg add "HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlFileSystem" /t REG_DWORD /f /v "LongPathsEnabled" /d "1"
创建文件selenium/.bazelrc.windows.local
将“startup --output_user_root=C:/tmp”添加到文件中
允许 Bazel 创建长文件路径的短名称版本: fsutil 8dot3name set 0
将 bazel 输出设置为C:/tmp
而不是嵌套在项目目录中:
使用以下 2 个注册表命令启用长路径支持:
如果您想为该项目做出贡献,但不想设置自己的本地开发环境,有两种选择。
GitPod 不是创建您自己的本地开发环境,而是为您提供了一个随时可用的环境。
作为替代方案,您可以构建一个开发容器(基本上是一个 docker 容器),适合使用 .devcontainer 目录中的 devcontainer.json 构建和测试 Selenium。支持 VS Code 或 IntelliJ IDEA 等 IDE 应该会告诉您如何创建这样的容器。
您还可以使用 dev 映像目录中的 Dockerfile 构建适合构建和测试 Selenium 的 Docker 映像。
Selenium 使用名为 Bazel 的通用构建工具构建,使我们能够轻松管理依赖项下载、生成所需的二进制文件、构建和发布包以及执行测试;一切都以快速、高效的方式进行。有关更详细的讨论,请阅读 Simon Stewart 的有关构建 Selenium 的文章
通常我们使用自定义的 Rake 包装器来包装 Bazel 命令。这些是使用./go
命令运行的。
常见的 Bazel 命令有:
bazel build
— 评估依赖关系,编译源文件并为指定目标生成输出文件。它用于创建可执行二进制文件、库或其他工件。
bazel run
— 构建目标然后执行它。它通常用于生成可执行二进制文件的目标。
bazel test
— 在具有附加测试功能的上下文中构建并运行目标
bazel query
— 识别所提供路径的可用目标。
每个可以构建的模块都在BUILD.bazel
文件中定义。要执行该模块,请以//
开头引用它,然后包含定义它的文件的相对路径,然后是:
,然后是目标的名称。例如,构建网格的目标名为executable-grid
,它在'selenium/java/src/org/openqa/selenium/grid/BAZEL.build'
文件中定义。因此,要构建网格,您可以运行: bazel build //java/src/org/openqa/selenium/grid:executable-grid
。
Bazel 文档提供了有关各种快捷方式以及构建多个目标的所有方法的便捷指南,Selenium 经常使用这些方法。
为给定语言构建一切:
bazel build //<语言>/...
要仅构建网格,可以使用一个别名(日志将显示输出 jar 所在的位置):
bazel构建网格
为了让事情变得更简单,可以使用这个./go
命令构建每个绑定
./go <语言>:构建
团队的大多数成员都使用 Intellij 进行日常编辑。如果您使用 IntelliJ,那么我们强烈建议您安装 Bazel IJ 插件,该插件在其自己的站点上有记录。
要将 Selenium 与 IntelliJ Bazel 插件结合使用,请将存储库导入为 Bazel 项目,然后从脚本目录中选择项目视图文件。 Mac/Linux 为ij.bazelproject
,Windows 为ij-win.bazelproject
。
我们还使用 Google Java Format 进行 linting,因此使用 Google Java Formatter 插件很有用;有几个步骤可以让它工作,所以请阅读他们的配置文档。还有一个可以运行的自动格式化脚本: ./scripts/format.sh
虽然 Selenium 不是使用 Maven 构建的,但您可以通过部署到本地 Maven 存储库 ( ~/.m2/repository
) 来构建和安装供 Maven 在本地使用的 Selenium 片段,使用:
./去java:安装
依赖关系在文件 maven_deps.bzl 中定义。要自动更新并固定新的依赖项,请运行:
./go java:更新
您可以通过使用以下命令更新 python 目录中生成的文件来在本地运行 Python 代码:
./去py:更新
要根据特定提交在本地安装 Selenium,您可以使用:
./去py:安装
您可以使用irb
创建一个包含所有加载的 gem 的交互式 REPL,而不是使用 irb : bazel run //rb:console
如果你想调试代码,可以通过debug
gem 来完成:
将binding.break
添加到您希望调试器启动的代码中。
使用ruby_debug
配置运行测试: bazel test --config ruby_debug
。
当调试器启动时,在单独的终端中运行以下命令以连接到调试器:
bazel-selenium/外部/捆绑/bin/rdbg -A
如果你想使用 RubyMine 进行开发,你可以使用 Bazel 工件来配置它:
打开rb/
作为主项目目录。
根据需要运行bundle exec rake update
以创建最新的工件。如果这不起作用,请从selenium
(父)目录运行./go rb:update
。
在Settings / Languages & Frameworks / Ruby SDK and Gems中添加指向../bazel-selenium/external/rules_ruby_dist/dist/bin/ruby
的新解释器。
您现在应该能够运行和调试任何规范。它默认使用 Chrome,但您可以使用下面 Ruby 测试部分中指定的环境变量来更改它。
要保持Carbo.Bazel.lock
与Cargo.lock
同步,请运行:
CARGO_BAZEL_REPIN=true bazel 同步 --only=板条箱
有许多专门用于测试的 bazel 配置。
以下是我们在测试 Selenium 代码时使用的参数示例:
--pin_browsers
- 运行构建中定义的特定浏览器版本(版本定期更新)
--headless
- 以无头模式运行浏览器(支持 Chrome、Edge 和 Firefox)
--flaky_test_attempts 3
- 重新运行失败的测试最多 3 次
--local_test_jobs 1
- 控制测试的并行度
--cache_test_results=no
, -t-
- 禁用测试结果缓存并重新运行所有结果
--test_output all
- 打印测试的所有输出,而不仅仅是错误
--test_output streamed
- 一项一项地运行所有测试并立即打印其输出
--test_env FOO=bar
- 将额外的环境变量传递给测试进程
--run_under="xvfb-run -a"
- 在执行之前插入的前缀
Selenium 测试可以按大小过滤:
小——通常是在不打开浏览器的情况下进行单元测试
大——通常是实际驱动浏览器的测试
中等——比简单的单元测试更复杂的测试,但不能完全驱动浏览器
可以使用test_size_filters
参数来过滤它们,如下所示:
bazel test //<语言>/... --test_size_filters=small
测试也可以按标签过滤,例如:
bazel test //<语言>/... --test_tag_filters=this,-not-this
运行单元测试:
巴泽尔测试 //java/... --test_size_filters=small
要运行集成测试:
巴泽尔测试 //java/... --test_size_filters=medium
要运行浏览器测试:
bazel 测试 //java/... --test_size_filters=large --test_tag_filters=<浏览器>
要运行特定测试:
巴泽尔测试 //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest
要运行测试,请运行:
巴泽尔测试 //javascript/node/selenium-webdriver:tests
您可以使用--test_env
将浏览器名称作为SELENIUM_BROWSER
传递。
巴泽尔测试 //javascript/node/selenium-webdriver:tests --test_env=SELENIUM_BROWSER=firefox
使用以下命令运行单元测试:
巴泽尔测试 //py:unit
要使用特定浏览器运行测试:
bazel 测试 //py:test-<浏览器名称>
运行所有 Python 测试:
巴泽尔测试 //py:all
测试目标:
命令 | 描述 |
---|---|
bazel test //rb/... | 运行单元、所有集成测试和 lint |
bazel test //rb:lint | 运行 RuboCop linter |
bazel test //rb/spec/... | 为所有浏览器运行单元和集成测试 |
bazel test //rb/spec/... --test_size_filters small | 运行单元测试 |
bazel test //rb/spec/unit/... | 运行单元测试 |
bazel test //rb/spec/... --test_size_filters large | 为所有浏览器运行集成测试 |
bazel test //rb/spec/integration/... | 为所有浏览器运行集成测试 |
bazel test //rb/spec/integration/... --test_tag_filters firefox | 仅针对本地 Firefox 运行集成测试 |
bazel test //rb/spec/integration/... --test_tag_filters firefox-remote | 仅对远程 Firefox 运行集成测试 |
bazel test //rb/spec/integration/... --test_tag_filters firefox,firefox-remote | 为本地和远程 Firefox 运行集成测试 |
Ruby 测试目标与删除了_spec.rb
的规范文件具有相同的名称,因此您可以单独运行它们。集成测试目标还有一个浏览器和远程后缀来控制选择哪个浏览器以及是否使用网格。
测试文件 | 测试目标 |
---|---|
rb/spec/unit/selenium/webdriver/proxy_spec.rb | //rb/spec/unit/selenium/webdriver:proxy |
rb/spec/integration/selenium/webdriver/driver_spec.rb | //rb/spec/integration/selenium/webdriver:driver-chrome |
rb/spec/integration/selenium/webdriver/driver_spec.rb | //rb/spec/integration/selenium/webdriver:driver-chrome-remote |
rb/spec/integration/selenium/webdriver/driver_spec.rb | //rb/spec/integration/selenium/webdriver:driver-firefox |
rb/spec/integration/selenium/webdriver/driver_spec.rb | //rb/spec/integration/selenium/webdriver:driver-firefox-remote |
支持的浏览器:
chrome
edge
firefox
firefox-beta
ie
safari
safari-preview
除了通用选项示例之外,这里还有一些其他 Ruby 特定的示例:
--test_arg "-eTimeouts"
- 仅测试名称包含“Timeouts”的规范
--test_arg "
- 传递任何额外的 RSpec 参数(请参阅bazel run @bundle//bin:rspec -- --help
)
支持与--test_env
一起使用的环境变量:
WD_SPEC_DRIVER
- 要测试的驱动程序;浏览器名称或“远程”(由 Bazel 设置)
WD_REMOTE_BROWSER
- 当WD_SPEC_DRIVER
为remote
时;要测试的浏览器的名称(由 Bazel 设置)
WD_REMOTE_URL
- 用于远程测试的已运行服务器的 URL
DOWNLOAD_SERVER
- 当WD_REMOTE_URL
未设置时;是否下载并使用最新发布的服务器版本进行远程测试
DEBUG
- 打开详细调试
HEADLESS
- 适用于 chrome、edge 和 firefox;在无头模式下运行测试
DISABLE_BUILD_CHECK
- 用于镀铬和边缘;是否忽略驱动程序和浏览器版本不匹配(允许测试 Canary 版本)
CHROME_BINARY
- 测试特定 Chrome 浏览器的路径
CHROMEDRIVER_BINARY
- 测试特定 ChromeDriver 的路径
EDGE_BINARY
- 测试特定 Edge 浏览器的路径
MSEDGEDRIVER_BINARY
- 测试特定 msedgedriver 的路径
FIREFOX_BINARY
- 测试特定 Firefox 浏览器的路径
GECKODRIVER_BINARY
- 测试特定 GeckoDriver 的路径
要使用特定版本的 Ruby 运行,您可以在rb/.ruby-version
中或从命令行更改版本:
echo '' > rb/.ruby-版本
.NET 测试当前仅适用于固定浏览器,因此请确保包含该浏览器。
使用以下命令运行所有测试:
巴泽尔测试 //dotnet/test/common:AllTests --pin_browsers=true
您可以通过指定类名来运行特定测试:
巴泽尔测试 //dotnet/test/common:ElementFindingTest --pin_browsers=true
如果模块支持多种浏览器:
巴泽尔测试 //dotnet/test/common:ElementFindingTest-edge --pin_browsers=true
Rust 测试的运行方式为:
巴泽尔测试//rust/...
默认情况下,Bazel 在您当前的 X-server UI 中运行这些测试。如果您愿意,您也可以在虚拟或嵌套 X 服务器中运行它们。
运行 X 服务器Xvfb :99
或Xnest :99
运行窗口管理器,例如DISPLAY=:99 jwm
运行您感兴趣的测试:
巴泽尔测试 --test_env=DISPLAY=:99 //java/... --test_tag_filters=chrome
在虚拟 X 服务器中运行测试的一种简单方法是使用 Bazel 的--run_under
功能:
bazel test --run_under="xvfb-run -a" //java/...
API 文档可以在这里找到:
C#
JavaScript
爪哇
Python
红宝石
要更新特定语言的 API 文档: ./go
要更新所有文档: ./go all:docs
请注意,JavaScript 生成目前已损坏。
发布的完整流程可以在 wiki 中找到
发布是构建和发布的结合,通常需要协调多个执行和额外的处理。正如构建部分中所讨论的,我们使用 Rake 任务和./go
命令来完成这些事情。这些./go
命令包含--stamp
参数,以提供有关所构建资产的必要信息。
您可以使用以下方式构建和发布所有内容:
./全部执行:释放
构建并发布特定语言:
./go <语言>:release
如果您有权访问 Selenium EngFlow 存储库,则可以使用以下命令远程构建资产并在本地下载:
./go all:release['--config', 'release']