微软出品的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 ...
随机推荐
- 关于nth-of-type的注意事项
普通使用 nth-of-type: <div class="box"> <div> 第一个元素 </div> <p>没有用的元素&l ...
- linux行去重的一种方法
awk '{x[$0]++}END{for(i in x)print i}' newsub > newsub2// orcat oldword| awk -F "\t" ' ...
- ABPvNext修改密码强度
ABPvNext 5.0之后,一些原有的修改密码强度的办法已经被抛弃无法正确使用.目前亲测有效的办法只有通过配置管理修改密码强度. 这里配置文件设置配置的方式,更多方法,可参见官方文档中的Settin ...
- .net创建、发布、引用webservice项目
创建webservice引用 增加代码: 运行如下: 之后就可以发布我们的项目了,右击项目,选择发布: 此地址不要选择项目地址,另外创建一个地址: 至此,发布成功,接下来iis增加web网站: 这里i ...
- centos7所有用户循环登录
1 使用快捷键Ctrl+Alt+F2进入命令终端 2 输入账号密码 3 输入 /usr/bin/sudo 4 输入 startx 那种单用户,改配置的试了没有用
- 我在迁移我的IDEA的项目、模块等东西的过程中发生过的一部分问题的我的一部分的记录以及我的解决方案如下
使用idea2019阶段报的一些错: 1.'xxxServlet' is not assignable to 'javax.servlet.Servlet' 解决方案:把tomcat加入classpt ...
- win10开启休眠
powercfg /hibernate on 管理员模式下的命令提示符
- python-if、while、for语句的练习
简单练习 1. 根据百分制成绩打印及格和不及格,60分一下不及格 source = float(input('请输入您的成绩:')) if 0 <= source < 60: print( ...
- 10 个杀手级的 Python 自动化脚本
重复性任务总是耗时且无聊,想一想你想要一张一张地裁剪 100 张照片或 Fetch API.纠正拼写和语法等工作,所有这些任务都很耗时,为什么不自动化它们呢?在今天的文章中,我将与你分享 10 个 P ...
- ChatGPT 何许人也
有时候会想,如果chatGPT是人,它会是一个怎样的人呢?下面是我的推测过程. 首先,她应该是女人 会推测而不会计算 你问它: 3457 * 43216 = ,它回答 149261912 (这是错的. ...