- Selenium 教程
- Selenium - 首页
- Selenium - 概述
- Selenium - 组件
- Selenium - 自动化测试
- Selenium - 环境设置
- Selenium - 远程控制
- Selenium IDE 教程
- Selenium - IDE 简介
- Selenium - 特性
- Selenium - 限制
- Selenium - 安装
- Selenium - 创建测试
- Selenium - 创建脚本
- Selenium - 控制流
- Selenium - 存储变量
- Selenium - 警报和弹出窗口
- Selenium - Selenese 命令
- Selenium - 操作命令
- Selenium - 访问器命令
- Selenium - 断言命令
- Selenium - Assert/Verify 方法
- Selenium - 定位策略
- Selenium - 脚本调试
- Selenium - 验证点
- Selenium - 模式匹配
- Selenium - JSON 数据文件
- Selenium - 浏览器执行
- Selenium - 用户扩展
- Selenium - 代码导出
- Selenium - 代码发射
- Selenium - JavaScript 函数
- Selenium - 插件
- Selenium WebDriver 教程
- Selenium - 简介
- Selenium WebDriver vs RC
- Selenium - 安装
- Selenium - 第一个测试脚本
- Selenium - 驱动程序会话
- Selenium - 浏览器选项
- Selenium - Chrome 选项
- Selenium - Edge 选项
- Selenium - Firefox 选项
- Selenium - Safari 选项
- Selenium - 双击
- Selenium - 右键单击
- Python 中的 HTML 报告
- 处理编辑框
- Selenium - 单个元素
- Selenium - 多个元素
- Selenium Web 元素
- Selenium - 文件上传
- Selenium - 定位器策略
- Selenium - 相对定位器
- Selenium - 查找器
- Selenium - 查找所有链接
- Selenium - 用户交互
- Selenium - WebElement 命令
- Selenium - 浏览器交互
- Selenium - 浏览器命令
- Selenium - 浏览器导航
- Selenium - 警报和弹出窗口
- Selenium - 处理表单
- Selenium - 窗口和标签页
- Selenium - 处理链接
- Selenium - 输入框
- Selenium - 单选按钮
- Selenium - 复选框
- Selenium - 下拉框
- Selenium - 处理 IFrame
- Selenium - 处理 Cookie
- Selenium - 日期时间选择器
- Selenium - 动态 Web 表格
- Selenium - Actions 类
- Selenium - Action 类
- Selenium - 键盘事件
- Selenium - 键上/下
- Selenium - 复制和粘贴
- Selenium - 处理特殊键
- Selenium - 鼠标事件
- Selenium - 拖放
- Selenium - 笔事件
- Selenium - 滚动操作
- Selenium - 等待策略
- Selenium - 显式/隐式等待
- Selenium - 支持特性
- Selenium - 多选
- Selenium - 等待支持
- Selenium - 选择支持
- Selenium - 颜色支持
- Selenium - ThreadGuard
- Selenium - 错误和日志记录
- Selenium - 异常处理
- Selenium - 杂项
- Selenium - 处理 Ajax 调用
- Selenium - JSON 数据文件
- Selenium - CSV 数据文件
- Selenium - Excel 数据文件
- Selenium - 跨浏览器测试
- Selenium - 多浏览器测试
- Selenium - 多窗口测试
- Selenium - JavaScript 执行器
- Selenium - 无头执行
- Selenium - 捕获屏幕截图
- Selenium - 捕获视频
- Selenium - 页面对象模型
- Selenium - 页面工厂
- Selenium - 记录和回放
- Selenium - 框架
- Selenium - 浏览上下文
- Selenium - DevTools
- Selenium Grid 教程
- Selenium - 概述
- Selenium - 架构
- Selenium - 组件
- Selenium - 配置
- Selenium - 创建测试脚本
- Selenium - 测试执行
- Selenium - 端点
- Selenium - 自定义节点
- Selenium 报告工具
- Selenium - 报告工具
- Selenium - TestNG
- Selenium - JUnit
- Selenium - Allure
- Selenium & 其他技术
- Selenium - Java 教程
- Selenium - Python 教程
- Selenium - C# 教程
- Selenium - Javascript 教程
- Selenium - Kotlin 教程
- Selenium - Ruby 教程
- Selenium - Maven & Jenkins
- Selenium - 数据库测试
- Selenium - LogExpert 日志记录
- Selenium - Log4j 日志记录
- Selenium - Robot Framework
- Selenium - AutoIT
- Selenium - Flash 测试
- Selenium - Apache Ant
- Selenium - Github 教程
- Selenium - SoapUI
- Selenium - Cucumber
- Selenium - IntelliJ
- Selenium - XPath
- Selenium 杂项概念
- Selenium - IE 驱动程序
- Selenium - 自动化框架
- Selenium - 关键字驱动框架
- Selenium - 数据驱动框架
- Selenium - 混合驱动框架
- Selenium - SSL 证书错误
- Selenium - 替代方案
- Selenium 有用资源
- Selenium - 问答
- Selenium - 快速指南
- Selenium - 有用资源
- Selenium - 自动化实践
- Selenium - 讨论
Selenium Grid - 自定义节点
Selenium Grid 4 的最新版本是在没有利用 Selenium Grid 旧版本代码库的情况下开发的。此最新版本的 Selenium Grid 4 版本具有一些高级功能,例如自定义节点。
最新版本的 Selenium Grid 允许在三种不同的 Selenium Grid 模式下触发测试执行。它们被称为独立模式、集线器和节点模式以及分布式模式。
Selenium Grid 中的节点自定义
在使用 Selenium Grid 在不同浏览器及其平台、设备上执行并行测试或跨浏览器测试时,我们可能需要根据需求自定义节点。
在执行会话开始之前,我们可能需要添加一些先决条件步骤,或者在会话完成后执行任何整理活动。要执行节点自定义,需要执行以下步骤:
设计一个类,该类将扩展 -
org.openqa.selenium.grid.node.Node.
在新建的类中追加一个静态方法(工厂方法),该方法应具有以下签名:public static Node created(Config config)。此处,Node 与 org.openqa.selenium.grid.node.Node 类型相同,Config 与 - 类型相同。
org.openqa.selenium.grid.config.Config.
在工厂方法内部,应添加新类的实现逻辑。
要将新开发的实现合并到集线器中,请启动节点并将前一个的完全限定类名发送到参数:–node-implementation。
使用 Uber Jar 进行节点自定义
使用 uber jar 实现节点自定义的步骤如下所列:
在系统中安装 Java(版本高于 8),并使用命令检查它是否存在:java -version。如果安装已成功完成,则将显示已安装的 Java 版本。
在系统中安装 Maven,并使用命令检查它是否存在:mvn -version。如果安装已成功完成,则将显示已安装的 Maven 版本。
安装任何 IDE,如 Eclipse、IntelliJ 等。
从链接将 Selenium Grid 依赖项添加到 pom.xml 中:
从链接将 Apache Maven Shade Plugin 添加到 pom.xml 中:
将自定义节点附加到当前项目。
构建 uber jar 以使用命令启动节点:java -jar。
使用以下命令启动节点:
java -jar custom_node-server.jar node \ --node-implementation org.seleniumhq.samples.DecoratedLoggingNode
使用普通 Jar 进行节点自定义
使用普通 jar 实现节点自定义的步骤如下所列:
在系统中安装 Java(版本高于 8),并使用命令检查它是否存在:java -version。如果安装已成功完成,则将显示已安装的 Java 版本。
在系统中安装 Maven,并使用命令检查它是否存在:mvn -version。如果安装已成功完成,则将显示已安装的 Maven 版本。
安装任何 IDE,如 Eclipse、IntelliJ 等。
从链接将 Selenium Grid 依赖项添加到 pom.xml 中:https://mvnrepository.com/artifact/。
从链接将 Apache Maven Shade Plugin 添加到 pom.xml 中:https://maven.apache.org/plugins/。
将自定义节点附加到当前项目。
构建 uber jar 以使用命令启动节点:java -jar。
使用以下命令启动节点:
java -jar selenium-server-4.6.0.jar \ --ext custom_node-1.0-SNAPSHOT.jar node \ --node-implementation org.seleniumhq.samples.DecoratedLoggingNode
DecoratedLoggingNode.java 中的代码实现
package org.seleniumhq.samples; import java.io.IOException; import java.net.URI; import java.util.UUID; import java.util.function.Supplier; import org.openqa.selenium.Capabilities; import org.openqa.selenium.NoSuchSessionException; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.data.CreateSessionRequest; import org.openqa.selenium.grid.data.CreateSessionResponse; import org.openqa.selenium.grid.data.NodeId; import org.openqa.selenium.grid.data.NodeStatus; import org.openqa.selenium.grid.data.Session; import org.openqa.selenium.grid.log.LoggingOptions; import org.openqa.selenium.grid.node.HealthCheck; import org.openqa.selenium.grid.node.Node; import org.openqa.selenium.grid.node.local.LocalNodeFactory; import org.openqa.selenium.grid.security.Secret; import org.openqa.selenium.grid.security.SecretOptions; import org.openqa.selenium.grid.server.BaseServerOptions; import org.openqa.selenium.internal.Either; import org.openqa.selenium.io.TemporaryFilesystem; import org.openqa.selenium.remote.SessionId; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; import org.openqa.selenium.remote.tracing.Tracer; public class DecoratedLoggingNode extends Node { private Node node; protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret) { super(tracer, nodeId, uri, registrationSecret); } public static Node create(Config config) { LoggingOptions loggingOptions = new LoggingOptions(config); BaseServerOptions serverOptions = new BaseServerOptions(config); URI uri = serverOptions.getExternalUri(); SecretOptions secretOptions = new SecretOptions(config); // Refer to the foot notes for additional context on this line. Node node = LocalNodeFactory.create(config); DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(), node.getId(), uri, secretOptions.getRegistrationSecret()); wrapper.node = node; return wrapper; } @Override public Either<WebDriverException, CreateSessionResponse> newSession( CreateSessionRequest sessionRequest) { return perform(() -> node.newSession(sessionRequest), "newSession"); } @Override public HttpResponse executeWebDriverCommand(HttpRequest req) { return perform(() -> node.executeWebDriverCommand(req), "executeWebDriverCommand"); } @Override public Session getSession(SessionId id) throws NoSuchSessionException { return perform(() -> node.getSession(id), "getSession"); } @Override public HttpResponse uploadFile(HttpRequest req, SessionId id) { return perform(() -> node.uploadFile(req, id), "uploadFile"); } @Override public HttpResponse downloadFile(HttpRequest req, SessionId id) { return perform(() -> node.downloadFile(req, id), "downloadFile"); } @Override public TemporaryFilesystem getDownloadsFilesystem(UUID uuid) { return perform(() -> { try { return node.getDownloadsFilesystem(uuid); } catch (IOException e) { throw new RuntimeException(e); } }, "downloadsFilesystem"); } @Override public TemporaryFilesystem getUploadsFilesystem(SessionId id) throws IOException { return perform(() -> { try { return node.getUploadsFilesystem(id); } catch (IOException e) { throw new RuntimeException(e); } }, "uploadsFilesystem"); } @Override public void stop(SessionId id) throws NoSuchSessionException { perform(() -> node.stop(id), "stop"); } @Override public boolean isSessionOwner(SessionId id) { return perform(() -> node.isSessionOwner(id), "isSessionOwner"); } @Override public boolean isSupporting(Capabilities capabilities) { return perform(() -> node.isSupporting(capabilities), "isSupporting"); } @Override public NodeStatus getStatus() { return perform(() -> node.getStatus(), "getStatus"); } @Override public HealthCheck getHealthCheck() { return perform(() -> node.getHealthCheck(), "getHealthCheck"); } @Override public void drain() { perform(() -> node.drain(), "drain"); } @Override public boolean isReady() { return perform(() -> node.isReady(), "isReady"); } private void perform(Runnable function, String operation) { try { System.err.printf("[COMMENTATOR] Before %s()%n", operation); function.run(); } finally { System.err.printf("[COMMENTATOR] After %s()%n", operation); } } private <T> T perform(Supplier<T> function, String operation) { try { System.err.printf("[COMMENTATOR] Before %s()%n", operation); return function.get(); } finally { System.err.printf("[COMMENTATOR] After %s()%n", operation); } } }
DecoratedLoggingNode.java 的源代码:https://www.seleniumcn.cn/documentation/。
在上述实现中,以下代码:
Node node = LocalNodeFactory.create(config) 用于专门生成 LocalNode。org.openqa.selenium.grid.node.Node 有两种面向用户的实现。这些是创建自定义节点和收集有关节点信息的绝佳起点。
org.openqa.selenium.grid.node.local.LocalNode - 用于指向长时间运行的节点,并且是启动节点时获取的默认逻辑。可以通过调用 LocalNodeFactory.create(config) 生成它。此处,LocalNodeFactory 是 org.openqa.selenium.grid.node.local 的一部分,Config 是 org.openqa.selenium.grid.config 的一部分。
org.openqa.selenium.grid.node.k8s.OneShotNode - 这是一个重要的参考逻辑,其中节点在一次测试会话后正确关闭自身。此类对任何预先存在的 Maven 工件不可用。可以通过调用 OneShotNode.create(config) 生成它。此处,OneShotNode 是 org.openqa.selenium.grid.node.k8s 的一部分,Config 是 org.openqa.selenium.grid.config 的一部分。
这结束了我们关于 Selenium Grid - 自定义节点教程的全面介绍。我们从描述如何在 Selenium Grid 中执行节点自定义、使用 uber jar 进行节点自定义以及在 Selenium Grid 中使用普通 jar 进行节点自定义开始。
这使您深入了解了 Selenium Grid 自定义节点。明智的做法是不断练习您学到的知识并探索与 Selenium 相关的其他知识,以加深您的理解并拓宽您的视野。