实例讲解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.

强大的自动化能力

②安装

  • 建议在虚拟环境中操作,创建好虚拟环境

    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(一)的更多相关文章

  1. float实例讲解

    float实例讲解 float是个强大的属性,在实际前端开发过程中,人们经常拿它来进行布局,但有时,使用的不好,也麻烦多多啊. 比如,现在我们要实现一个两列布局,左边的列,宽度固定:右边的列,宽度自动 ...

  2. S3C2440上RTC时钟驱动开发实例讲解(转载)

    嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 共享资源,欢迎转载:http:/ ...

  3. 实例讲解Oracle数据库设置默认表空间问题

    实例讲解Oracle数据库设置默认表空间问题   实例讲解Oracle数据库设置默认表空间问题,阅读实例讲解Oracle数据库设置默认表空间问题,DBA们经常会遇到一个这样令人头疼的问题:不知道谁在O ...

  4. 基于tcpdump实例讲解TCP/IP协议

    前言 虽然网络编程的socket大家很多都会操作,但是很多还是不熟悉socket编程中,底层TCP/IP协议的交互过程,本文会一个简单的客户端程序和服务端程序的交互过程,使用tcpdump抓包,实例讲 ...

  5. makefile基础实例讲解 分类: C/C++ 2015-03-16 10:11 66人阅读 评论(0) 收藏

    一.makefile简介 定义:makefile定义了软件开发过程中,项目工程编译链.接接的方法和规则. 产生:由IDE自动生成或者开发者手动书写. 作用:Unix(MAC OS.Solars)和Li ...

  6. 实例讲解Linux系统中硬链接与软链接的创建

    导读 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接.硬链接与软链接的区别从根本上要从Inode节点说 ...

  7. spring事务传播机制实例讲解

    http://kingj.iteye.com/blog/1680350   spring事务传播机制实例讲解 博客分类:   spring java历险     天温习spring的事务处理机制,总结 ...

  8. 实例讲解MySQL联合查询

    好了终于贴完了MySQL联合查询的内容了,加上上一篇一共2篇,都是我转载的,实例讲解MySQL联合查询.那下面就具体讲讲简单的JOIN的用法了.首先我们假设有2个表A和B,他们的表结构和字段分别为: ...

  9. Html代码seo优化最佳布局实例讲解

    搜索引擎对html代码是非常优化的,所以html的优化是做好推广的第一步.一个符合seo规则的代码大体如下界面所示. 1.<!–木庄网络博客–> 这个东西是些页面注释的,可以在这里加我的& ...

  10. 【MySQL】分页查询实例讲解

    MySQL分页查询实例讲解 1. 前言 本文描述了团队在工作中遇到的一个MySQL分页查询问题,顺带讲解相关知识点,为后来者鉴.本文的重点不是"怎样"优化表结构和SQL语句,而是探 ...

随机推荐

  1. 运行python脚本报错SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape

    运行python脚本报错 SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes  in position 2-3: ...

  2. Kafka源码阅读系列——Producer

    Producer Kafka源码的exmaple模块有一个Producer类,继承了Thread类,构造方法会指定topic,是否异步,是否幂等,配置Kafka集群信息,初始化一个KafkaProdu ...

  3. [cisco][LAB]OSPF in NBMA

    NBMA為一種沒有廣播類型的的網路連接,這會使得OSPF建立需要手動設定 拓樸如下: R1# ! interface Loopback0 ip address 172.16.1.1 255.255.2 ...

  4. beamforming源码标记

    p:各阵元的声压信号矩阵 R:接收数据的自协方差矩阵 Pcbf:交叉谱矩阵

  5. [C# 学习笔记]运用 GDI+ 的 Matrix 进行显示图形的平移和缩放

    C# 学习中,想尝试着做一个工控方面的上位机,可以读取CAD绘制的图形,然后把它显示出来,后面让运动控制器去走CAD里面的轨迹. 一.用netDXF 开源包,对DXF文件进行解析.解析后的直线.圆.圆 ...

  6. Linux 截图快捷键 - 搬运

    Linux 截图快捷键 转自:linux 截图快捷键 环境 Linux Mint  21.1 1. Prt ScSysRq ---->全屏截图2. Shift+Prt ScSysRq ----& ...

  7. Checkmk监控工具使用手册

    其实用法Checkmk官网文档很全面:https://docs.checkmk.com/latest/en/intro_setup.html 顺着beginner's guide章节看完基本就能上手, ...

  8. Docker下部署LNMP黄金架构

    一.部署lnmp 1.网络规划 172.16.10.0/24nginx:172.16.10.10mysql:172.16.10.20php:172.16.10.30网站访问主目录:/wwwrootng ...

  9. App 用户新体验——Agora Native SDK 3.4.0

    声网Agora Native SDK 3.4.0 本月已正式上线.新版本不仅增加了更丰富的实时美声音效.屏幕共享.虚拟节拍器等功能,同时在 SDK 的稳定性.兼容性及安全合规上做了大幅度升级,希望为 ...

  10. WPF监听快捷键的几种方式

    调用Win32 API(优先级最高,全局监听, 支持最小化失焦等情况) 那么,假如我要在一个WPF程序监听CTRL+5按键,首先在主窗口程序添加以下代码: /// <summary> // ...