2026-05-21
Playwright
00

目录

前言
与HTML输入元素的交互
1. 文本输入框的交互:locator.fill()方法适用于以下三种元素类型:
2. 复选框的选中与取消:locator.set_checked() 适用于三类元素:
3. 下拉框选项操纵:locator.set_checked() 只用于原生的 <select> 元素:
4. 鼠标的点击操作:
鼠标的单击操作,点击操作前的可操作性检查包括:
5. 文件的上传操作:文件上传是通过setinputfiles()方法完成的,该方法支持单文件、多文件、目录上传以及清空文件取消文件上传的操作。
5.1 单文件的上传
5.2 多文件的上传:前提条件HTML必须支持<input type="file" multiple>,多个文件的路径放在列表中传入方法中,具体示例如下:
5.3 清空文件操作,这里的.setinputfiles([])方法。
5.4 内存上传,这里指的是脚本中直接生成虚拟的文件内容,并将其作为文件上传,而不需要读取硬盘上的真实文件,这就是高级的所在。在这里可以根据测试需要,灵活地构造不同的文件类型。
5.5 input 被隐藏,我们就当存在<input type="file">进行上传操作,我们也可以控制台命令来看看到底是否存在input标签。
6. 页面的滚动操作。
6.1 大多数情况下不需要手动滚动,元素不在可视区域时Playwright会自动滚动到可视区域。
6.2 手动滚动,借助scrollintoviewifneeded()方法。
6.3 更加精确的鼠标滚轮滚动,.mouse.wheel()。
涉及资料

前言

 对playwright所提供的元素的操作方法以及使用的条件进行简单的实践。

与HTML输入元素的交互

1. 文本输入框的交互:locator.fill()方法适用于以下三种元素类型:

  • <input>:输入框
python
page.goto("https://2x.ant.design/components/input-cn/") page.get_by_placeholder("Basic usage", exact=False).fill("2020-02-02")
  • <textarea>:多行文本,文本域。
python
page.goto("https://2x.ant.design/components/input-cn/") page.get_by_placeholder("Autosize height with minimum and maximum number of lines", exact=False).fill("多行文本")
  • [contenteditable]可编辑元素:富文本/自定义输入框。

2. 复选框的选中与取消:locator.set_checked() 适用于三类元素:

  • input[type=checkbox]:原生的复选框的选中与取消。
python
page.goto("https://2x.ant.design/components/checkbox-cn/") page.get_by_role("checkbox", name="Checked-Enabled").uncheck() page.get_by_role("checkbox", name="Checked-Enabled").check() expect(page.get_by_role("checkbox", name="Checked-Enabled")).to_be_checked()
  • input[type=radio]:原生的单选框的选中。
python
page.goto("https://2x.ant.design/components/radio-cn/") page.locator("#components-radio-demo-radiogroup").get_by_role("radio", name="B").check()
  • [role=checkbox]:ARIA组件。
python
page.goto("https://react-aria.adobe.com/CheckboxGroup") page.locator("#react-aria-_R_1mbirda_").get_by_text("Soccer").click()

3. 下拉框选项操纵:locator.set_checked() 只用于原生的 <select> 元素:

python
page.goto("https://react-aria.adobe.com/CheckboxGroup") page.locator("#react-aria-_R_1mbirda_").get_by_text("Soccer").click()

注意

目前基本都是引入组件的下拉框,很少有原生的。 原生的标准格式如下: image.png

4. 鼠标的点击操作:

鼠标的单击操作,点击操作前的可操作性检查包括:

  1. 元素必须存在(DOM中)
  2. 元素必须可见(非 display:none/visibility:hidden
  3. 元素必须稳定(动画结束)
  4. 自动滚动到视口内
  5. 检查是否被遮挡(能否接收 pointer 事件)
  6. 执行点击
  7. 如果中途 DOM 变化 → 自动重试
python
page.goto("https://react-aria.adobe.com/CheckboxGroup") # 单击操作 page.locator("#react-aria-_R_1mbirda_").get_by_text("Soccer").click() # 双击操作 page.get_by_role("button", name="Star").dblclick() # 右键 page.get_by_role("button", name="Star").click(button="right") # 也可多个修饰健组合使用如:click(modifiers=["Shift","Ctrl"])。 page.get_by_role("button", name="Star").click(modifiers=["Shift"]) # 鼠标悬停操作:图标数据的显示、有些下拉框的触发等。 page.goto("https://2x.ant.design/components/dropdown-cn/") page.locator("#components-dropdown-demo-basic").get_by_role("link", name="Hover me ").hover() # 指定位置点击:地图场景、颜色选择器 page.goto("https://www.google.com/maps/@36.1951437,138.5483037,10z?entry=ttu&g_ep=EgoyMDI2MDQwNy4wIKXMDSoASAFQAw%3D%3D") page.get_by_role("button", name="Star").click(position={ "x": 0, "y": 0})

5. 文件的上传操作:文件上传是通过set_input_files()方法完成的,该方法支持单文件、多文件、目录上传以及清空文件取消文件上传的操作。

5.1 单文件的上传

python
with sync_playwright() as p: browser = p.chromium.launch( headless=False, # args=["--no-proxy-server"] ) page = browser.new_page() page.goto("https://2x.ant.design/components/upload-cn/") page.locator('input[type="file"]').nth(0).set_input_files("/Users/jingwei/Desktop/截图/Snipaste_2024-03-20_09-40-39.png") sleep(5) browser.close()

5.2 多文件的上传:前提条件HTML必须支持<input type="file" multiple>,多个文件的路径放在列表中传入方法中,具体示例如下:

html
# 元素 <input type="file" accept="" multiple="" style="display: none;">
python
page.goto("https://2x.ant.design/components/upload-cn/") page.locator('input[type="file"]').nth(2).set_input_files([ "/Users/jingwei/Desktop/截图/Snipaste_2024-03-20_09-40-39.png", "/Users/jingwei/Desktop/截图/制图/报告文件.png" ])

5.3 清空文件操作,这里的.set_input_files([])方法。

我的实践的时候并没有发现实际的效果,建议点击页面真是的删除与清空按钮,具体原因可能是:

  • .set_input_files([])方法并不会触发浏览器原生的文件取消/清空事件,它只是清空了Playwright内部记录的文件路径,但页面的上传组建通常不会显现这种变化。
  • 在大多数情况下input元素是被隐藏的,页面上显示的“已选文件”的信息是JavaScript监听change事件后渲染的。
  • .set_input_files([])不会触发change事件,即使清空了值,也不一定会触发change事件。
  • UI状态的独立:页面上的文件列表、文件名等UI状态是由JavaScript维护的,与input的实际值可能不同步。

5.4 内存上传,这里指的是脚本中直接生成虚拟的文件内容,并将其作为文件上传,而不需要读取硬盘上的真实文件,这就是高级的所在。在这里可以根据测试需要,灵活地构造不同的文件类型。

python
page.goto("https://2x.ant.design/components/upload-cn/") upload = page.locator( 'input[type="file"]' ).nth(0) upload.nth(0).set_input_files( files=[ { "name": "test.txt", # 文件名 "mimeType": "text/plain", # 文件类型 "buffer": b"hello world" # 文件内容 } ] ) sleep(5) browser.close()

5.5 input 被隐藏,我们就当存在<input type="file">进行上传操作,我们也可以控制台命令来看看到底是否存在input标签。

js
document.querySelectorAll('input')

这里以课堂派中提交作业功能来进行测试。

python
page.goto("https://www.ketangpai.com/#/login") print("the page title is {}".format(page.title())) page.fill('//input[@placeholder="请输入邮箱/手机号/账号"]', "") page.fill('//input[@placeholder="请输入密码"]', "") page.click('//button[./span="登录"]') page.wait_for_timeout(5) course = page.locator( '.header-info', has_text="网络安全高级课程2301" ).first course.click() sleep(5) page.get_by_text("作业").click() with page.context.expect_page() as new_page_info: page.get_by_text("w58-rce-23.6.21").click() new_page = new_page_info.value # 等待新页面加载完成 new_page.wait_for_load_state() # 后续全部操作新页面 new_page.get_by_text("提交作业").click() new_page.locator('input[type="file"]').set_input_files( "/Users/jingwei/Desktop/截图/制图/报告文件.png" ) new_page.get_by_role("button", name="确认提交").click() new_page.get_by_role("button", name="确定").click() sleep(5) page.close()

6. 页面的滚动操作。

6.1 大多数情况下不需要手动滚动,元素不在可视区域时Playwright会自动滚动到可视区域。

6.2 手动滚动,借助scroll_into_view_if_needed()方法。

python
page.goto("https://www.ketangpai.com/#/login") print("the page title is {}".format(page.title())) page.fill('//input[@placeholder="请输入邮箱/手机号/账号"]', "") page.fill('//input[@placeholder="请输入密码"]', "") page.click('//button[./span="登录"]') page.wait_for_timeout(5) page.locator('h3:has-text("2020-2021 第一学期")').scroll_into_view_if_needed() sleep(5)

6.3 更加精确的鼠标滚轮滚动,.mouse.wheel()

python
page.locator('h2:has-text("置顶课程")').scroll_into_view_if_needed() page.locator('h2:has-text("置顶课程")').hover() page.mouse.wheel(0, 100)

涉及资料

Playwright for Python官方文档

本文作者:精卫

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!