实例讲解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. Web_Servlet四大域对象

    保存数据的对象作用于从大到小: ServletContext -- 保存数据到web项目中 Session(会话对象)  -- Request -- 保存当前请求(链),有转发就保存包括转发的数据 P ...

  2. MySQL_20200417

    MySQL安装与卸载 SQL语句与Oracle大致相同 主要使用 Navicat for MySQL进行数据库操作 MySQL常用的命令: 登录:mysql -uroot -p  /mysql -ur ...

  3. cadence-ADE反相器仿真

    Cadence-ADE仿真 连接电路 鼠标移至schematic绘制区域,单击放置inv i键继续添加gnd, vdc(3.3V), vpulse(0-3.3V,Period 1us,Pulse wi ...

  4. pip下载时使用国内镜像 设置pip.ini文件

    https://blog.csdn.net/u011107575/article/details/109901086 https://www.python.org/ftp/python/https:/ ...

  5. 利用shell脚本提高访问GitHub速度

    Github由于做了域名限制,所以访问比较慢,编写了个脚本达到做本地域名解析提高GitHub的访问速度 #!/usr/bin/env bash # 该脚本用来提升github的访问速度 ROOT_UI ...

  6. UG二次开发-CAM-执行方式

    以C#开发为例,通常先用[操作记录]功能录制关键代码,得到一个.cs文件. (1)可以直接使用[播放操作记录]的方式执行该.cs文件. (2)可以建立一个C#的类库工程,将上述.cs文件加载进去,添加 ...

  7. 6-SSRF漏洞

    1.SSRF漏洞介绍 SSRF是一种由攻击者构造请求,由服务端发起请求的安全漏洞.一般情况下,ssrf攻击的目标是外网无法访问的内部系统. 2.SSRF原理 Ssrf的形成大多是由于服务端提供了从其他 ...

  8. PerfDog的使用教程

    一.介绍: 移动全平台iOS/Android性能测试.分析工具平台,快速定位分析性能问题.PerfDog支持移动平台所有应用程序(游戏.APP应用.浏览器.小程序.小游戏.H5.后台系统进程等).An ...

  9. LP两阶段法(一阶段)

    \begin{equation}\begin{aligned}\min \quad & z=\mathbf{c}^{T} \mathbf{x} \\\text { s.t. } & \ ...

  10. 《MySQL是怎样运行的》第七章小结