创网头像创网独立产品工程师
菜单

其他 / 设置

返回博客

建站经验 · 中文译文

Playwright:普通点击前的可交互检查

Playwright 在执行操作前,会对元素进行一系列可交互性检查,以确保操作按预期发生。它会自动等待所有相关检查通过,之后才执行所请求的操作。如果必要的检查未能在指定超时时间内通过,操作会失败,并抛出 TimeoutError。

简介

Playwright 在执行操作前,会对元素进行一系列可交互性检查,以确保操作按预期发生。它会自动等待所有相关检查通过,之后才执行所请求的操作。如果必要的检查未能在指定超时时间内通过,操作会失败,并抛出 TimeoutError。

例如,执行 locator.click() 时,Playwright 会确保:

  • locator 恰好定位到一个元素

  • 元素可见(Visible)

  • 元素稳定(Stable),即未处于动画过程中,或动画已经结束

  • 元素能接收事件(Receives Events),即未被其他元素遮挡

  • 元素已启用(Enabled)

以下是各项操作所执行的可交互性检查的完整列表:

操作 可见 稳定 接收事件 已启用 可编辑
locator.check() 是 是 是 是 -
locator.click() 是 是 是 是 -
locator.dblclick() 是 是 是 是 -
locator.setChecked() 是 是 是 是 -
locator.tap() 是 是 是 是 -
locator.uncheck() 是 是 是 是 -
locator.hover() 是 是 是 - -
locator.dragTo() 是 是 是 - -
locator.screenshot() 是 是 - - -
locator.fill() 是 - - 是 是
locator.clear() 是 - - 是 是
locator.selectOption() 是 - - 是 -
locator.selectText() 是 - - - -
locator.scrollIntoViewIfNeeded() - 是 - - -
locator.blur() - - - - -
locator.dispatchEvent() - - - - -
locator.focus() - - - - -
locator.press() - - - - -
locator.pressSequentially() - - - - -
locator.setInputFiles() - - - - -

强制执行操作

一些操作(如 locator.click())支持 force 选项,用于关闭非必要的可交互性检查。例如,将 locator.click() 方法的 force 参数设为真值时,就不会检查目标元素是否确实能接收到点击事件。

断言

Playwright 提供会自动重试的断言,通过等待条件满足来减少测试的不稳定性;这与执行操作前的自动等待类似。

断言 说明
expect(locator).toBeAttached() 元素已附加到 DOM
expect(locator).toBeChecked() 复选框已勾选
expect(locator).toBeDisabled() 元素被禁用
expect(locator).toBeEditable() 元素可编辑
expect(locator).toBeEmpty() 容器为空
expect(locator).toBeEnabled() 元素已启用
expect(locator).toBeFocused() 元素获得焦点
expect(locator).toBeHidden() 元素不可见
expect(locator).toBeInViewport() 元素与视口相交
expect(locator).toBeVisible() 元素可见
expect(locator).toContainText() 元素包含指定文本
expect(locator).toHaveAttribute() 元素具有指定 DOM 属性
expect(locator).toHaveClass() 元素具有指定 class 属性
expect(locator).toHaveCount() 列表包含确切数量的子元素
expect(locator).toHaveCSS() 元素具有指定 CSS 属性
expect(locator).toHaveId() 元素具有指定 ID
expect(locator).toHaveJSProperty() 元素具有指定 JavaScript 属性
expect(locator).toHaveText() 元素文本与指定内容匹配
expect(locator).toHaveValue() 输入框具有指定值
expect(locator).toHaveValues() 选择框已选中指定选项
expect(page).toHaveTitle() 页面具有指定标题
expect(page).toHaveURL() 页面具有指定 URL
expect(response).toBeOK() 响应状态为 OK

更多内容请参阅断言指南。

可见(Visible)

当元素拥有非空边界框,且计算样式不为 visibility:hidden 时,才被视为可见。

请注意,根据这一定义:

  • 尺寸为零的元素不被视为可见。

  • 具有 display:none 的元素不被视为可见。

  • 具有 opacity:0 的元素被视为可见。

稳定(Stable)

当元素在至少两个连续动画帧内保持相同的边界框时,就被视为稳定。

已启用(Enabled)

未被禁用的元素被视为已启用。

在以下情况下,元素被视为禁用:

  • 它是带有 [disabled] 属性的 <button>、<select>、<input>、<textarea>、<option> 或 <optgroup>;

  • 它是 <button>、<select>、<input>、<textarea>、<option> 或 <optgroup>,并且位于带有 [disabled] 属性的 <fieldset> 内;

  • 它是带有 [aria-disabled=true] 属性的元素的后代。

可编辑(Editable)

元素已启用且不为只读时,才被视为可编辑。

以下情况下,元素被视为只读:

  • 它是带有 [readonly] 属性的 <select>、<input> 或 <textarea>;

  • 它带有 [aria-readonly=true] 属性,并具有支持该属性的 ARIA 角色。

接收事件(Receives Events)

当元素是操作位置上指针事件命中的目标时,才被视为能够接收指针事件。例如,在坐标 (10;10) 点击时,Playwright 会检查是否有其他元素(通常是覆盖层)抢先捕获这个位置上的点击。

例如,在下面的场景中,不论何时调用 locator.click(),Playwright 都会点击 Sign Up(注册)按钮:

  • 页面正在检查用户名是否唯一,此时 Sign Up 按钮被禁用;

  • 与服务器完成检查后,原先禁用的 Sign Up 按钮被一个已启用的按钮替换。

示例代码许可(原文)

官方 LICENSE-CODE

    MIT License

    Copyright (c) Microsoft Corporation.

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE