微软出品的UI自动化测试工具Playwright(三)
微软出品的UI自动化测试工具Playwright(三)
| 网址 | 说明 |
|---|---|
| https://playwright.dev/ | 官网首页 |
| https://playwright.dev/python/docs/intro | Python部分入口 |
| https://github.com/microsoft/playwright-python | github,python入口 |
| https://github.com/microsoft/playwright-python/releases | python部分的release notes |
本文基于 playwright 1.32.1 发布于 2023-3-30
学习前你得有html、css、xpath等基础,最好有selenium基础,我是对比来讲解的
⑤实例
通过一个个实例来讲述Playwright的能力
实例一: 打开某某网站
参考代码
from playwright.sync_api import sync_playwright with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
执行效果:打开百度后自动关闭
对比selenium,这是有点麻烦的
playwright是个包(文件夹),里面主要是3个部分
- sync_api:同步,入门你用的最多的是这个
- driver
- async_api:异步
sync_playwright是一个函数,返回值类型是PlaywrightContextManager
def sync_playwright() -> PlaywrightContextManager:
return PlaywrightContextManager()
从名字上看得出是个上下文管理器,所以你可以用with来处理
钻进去你能看到__enter__和__exit def __enter__(self) -> SyncPlaywright:
而这个SyncPlaywright是有很多属性的,主要的就是我们要打开的几个浏览器
def chromium(self) -> "BrowserType":
"""Playwright.chromium This object can be used to launch or connect to Chromium, returning instances of `Browser`. Returns
-------
BrowserType
"""
return mapping.from_impl(self._impl_obj.chromium) def firefox(self) -> "BrowserType":
def webkit(self) -> "BrowserType":
BrowserType则是浏览器类型类,它的launch方法是重要的方法,参数非常多,一般用到的就是headless,赋值False就是有头(能看到页面)。返回的是浏览器实例。
在playwright中你仅有一个浏览器实例是作不了什么的,你必须要打开一个页面
Browser有一些方法属性,其中new_page是用来打开新的页面的,返回类型是Page
玩过selenium的同学应该知道,Page对象是你最多了解的部分
Page对象属性方法详见附录一
实例二: 登录开源论坛
前面了解了打开网页
下面就涉及UI自动化测试最重要的定位了
参考代码
from playwright.sync_api import sync_playwright with sync_playwright() as p:
browser_type = p.chromium
browser = browser_type.launch(headless=False)
page = browser.new_page()
page.goto("http://114.116.2.138:8090/forum.php")
page.locator('#ls_username').fill('admin')
page.locator('#ls_password').fill('123456')
page.locator('.pn.vm').click()
page.wait_for_timeout(5000)
可以看到我们使用了css语法来定位
page对象的locator方法中就可以去塞一个css表达式来定位元素
而这个元素也是非常重要的对象,其类型是Locator,这个对象的属性方法可以参考附录二
此处的等待要注意,在页面上等待不建议使用time.sleep,而是应该用page的wait_for_timeout
参考代码2
from playwright.sync_api import sync_playwright with sync_playwright() as p:
browser_type = p.chromium
browser = browser_type.launch(headless=False)
page = browser.new_page()
page.goto("http://114.116.2.138:8090/forum.php")
page.fill('#ls_username','admin')
page.fill('#ls_password','123456')
page.click('.pn.vm')
page.wait_for_timeout(5000)
的确,locator都可以省略的,直接在fill或者click上写表达式
实例三: 获取百度热点
参考代码
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto('https://www.baidu.com')
hot_news = page.locator('.title-content-title').all_text_contents()
for hot_new in hot_news:
print(hot_new)
上述代码是ok的,但是你如果从selenium转过来,是比较别扭的
因为page.locator('.title-content-title')定位元素在实例二中提到了,但此处表达式.title-content-title是有多个元素的
在selenium中如果定位到了多个,你操作的是第一个,但playwright用locator的做法不一样,这多少有点不习惯。
此处all_text_contents()的返回是个list,其内容就是我们热点的文本信息
['红树林边的瞩望', '带你体验中老友谊之旅', '中央转移支付首破十万亿 钱去哪儿了', '云南玉溪山火蔓延 火场燃烧迅猛', '银行发现7位数存款5年未动急寻人', '台媒:大陆禁航从27分钟变6小时']
我们可以看看如果定位到一个元素的话,它的输出是没问题的
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto('https://www.baidu.com')
# .hotsearch-item:nth-child(1) .title-content-title 这个表达式就定位到一个元素
hot_news = page.locator('.hotsearch-item:nth-child(1) .title-content-title')
print(hot_news.text_content())
如果你定位到多个元素,就不行了
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto('https://www.baidu.com')
hot_news = page.locator('.title-content-title')
print(hot_news.text_content())
Traceback (most recent call last):
File "D:\pythonProject\AutoTest\DemoPlaywright0413\demos\demo_openpage.py", line 7, in <module>
print(hot_news.text_content())
File "D:\pythonProject\AutoTest\DemoPlaywright0413\venv\lib\site-packages\playwright\sync_api\_generated.py", line 17562, in text_content
self._sync(self._impl_obj.text_content(timeout=timeout))
File "D:\pythonProject\AutoTest\DemoPlaywright0413\venv\lib\site-packages\playwright\_impl\_sync_base.py", line 104, in _sync
return task.result()
File "D:\pythonProject\AutoTest\DemoPlaywright0413\venv\lib\site-packages\playwright\_impl\_locator.py", line 564, in text_content
return await self._frame.text_content(
File "D:\pythonProject\AutoTest\DemoPlaywright0413\venv\lib\site-packages\playwright\_impl\_frame.py", line 605, in text_content
return await self._channel.send("textContent", locals_to_params(locals()))
File "D:\pythonProject\AutoTest\DemoPlaywright0413\venv\lib\site-packages\playwright\_impl\_connection.py", line 61, in send
return await self._connection.wrap_api_call(
File "D:\pythonProject\AutoTest\DemoPlaywright0413\venv\lib\site-packages\playwright\_impl\_connection.py", line 461, in wrap_api_call
return await cb()
File "D:\pythonProject\AutoTest\DemoPlaywright0413\venv\lib\site-packages\playwright\_impl\_connection.py", line 96, in inner_send
result = next(iter(done)).result()
playwright._impl._api_types.Error: Error: strict mode violation: locator(".title-content-title") resolved to 6 elements:
1) <span class="title-content-title">红树林边的瞩望</span> aka get_by_role("link", name=" 红树林边的瞩望")
2) <span class="title-content-title">带你体验中老友谊之旅</span> aka get_by_role("link", name="3 带你体验中老友谊之旅")
3) <span class="title-content-title">中央转移支付首破十万亿 钱去哪儿了</span> aka get_by_role("link", name="1 中央转移支付首破十万亿 钱去哪儿了")
4) <span class="title-content-title">云南玉溪山火蔓延 火场燃烧迅猛</span> aka get_by_role("link", name="4 云南玉溪山火蔓延 火场燃烧迅猛")
5) <span class="title-content-title">银行发现7位数存款5年未动急寻人</span> aka get_by_role("link", name="2 银行发现7位数存款5年未动急寻人")
6) <span class="title-content-title">台媒:大陆禁航从27分钟变6小时</span> aka get_by_role("link", name="5 台媒:大陆禁航从27分钟变6小时") =========================== logs ===========================
waiting for locator(".title-content-title")
============================================================ 进程已结束,退出代码为 1
- 然playwright还有一些其他的定位方法
实例四: 验证码破解登录
参考代码
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto('http://121.5.150.55:8090/forum.php')
page.locator('#ls_username').fill('admin')
page.locator('#ls_password').fill('123456')
page.locator('.pn.vm').click()
code_bytes = page.locator("[id^='vseccode_cSA']>img").screenshot()
import ddddocr
ocr = ddddocr.DdddOcr()
code_text = ocr.classification(code_bytes)
page.locator("input[id^='seccodeverify_cSA']").fill(code_text)
page.locator("[name='loginsubmit']").click()
在这个案例中,我们主要用到了元素的screenshot(),返回的是一个bytes对象
然后经过ddddocr处理可以得到其文本
实例五: 相对定位
仅供参考
实例代码
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto('http://121.41.14.39:8088/index.html')
page.locator('input:above(#password)').fill('sq1')
page.locator('#password:near(#username)').fill('123')
page.locator('#code:left-of(img)').fill('999999')
page.locator('#submitButton:below(#code)').click()
page.wait_for_timeout(5000)
实例六: 论坛的悬停登录
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto('http://114.116.2.138:8090/forum.php')
qmenu_locator = page.locator('#qmenu')
qmenu_locator.hover()
page.click('.xi2>strong')
page.fill('[id^=username_L]','admin')
page.fill('[id^=password3_L]','123456')
page.click('[name=loginsubmit].pn.pnc')
page.wait_for_timeout(5000)
实例七: 论坛的发帖
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto('http://114.116.2.138:8090/forum.php')
page.fill('#ls_username','admin')
page.fill('#ls_password','123456')
page.keyboard.press('Enter')
page.wait_for_timeout(2000)
page.click('text=默认版块')
page.click('css=#newspecial')
page.fill('#subject','帖子标题')
page.frame_locator('#e_iframe').locator('#editorheader+body').fill('帖子内容') #frame切换
page.click('#postsubmit')
page.wait_for_timeout(5000)
附录
Page对象属性方法
| 属性 | 说明 |
|---|---|
| accessibility | 可访问性 |
| add_init_script | |
| add_script_tag | |
| add_style_tag | |
| bring_to_front | |
| check | |
| click | |
| close | |
| content | |
| context | 上下文 |
| dblclick | 双击 |
| dispatch_event | |
| drag_and_drop | |
| emulate_media | |
| eval_on_selector | |
| eval_on_selector_all | |
| evaluate | |
| evaluate_handle | |
| expect_console_message | |
| expect_download | |
| expect_event | |
| expect_file_chooser | |
| expect_navigation | |
| expect_popup | |
| expect_request | |
| expect_request_finished | |
| expect_response | |
| expect_websocket | |
| expect_worker | |
| expose_binding | |
| expose_function | |
| fill | |
| focus | |
| frame | |
| frame_locator | |
| frames | |
| get_attribute | |
| get_by_alt_text | |
| get_by_label | |
| get_by_placeholder | |
| get_by_role | |
| get_by_test_id | |
| get_by_text | |
| get_by_title | |
| go_back | |
| go_forward | |
| goto | 跳转到指定页面 |
| hover | |
| inner_html | |
| inner_text | |
| input_value | |
| is_checked | |
| is_closed | |
| is_disabled | |
| is_editable | |
| is_enabled | |
| is_hidden | |
| is_visible | |
| keyboard | 键盘操作入口,返回Keyboard |
| locator | 定位元素 |
| main_frame | |
| mouse | 鼠标操作入口,返回Mouse |
| on | |
| once | |
| opener | |
| pause | |
| press | |
| query_selector | |
| query_selector_all | |
| reload | 页面刷新 |
| remove_listener | |
| request | |
| route | |
| route_from_har | |
| screenshot | 截图 |
| select_option | |
| set_checked | |
| set_content | |
| set_default_navigation_timeout | |
| set_default_timeout | |
| set_extra_http_headers | |
| set_input_files | |
| set_viewport_size | |
| tap | |
| text_content | |
| title | 标题 |
| touchscreen | |
| type | |
| uncheck | |
| unroute | |
| url | url |
| video | |
| viewport_size | |
| wait_for_event | |
| wait_for_function | |
| wait_for_load_state | |
| wait_for_selector | |
| wait_for_timeout | 等待,参数是毫秒,float |
| wait_for_url | |
| workers |
Locator对象属性方法
| 属性 | 说明 |
|---|---|
| all | 所有元素 |
| all_inner_texts | |
| all_text_contents | 所有文本内容 |
| blur | |
| bounding_box | |
| check | |
| clear | 清空 |
| click | 点击 |
| count | 元素个数 |
| dblclick | 双击 |
| dispatch_event | |
| drag_to | 拖拽 |
| element_handle | |
| element_handles | |
| evaluate | |
| evaluate_all | |
| evaluate_handle | |
| fill | 输入内容 |
| filter | |
| first | |
| focus | |
| frame_locator | |
| get_attribute | |
| get_by_alt_text | 通过alt属性的文本定位 |
| get_by_label | |
| get_by_placeholder | |
| get_by_role | |
| get_by_test_id | |
| get_by_text | |
| get_by_title | |
| highlight | |
| hover | |
| inner_html | |
| inner_text | |
| input_value | |
| is_checked | |
| is_disabled | |
| is_editable | |
| is_enabled | |
| is_hidden | |
| is_visible | |
| last | |
| locator | |
| nth | 下标 |
| on | |
| once | |
| page | |
| press | |
| remove_listener | |
| screenshot | 元素截图 |
| scroll_into_view_if_needed | |
| select_option | |
| select_text | |
| set_checked | |
| set_input_files | |
| tap | |
| text_content | |
| type | |
| uncheck | |
| wait_for |
get_by_role所支持的标签
[
"alert",
"alertdialog",
"application",
"article",
"banner",
"blockquote",
"button",
"caption",
"cell",
"checkbox",
"code",
"columnheader",
"combobox",
"complementary",
"contentinfo",
"definition",
"deletion",
"dialog",
"directory",
"document",
"emphasis",
"feed",
"figure",
"form",
"generic",
"grid",
"gridcell",
"group",
"heading",
"img",
"insertion",
"link",
"list",
"listbox",
"listitem",
"log",
"main",
"marquee",
"math",
"menu",
"menubar",
"menuitem",
"menuitemcheckbox",
"menuitemradio",
"meter",
"navigation",
"none",
"note",
"option",
"paragraph",
"presentation",
"progressbar",
"radio",
"radiogroup",
"region",
"row",
"rowgroup",
"rowheader",
"scrollbar",
"search",
"searchbox",
"separator",
"slider",
"spinbutton",
"status",
"strong",
"subscript",
"superscript",
"switch",
"tab",
"table",
"tablist",
"tabpanel",
"term",
"textbox",
"time",
"timer",
"toolbar",
"tooltip",
"tree",
"treegrid",
"treeitem",
]
元素状态
| 元素状态(英) | 元素状态(中) | 说明(英) |
|---|---|---|
| Attached | 附着 | Element is considered attached when it is connected to a Document or a ShadowRoot. |
| 元素连接到DOM或者ShadowRoot则认为元素是附着的 | ||
| Visible | 可见 | Element is considered visible when it has non-empty bounding box and does not have visibility:hidden computed style. Note that elements of zero size or with display:none are not considered visible. |
元素的可见意味着它有边界并且没有visibility:hidden,注意元素大小为0或者具有 display:none则认为是不可见的 |
||
| Stable | 稳定的 | Element is considered stable when it has maintained the same bounding box for at least two consecutive animation frames |
| 元素在至少两个连续的动画帧中保持相同的边界框时被认为是稳定的 | ||
| Enabled | 使能 | Element is considered enabled unless it is a <button>, <select>, <input> or <textarea> with a disabled property. |
元素如果是 <button>, <select>, <input> or <textarea>且具有disabled属性就认为是非使能的,否则都是使能的 |
||
| Editable | 可编辑 | Element is considered editable when it is enabled and does not have readonly property set. |
元素是可编辑的,意味着它一定是使能的且没有readonly属性 |
||
| Receivces Events | 接收事件 | element is considered receiving pointer events when it is the hit target of the pointer event at the action point. For example, when clicking at the point (10;10), Playwright checks whether some other element (usually an overlay) will instead capture the click at (10;10) |
微软出品的UI自动化测试工具Playwright(三)的更多相关文章
- Selenide 阶段性总结介绍(UI自动化测试工具)
今天给大家介绍一个比较新的UI自动化测试工具-- Selenide.确实是比较新的,国内应该还没有多少人用它.在百度和google上你只能搜到一个中文帖子简单介绍了一下.如果你想用这个工具,不可避免的 ...
- Airtest网易开源的一款UI自动化测试工具
Airtest网易开源的一款UI自动化测试工具 1 Airtest 简介Airtest Project是网易游戏内部工具团队开发并开源的一款UI自动化测试工具,据说曾经获得谷歌力挺. AirtestI ...
- 非常好用的1款UI自动化测试工具:airTest
网易团队开发的UI自动化测试神器airTest,下载地址:http://airtest.netease.com/tutorial/Tutorial.html Appium和airTest对比,我的看法 ...
- 网易UI自动化测试工具Airtest中导入air文件中的方法
最近看了一下网易的Airtest ,UI测试工具,写了一些后在导入其他air文件中的.py文件,卡了一下,现在博客中纪录一下导入其他air文件的方式: 在Airtest 测试工具中,导入其他air文件 ...
- UI 自动化测试工具BackstopJS简介(1)
BackstopJS源码地址 https://github.com/garris/BackstopJS 我写了一个DEMO放到github上面,https://github.com/shenggen1 ...
- 微软出品自动化神器Playwright,不用写一行代码(Playwright+Java)系列(一) 之 环境搭建及脚本录制
一.前言 半年前,偶然在视频号刷到某机构正在直播讲解Playwright框架的使用,就看了一会,感觉还不错,便被种草,就想着自己有时间也可以自己学一下,这一想着就半年多过去了. 读到这,你可能就去百度 ...
- <自动化测试方案_7>第七章、PC端UI自动化测试
第七章.PC端UI自动化测试 UI自动化测试又分为:Web自动化测试,App自动化测试.微信小程序.微信公众号UI层的自动化测试工具非常多,比较主流的是UFT(QTP),Robot Framework ...
- 使用WatiN进行UI自动化测试
Watin是一个UI自动化测试工具,支持ie/firefox,官方网站:http://watin.org/. 主要有以下特点: 支持主要的html元素,见:http://watin.org/docum ...
- 如何正确选择UI自动化测试
近年流行一个词-UI,和UI搭边好像都那么高大上,软件测试行业也不例外,比如UI自动化测试. 常见的UI自动化测试程序有哪些呢? l 带UI的Unit Test,比如mock掉底层代码,仅仅测试UI ...
- 微软自动化测试工具palywright
前言 我们介绍许多e2e的自动化测试工具 一类是基于 Selenium 的测试框架: robot framework gauge SeleniumBase seldom(我自己维护的) 另一类是基于J ...
随机推荐
- django_设计模式和模板层
一.django的设计模式 1.传统MVC设计模式 (1)MVC(Model-View-Controller,模型-视图-控制器)模式. M--模型层,主要用于对数据库的封装: V--视图层,用于向用 ...
- c# 连接SQLite 查询数据 写入txt文本
using Newtonsoft.Json.Linq; using System; using System.Data.SQLite; using System.IO; namespace @publ ...
- 负数位运算的右移操作-C语言基础
这一篇探讨的是"负数位运算的右移操作",涉及到数据的源码.反码.补码的转换操作.属于C语言基础篇. 先看例子 #include <stdio.h> int main(v ...
- linux查看IP地址
方法一:ifconfig -a 方法二:ip addr
- MobaXterm注册认证版,亲测可用,操作简单(本机已安装python3环境)
去github地址下下载代码 解压后在该目录下打开CMD 执行MobaXterm-Keygen.py <UserName> <Version>命令 生成的文件放在安装目录下,我 ...
- React支持less操作
React支持less操作 1.执行暴漏命令 npm run eject 2.输入" Y " 确认 这时候发现config文件夹没暴漏出来,是因为git没有暂存,得执行如下命令: ...
- ubuntu14.04 cm12.0 genymotion
前几天在ubuntu14.04编译过android5.0.1源码,但是呢?不知怎么运行不起来,后来又试了试把img文件在win平台运行虚拟机不知怎么还是不行,再后来想通过刷机运行学习framework ...
- 谷歌翻译不能用解决办法(谷歌翻译关闭后,如何继续使用Chrome浏览器的翻译功能?)
1.查找 IP 虽然谷歌不再提供 translate.google.cn 网页版的服务了,但谷歌翻译的 API 服务还在. 只需要通过 hosts 重定向至国内服务器,即可恢复使用. 1.Ping ...
- baodoumi mybaitplus自增很大问题
参考: https://blog.csdn.net/u012019209/article/details/124585933 @TableId(type = IdType.AUTO) private ...
- 文件的上传&预览&下载学习(四)
0.参考博客 https://blog.csdn.net/Chengzi_comm/article/details/53037967 逻辑清晰 https://blog.csdn.net/alli09 ...