实例讲解Playwright(一)
实例讲解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介绍
理念:Playwright enables reliable end-to-end testing for modern web apps
Playwright是一个web自动化测试框架
Playwright is a framework for Web Testing and Automation
支持所有的浏览器
- Test on Chromium, Firefox and WebKit. Playwright has full API coverage for all modern browsers, including Google Chrome and Microsoft Edge (with Chromium), Apple Safari (with WebKit) and Mozilla Firefox.
- Cross-platform WebKit testing. With Playwright, test how your app behaves in Apple Safari with WebKit builds for Windows, Linux and macOS. Test locally and on CI.
- Test for mobile移动端测试. Use device emulation to test your responsive web apps in mobile web browsers.
- Headless and headed有头无头模式. Playwright supports headless (without browser UI) and headed (with browser UI) modes for all browsers and all platforms. Headed is great for debugging, and headless is faster and suited for CI/cloud executions.
快速可靠的执行
- Auto-wait APIs 自动等待. Playwright interactions auto-wait for elements to be ready. This improves reliability and simplifies test authoring.
- Timeout-free automation. Playwright receives browser signals, like network requests, page navigations and page load events to eliminate the need for sleep timeouts that cause flakiness.
- Fast isolation with browser contexts. Reuse a single browser instance for multiple isolated execution environments with browser contexts.
- Resilient element locators. Playwright can rely on user-facing strings, like text content and accessibility attributes to locate elements. These locators are more resilient than selectors tightly-coupled to the DOM structure.
强大的自动化能力
- Multiple domains, pages and frames. Playwright is an out-of-process automation driver that is not limited by the scope of in-page JavaScript execution and can automate scenarios with multiple pages.
- Powerful network control. Playwright introduces context-wide network interception to stub and mock network requests.
- Modern web features. Playwright supports web components through shadow-piercing locators, geolocation, permissions, web workers and other modern web APIs.
- Capabilities to cover all scenarios. Support for file downloads and uploads, out-of-process iframes, native input events, and even dark mode.
②安装
建议在虚拟环境中操作,创建好虚拟环境
python -m venv venv_playwright
切换到该环境下
cd venv_playwright\Scripts\
activate.bat (venv_playwright) # 看到这个就表示切换成功了
执行如下命令
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip install --upgrade pip
pip install playwright # 安装第三方库
playwright install
③定位
定位在UI自动化测试的重要性不需要多说
示例html,搜罗了官网的一些example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PlaywrightDEMO</title>
</head>
<body>
<h3>Sign up</h3>
<label>
<input type="checkbox" /> Subscribe
</label>
<br/>
<button>Submit</button>
<hr>
<button>登录</button>
<span>Welcome, John</span>
<label>Password <input type="password" /></label>
<input type="email" placeholder="name@example.com" />
<img alt="playwright logo" src="playwright-logo.svg" width="100" />
<span title='Issues count'>25 issues</span>
<hr>
<ul>
<li>apple</li>
<li>banana</li>
<li>orange</li>
</ul>
<hr>
<iframe src="http://114.116.2.138:8090/forum.php" id='if' name='nf' width="600" height="600"></iframe>
</body>
</html>
get_by_系列定位
playwright的定位,个人觉得非常杂乱,其能力应是超过selenium的,但不太易学
get_by_有好多,仅供参考之用,返回对象也是Locator
定位方式 描述 page.get_by_role() role是标签名(但不是所见即所得),可以传递name参数 page.get_by_text() 标签文本 page.get_by_label() label标签名 page.get_by_placeholder() placeholder属性值 page.get_by_alt_text() alt属性值 page.get_by_title() title属性值 page.get_by_test_id() 略 示例代码1 get_by_role
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto(r'D:\pythonProject\AutoTest\DemoPlaywright0413\demos\demo.html')
print(page.get_by_role('button', name='登录').text_content()) # 定位的是<button>登录</button>
# 要注意的是,你定位
示例代码2 get_by_label
page.get_by_label('Password').fill('123456')
# 定位的是 <label>Password <input type="password" /></label>
示例代码3 get_by_placeholder
page.get_by_placeholder('name@example.com').fill('123456')
# 定位的是 <input type="email" placeholder="name@example.com" />
示例代码4 get_by_text ,注意可以结合re
print(page.get_by_text('Welcome, John').text_content())
import re
print(page.get_by_text(re.compile('welcome, john',re.IGNORECASE)).text_content())
# 定位的是 <span>Welcome, John</span>
示例代码5 get_by_alt_text
pic_bytes = page.get_by_alt_text("playwright logo").screenshot()
with open('log.png','wb') as f:
f.write(pic_bytes)
# get_by_alt_text("playwright logo") 定位的是 <img alt="playwright logo" src="playwright-logo.svg" width="100" />
# 定位到的
示例代码6 get_by_title
print(page.get_by_title("Issues count").text_content())
# 定位到的是 <span title='Issues count'>25 issues</span>
locator定位
你用的更多的应该是locator定位
locator可以配合css或者xpath实现定位,你有这些基础就很容易理解
举例
page.locator("css=button").click()
page.locator("button").click() page.locator("xpath=//button").click()
page.locator("//button").click() page.locator("text=立即注册").click() # 有点像 LINK_TEXT
示例html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Text</title>
</head>
<body>
<a href="https://www.qq.com">
QQ
</a>
<span id="sp" >SPAN</span>
</body>
</html>
示例代码
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto(r'D:\pythonProject\AutoTest\DemoPlaywright0413\demos\demo_text.html')
print(page.locator("text=QQ").get_attribute('href'))
print(page.locator("text=SPAN").get_attribute('id'))
可以看到playwright的定位不限于 link text,对普通的text也有定位能力
相对定位
- 跟selenium4一样,playwright也提供了相对定位
- 由于一般很少用,本文不阐述,但我也写了一个demo给你
- 具体可以参考
实例五: 相对定位
多元素处理
实际操作过程中一个定位表达式定位到多个元素是非常常见的情况,
实例三:获取百度热点
就是此类情况selenium对于定位到多个元素,如果用的是find_element,操作的是第一个元素
而playwright不可以!它有自己的一套处理方式。
我们来看一个示例,这里有好几个问题。
示例html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MultipleElement</title>
</head>
<body>
<ul>
<li class="item">apple</li>
<li class="item">banana</li>
<li class="item">orange</li>
</ul>
</body>
</html>
示例代码
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto(r'D:\pythonProject\AutoTest\DemoPlaywright0413\demos\MultipleElement.html')
print(page.get_by_role('li').text_content())
提示报错
playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for get_by_role("li")
============================================================
准确的来说这个提示仅仅告诉你了超时,但原因其实是你写的li,并不是一个合法的标签,你可以
参考附录:get_by_role所支持的标签
对于li标签你要写的是listitem,这里我们也能看出来get_by_role这样的方法的缺陷
修改代码如下
print(page.get_by_role('listitem').text_content())
还是错,提示如下
playwright._impl._api_types.Error: Error: strict mode violation: get_by_role("listitem") resolved to 3 elements:
1) <li class="item">apple</li> aka get_by_text("apple")
2) <li class="item">banana</li> aka get_by_text("banana")
3) <li class="item">orange</li> aka get_by_text("orange") =========================== logs ===========================
waiting for get_by_role("listitem")
============================================================
这次提示倒是比较清晰了,告诉你定位到了多个
如何解决?
方式一: filter by text
print(page.get_by_role('listitem').filter(has_text='apple').text_content())
- 也可以结合正则处理
import re
print(page.get_by_role('listitem').filter(has_text=re.compile('APPLE',re.IGNORECASE)).text_content())
方式二: count和nth
示例代码
count = page.locator('.item').count()
for index in range(count):
print(page.locator('.item').nth(index).text_content())
这里有点要注意的是,哪怕没有符合给定表达式的元素,这个count也不会报错
count = page.locator('.ob').count()
print(count) # 0
方式三: all
示例代码
elements = page.locator('.item').all() # 理解为所有的元素, 这就有点像
for element in elements: # 在元素中遍历
print(element.text_content())
.all()可以理解为定位到的所有的元素,就有点像find_elements的效果了
方式四: all_text_contents
示例代码
element_texts = page.locator('.item').all_text_contents()
for element_text in element_texts:
print(element_text)
这个属性更多用于获取元素的文本,如果要依次点击元素,还是要用上面的方式三
实例讲解Playwright(一)的更多相关文章
- float实例讲解
float实例讲解 float是个强大的属性,在实际前端开发过程中,人们经常拿它来进行布局,但有时,使用的不好,也麻烦多多啊. 比如,现在我们要实现一个两列布局,左边的列,宽度固定:右边的列,宽度自动 ...
- S3C2440上RTC时钟驱动开发实例讲解(转载)
嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 共享资源,欢迎转载:http:/ ...
- 实例讲解Oracle数据库设置默认表空间问题
实例讲解Oracle数据库设置默认表空间问题 实例讲解Oracle数据库设置默认表空间问题,阅读实例讲解Oracle数据库设置默认表空间问题,DBA们经常会遇到一个这样令人头疼的问题:不知道谁在O ...
- 基于tcpdump实例讲解TCP/IP协议
前言 虽然网络编程的socket大家很多都会操作,但是很多还是不熟悉socket编程中,底层TCP/IP协议的交互过程,本文会一个简单的客户端程序和服务端程序的交互过程,使用tcpdump抓包,实例讲 ...
- makefile基础实例讲解 分类: C/C++ 2015-03-16 10:11 66人阅读 评论(0) 收藏
一.makefile简介 定义:makefile定义了软件开发过程中,项目工程编译链.接接的方法和规则. 产生:由IDE自动生成或者开发者手动书写. 作用:Unix(MAC OS.Solars)和Li ...
- 实例讲解Linux系统中硬链接与软链接的创建
导读 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接.硬链接与软链接的区别从根本上要从Inode节点说 ...
- spring事务传播机制实例讲解
http://kingj.iteye.com/blog/1680350 spring事务传播机制实例讲解 博客分类: spring java历险 天温习spring的事务处理机制,总结 ...
- 实例讲解MySQL联合查询
好了终于贴完了MySQL联合查询的内容了,加上上一篇一共2篇,都是我转载的,实例讲解MySQL联合查询.那下面就具体讲讲简单的JOIN的用法了.首先我们假设有2个表A和B,他们的表结构和字段分别为: ...
- Html代码seo优化最佳布局实例讲解
搜索引擎对html代码是非常优化的,所以html的优化是做好推广的第一步.一个符合seo规则的代码大体如下界面所示. 1.<!–木庄网络博客–> 这个东西是些页面注释的,可以在这里加我的& ...
- 【MySQL】分页查询实例讲解
MySQL分页查询实例讲解 1. 前言 本文描述了团队在工作中遇到的一个MySQL分页查询问题,顺带讲解相关知识点,为后来者鉴.本文的重点不是"怎样"优化表结构和SQL语句,而是探 ...
随机推荐
- antv g6 中自定义tooltip 当有该属性时展示没有时不展示
getContent(e) { const outDiv = document.createElement('div'); outDiv.style.width = '180px'; outDiv.i ...
- vite设置跨域
1. vite.config.ts或者vite.config.js文件 server: { port: 3001, host: '0.0.0.0', open: true, proxy: { // 代 ...
- MP逻辑删除
在实体类中加上@TableLogic注解 在配置类中加入逻辑删除插件
- 记安装MySQL数据库
记录一次自己动手安装MySQL数据库所踩的坑 MySQL安装包与操作系统匹配 安装包有amd和Intel,32位.64位多种组合需要确认仔细使用者操作系统和CPU型号 例如我使用的是CentOS ...
- [cisco]Configure private VLAN
vlan 100 private-vlan isolated ! vlan 200 private-vlan community ! vlan 300 private-vlan primary pri ...
- 前端复习之JavaScript(ECMAScript5)
啦啦啦啦啦啦啦啦绿绿绿绿绿绿 1 1.JavaScript: 2 前段三大语言:HTML CSS js 3 HTML:专门编写网页内容的语言 4 CSS:专门编写网页样式的语言 5 js:专门编写网页 ...
- Unity 2D Sprite 俯视角渲染顺序设置
今天结合网上的一个教程复习了一下Unity中2D俯视角游戏的渲染顺序设置. 首先是在Hierachy中的摆放顺序,靠下的物体渲染顺序靠后: 然后是Sprite Renderer组件,可以通过组件中的S ...
- Python项目案例开发从入门到实战-1.2 Python语法基础
书籍信息 1.2 Python语法基础 1.2.1 Python数据类型 数值类型 整型(int):浮点型(float):复数(complex),以j或J结尾,如2+3j 字符串 布尔类型 空值,用N ...
- Git添加SSH密钥步骤
1.先去本机上面看看用户主目录里面有没有.ssh这个文件夹 如果有的话,再看看该目录下有没有id_rsa和id_rsa_pub这两个文件: 若还是有,就直接跳过这一步到下一步:若是没有,我们需要创建S ...
- 关于js通过修改行内样式来修改元素样式
关于js通过修改行内样式来修改元素样式 1.当我们通过使用js来修改html元素的样式时,使用的方法是为元素添加行内样式, 此时的js样式是生效的,因为行内样式优先级高于类名 2.如果已有同属性的行内 ...