Day3 - Playwright 页面元素
Playwright 可以与 HTML 输入元素交互,例如文本输入、复选框、单选按钮、选择选项、鼠标
单击、键入字符、键和快捷方式以及上传文件和焦点元素
1.fill()输入文字
- 使用 locator.fill() 是填写表单字段的最简单方法。它聚焦元素并input使用输入的文本触发事件。它适用于 , 和 [contenteditable] 元素。
page.get_by_placeholder("用户名").fill("ceshi")
2.type()输入文字
- 一个字符一个字符的输入,模拟用户真是键盘输入。
page.locator("#userPasswd").type('password')
3.click()鼠标点击
# 普通单击
page.locator('#login').click()
# 双击
page.locator('#login').dbclick()
# 右击
page.locator('#login').click(button="right")
# Shift + click
page.locator('#login').click(modifiers=['Shift'])
# 鼠标悬浮
page.locator('#login').hover()
4.文件上传
- 如果你之前用过selenium,肯定遇到过文件上传头疼的事,有些控件是input输入框,可以直接传本地文件地址,然而有些需要弹出本地文件选择器的时候就不好处理了。
- playwright 控件优雅的处理了文件上传操作,在这里一切都变得如此简单了。
- 文件上传主要有2种情况:
(1)input 标签的,并且 type=“file”
# 上传单个文件
page.get_by_label("Upload file").set_input_files('myfile.pdf')
# 上传多个文件
page.get_by_label("Upload files").set_input_files(['file1.txt', 'file2.txt'])
# 删除所有选择的文件
page.get_by_label("Upload file").set_input_files([])
(2)非input的文件上传框,必须点开文件框的情况(selenium 上没发实现的操作),可以使用page.expect_file_chooser()监听到弹出框,在弹出框上输入文件文件路径
# 点击选择文件,输入文件
with page.expect_file_chooser() as fc_info:
page.get_by_label("选择文件").click()
file_chooser = fc_info.value
file_chooser.set_files(r"D:\tou.png")
5.select下拉框
- 使用locator.select_option()选择元素中的一个或多个选项。
- 可以指定选项value选择。
- 可以选择多个选项。
# 选择一个选项,通过Value
page.locator("#TypeId").select_option("选项1")
# 选择多个选项
page.locator("#TypeId").select_option(['选项1','选项2','选项3'])
6.复选框和单选
- 使用 locator.set_checked() 是选中和取消选中复选框或单选按钮的最简单方法。
- input[type=checkbox]此方法可与, input[type=radio] 和元素一起使用 [role=checkbox]
# checkbox选中
page.locator("#checkboxFlag").check()
# 断言checkbox状态
assert page.locator("#checkboxFlag").is_checked() is True
# 单选按钮
page.get_by_lable('女').check()
7.focus()聚集指定元素
- 对于处理焦点事件的动态页面,您可以使用 locator.focus() 聚焦给定元素
page.get_by_label('password').focus()
8.drag_to 拖动
- 可以使用 locator.drag_to() 执行拖放操作
9.操作iframe
- iframe 是web自动化里面一个比较头疼的场景,在Selenium中处理 iframe 需要切换来切换去非常麻烦。
- 在playwright中,让其变得非常简单,我们在使用中无需切换iframe,直接定位元素即可。
- 示例:
frame = page.frame_locator('//iframe[contains(@id, "x-URS-iframe")]')
frame.locator('[name="email"]').fill('testemail')
frame.locator('[name="password"]').fill("123456")
frame.locator('#dologin').click()
- 当定位到多个时:
# 返回最后一个
frame_locator().last
# 返回第一个
frame_locator().first
# 可以使用index索引
frame_locator().nth(index)
10.screenshot截图
- playwright 除了可以截取当前屏幕,还可以截长图,也可以对某个元素截图
# 捕获屏幕截图并将其保存到文件中的快速方法
page.screenshot(path='screenshot.png')
# 截长图,设置 full_page=True 参数 screenshot 是一个完整的可滚动页面的屏幕截图
page.screenshot(path='screenshot.png',full_page=True)
# 捕捕获图片数据流,获取包含图像的缓冲区并对其进行后处理或将其传递给第三方像素差异工具,而不是写入文件。
screenshot_bytes = page.screenshot()
print(base64.b64encode(screenshot_bytes).decode())
# 截取单个元素
page.locator("#userPasswd").screenshot(path="screenshot.png")
11.文件下载download
- 使用示例
<h1>下载文件</h1>
<a href="https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.101/win64/chromedriver-win64.zip">点我下载</a>
- 关键代码示例:
with page.expect_download() as download_info:
page.get_by_text("点我下载").click()
download = download_info.value
print(download.url) # 获取下载的url地址
# 如果下载成功,则返回下载文件的路径
download.path()
# 保存到本地
download.save_as(download.suggested_filename)
- 其他download相关操作
# 取消下载
download.cancel()
# 删除下载的文件
download.delete()
# 返回下载错误
download.failure()
# 获取下载所属页面
download.page
# 下载路径
download.path()
# 将下载复制到用户指定的路径
download.sace_as(path)
# 返回此下载的建议文件名,由浏览器根据 Content-Disposition 响应标头或 download 属性计算得出
download.suggested_filename
# 返回下载的url
download.url
12.监听dialog处理弹出框
12.1 dialog事件监听
- 当出现 JavaScript
对话框时发出,例如alert,监听器必须dialog.accept()或dialog.dismiss()对话框 -
否则页面将冻结等待对话框。 - 注意:当没有监听器时,所有对话框都会自动关闭。
- 使用示例:
# 没监听时,自动会关闭
page.evaluate("alert('此操作不可撤销')")
def handle_dislog(dialog):
"""监听后处理"""
print(dialog.message)
dialog.dismiss()
with sync_playwright() as p:
browers = p.chromium.launch(headless=False)
page = browers.new_page()
page.goto("D:\Project\Studyplaywright\测试2.html")
# 有监听器时,必须处理对话框
page.on("dialog",handle_dislog)
page.evaluate("alert('此操作不可撤销')")
browers.close()
12.2 dialog属性和方法
# accept()当对话框被接受时返回
dialog.accept()
# default_value,如果对话框是提示的,则返回默认提示值。否则,返回空字符串。
dialog.default_value
# dismiss关闭对话框
dialog.dismiss()
# message获取对话框中显示的消息
dialog.message
# type返回对话框的类型
dialog.type
12.3 prompt提示框
<input id = "prompt" value = "prompt" type = "button" onclick = "var name = prompt('请输入微信公众号')" />
- 可以通过 dialog.type 判断到是 prompt 框,就可以给输入框输入内容
def handle_dialog(dialog):
"""监听后处理"""
print(dialog.message)
print(dialog.type)
print(dialog.default_value)
if dialog.type == 'prompt':
dialog.accept(prompt_text='hello world')
else:
dialog.dismiss()
page.on('dialog', handle_dialog)
page.evaluate("prompt('请输入微信公众号')")
13.hover()鼠标悬停
- 鼠标悬停到某个元素上后出现一些选项
page.locator("#id").hover()
14.定位多个元素
14.1 first和last
# 如果定位到多个元素,可以用first和last取第一个
page.locator('[type="checkbox"]').first # 第一个
page.locator('[type="checkbox"]').last #最后一个
14.2 nth()根据索引定位
page.locator('[type="checkbox"]').nth(0) # 第一个
page.locator('[type="checkbox"]').nth(2) # 第三个
14.3 count统计个数
page.locator('[type="checkbox"]').count() # 使用count可以统计元素的个数
14.4 all()定位全部
# all() 定位全部元素,批量操作
all = page.locator('[type="checkbox"]')
for loc in all.all():
loc.click()
15. locator.filter()过滤定位器
15.1 locator.filter()与locator().lacator()区别:
(1)locator().lacator()是从已经定位到的元素中,继续查询子元素或子孙元素
(2)locator.filter()是从已经定位到的元素中,根据选项缩小现有定位器的范围,可以按文本或定位器过滤。
15.2 has_text 参数使用
按文本过滤。它可以链接多次过滤。
page.locator('#s-top-left>a').filter(has_text="新闻").click()
# 等价于
page.locator('#s-top-left>a',has_text='新闻').click()
16.scroll 滚动到元素出到元素出现的位置
- 当页面超过屏幕的高度时候,需要滚动到元素出现的位置,让元素处于可视的窗口上才能去操作元素。
16.1 click 点击操作
- playwright在点击元素时,会自动滚动到元素出现的位置
16.2 滚动到元素出到元素出现位置
- 如果我们仅仅是让元素出现到窗口的可视范围,可以使用 scroll_into_view_if_needed()
方法,它会让元素出现在屏幕的正中间
page.get_by_text('分享').scroll_into_view_if_needed()
16.3 hover方法
- hover 方法是把鼠标放到元素上,它也会自动去页面上找到元素,让它出现在可视窗口。
page.get_by_text('分享').hover()
17.日历控件操作
- 遇到输入框是弹出日历控件,选一个日期的这种场景,可以直接在输入框输入内容。如果输入框是readonly的时候,可以用js改变输入框的属性。
(1)直接输入一个日期,如果能直接输入的情况,就不用点开了
page.locator('#date_day').fill('2021-04-01')
(2)readonly 的日的日历控件控件
<input type="text" id="birth_day" name="birthday" value="2023-04-02" readonly="readonly">
- 这种情况先要执行JavaScript 去掉元素的 readonly 属性,再输入JavaScript 操作日历控件。
# 去掉元素的readonly属性
js1 = 'document.getElementById("birth_day").removeAttribute("readonly");'
page.evaluate(js1)
# 直接给输入框赋值
js2 = 'document.getElementById("birth_day").value="2021-04-01";'
page.evaluate(js2)