编写复杂的用户操作

概述

Nightwatch 2 为使用 Selenium WebDriver 的较新 Actions API 执行复杂的用户手势提供了支持。

Actions API 提供了对指定输入设备可以执行的操作的精确控制。Selenium 为 3 种输入源提供接口

  • 键盘设备的键输入
  • 鼠标、笔或触摸设备的指针输入
  • 滚轮设备的滚轮输入(在 Selenium 4.2 中引入)

有关更多信息,请访问 W3C Webdriver 规范页面

示例

新 API 可通过 Nightwatch 中现有的 .perform() 命令使用。perform() 命令的先前功能仍然存在,并且与以前一样工作。

tests/sampleTest.js
describe('user actions api', function() {
  
it('demo test', function() { browser .navigateTo('https://nightwatch.node.org.cn') .perform(function() { const actions = this.actions({async: true});
return actions .keyDown(Keys.SHIFT) .keyUp(Keys.SHIFT); }); }) })

可用操作

.clear()

释放所有键、指针并清除内部状态。

参数

.click([element])

用于执行鼠标简单左键单击(按下/抬起)的简写。

参数
名称 类型 描述
元素
可选
WebElement 如果指定,则鼠标将首先移动到元素的中心,然后再执行单击操作。

.contextClick([element])

用于执行鼠标简单右键单击(按下/抬起)的简写。

参数
名称 类型 描述
元素
可选
WebElement 如果指定,则鼠标将首先移动到元素的中心,然后再执行单击操作。

.doubleClick([element])

用于执行鼠标双击左键的简写。

参数
名称 类型 描述
元素
可选
WebElement 如果指定,则鼠标将首先移动到元素的中心,然后再执行单击操作。

.dragAndDrop(from, to)

配置拖放操作,包括以下步骤
  1. 移动到 from 元素(要拖动的元素)的中心。
  2. 按下鼠标左键。
  3. 如果 to 目标是 WebElement,则将鼠标移动到其中心。否则,将鼠标移动指定的偏移量。
  4. 释放鼠标左键。
参数
名称 类型 描述
from WebElement 要按下鼠标左键开始拖动的元素
to WebElement
{x: number, y: number}
另一个要拖动的元素(将拖动到元素的中心),或一个指定偏移量(以像素为单位)的对象。

.insert(device, ...actions)

将操作追加到给定 device 的当前序列的末尾。如果启用了设备同步,则插入操作后,将为所有其他设备插入暂停,以确保所有操作序列的长度相同。

参数
名称 类型 描述
device 设备 要更新的设备
actions ...Action 要插入的操作。

.keyDown(key)

插入按下单个键的操作。

参数
名称 类型 描述
key string|number 要按下的键。此键可以指定为 Key 值、特定 Unicode 代码点或包含单个 Unicode 代码点的字符串。

.keyUp(key)

插入释放单个键的操作。

参数
名称 类型 描述
key string|number 要释放的键。此键可以指定为 Key 值、特定 Unicode 代码点或包含单个 Unicode 代码点的字符串。

.keyboard()

参数

返回
类型 描述
键盘 键盘设备句柄。

.mouse()

参数

返回
类型 描述
指针 鼠标指针设备句柄。

.move([options])

插入将鼠标移动相对于指定 originxy 像素的操作。origin 可以定义为鼠标的 当前位置视窗或特定 WebElement 的中心。

可以使用 duration 参数(默认为 100 毫秒)调整浏览器驱动程序执行移动操作所需的时间(以毫秒为单位)。

参数
名称 类型 描述
options
可选
对象 移动选项。默认为在 100 毫秒内将鼠标移动到视窗的左上角。

可用值为
{
  duration: {Number|undefined}, 
  origin: (Origin|WebElement|undefined), 
  x: {Number|undefined}, 
  y: {Number|undefined}
}

.pause(duration, ...devices)

为指定的设备插入暂停操作,确保每个设备在每个周期都处于空闲状态。暂停的长度(以毫秒为单位)可以指定为此方法的第一个参数(默认为 0)。否则,您只需指定应暂停的各个设备。

如果没有指定设备,则会为每个设备创建一个暂停操作(使用相同的持续时间)。

参数
名称 类型 描述
duration
可选
Number|Device 要插入的暂停长度(以毫秒为单位)。或者,可以省略 duration(产生默认的 0 毫秒暂停),并指定第一个要暂停的设备。
devices ...Device 要插入暂停的设备。如果没有指定设备,则会为所有设备插入暂停。

.press([button])

插入在鼠标的当前位置按下鼠标按钮的操作。

参数
名称 类型 描述
button
可选
按钮 要按下的按钮;默认为 LEFT

.release([button])

插入在鼠标的当前位置释放鼠标按钮的操作。

参数
名称 类型 描述
button
可选
按钮 要释放的按钮;默认为 LEFT

.sendKeys(...keys)

插入一系列操作以键入提供的键序列。对于每个键,这将记录一对 keyDown 和 keyUp 操作。

参数
名称 类型 描述
keys ...String|Number 要键入的键。

.synchronize(...devices)

确保此操作序列中引用的每个设备的操作序列的长度相同。对于序列过短的设备,这将插入暂停,以便每个设备在每个周期都定义了显式操作。

参数
名称 类型 描述
devices ...Device 要同步的特定设备。如果未指定,则所有设备的操作序列将同步。

使用操作周期

操作序列分为一系列“周期”。在每个周期中,浏览器驱动程序将为操作序列中包含的每个设备执行单个操作。在周期 0 时,驱动程序将执行为每个设备定义的第一个操作,在周期 1 时执行为每个设备定义的第二个操作,依此类推,直到所有操作都执行完毕。如果某个设备在特定周期没有定义操作,它将自动暂停。

默认情况下,操作序列将同步,因此每个周期只有一个设备定义了操作。考虑以下代码示例

tests/sampleTest.js
describe('user actions api', function() {
  
it('demo test', function() { browser .perform(function() { const actions = this.actions({async: true});
return actions .keyDown(Keys.SHIFT) .move({origin: el}) .press() .release() .keyUp(Keys.SHIFT); }); }) })

这将生成以下周期序列

设备 周期 1 周期 2 周期 3 周期 4 周期 5
键盘 keyDown(SHIFT) pause() pause() pause() keyUp(SHIFT)
鼠标 pause() move({origin: el}) press() release() pause()