实例讲解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. springMVC的定时器

    大家好,本人从事软件行业已有8年,大部分时间从事软件开发编写工作.好了废话少说了哈哈哈,直接干货. 在Java开发过程中有很多业务需求里面需要我们实时处理一些动态的业务比如库存的数据动态更新,实时数据 ...

  2. 1vue模板语法

    <body> <div id="app1"> <div>{{msg}}</div> </div> <script ...

  3. algorithm learning for Leetcode (1)

    Leetcode 算法学习(一) 前言:最近学校要求必须学习C++,着重提升技能板块.为了快速升级,我在GitHub上发现了一个开源的学习号召: https://labuladong.github.i ...

  4. MySQL -my.cnf配置文件优化

    # [mysqld] datadir=/var/lib/mysql #socket=/var/lib/mysql/mysql.sock user=mysql ### 设置主从的时候的唯一ID 每台主机 ...

  5. C# .netCore 上传文件到ftps/ftp

    白码一号的博客园 最近由于项目安全需要,将之前的ftp上传文件的方式,改用ftps 因为不太了解这个东西便开始了踩坑之旅 首先,最近在ubuntu 上搭建了这个服务 流程可以参考这些博客(部署网上的资 ...

  6. jmeter工具2个打开方法+配置黑窗口启动jmeter工具。

    实现从cmd黑窗口,输入jmeter,即可弹出jmeter工具界面.方法一:直接去安装在的目录,找jmeter_5.4.bat文件,双击即可打开工具. 方法二: 在环境变量中,配置JMETER_HOM ...

  7. weblogic11g打补丁,应用出现乱码

    解决办法: 1.找到域下的这个路径:autodeploy\manager\WEB-INF里的web.xml文件,先备份好,再添加以下语句: <context-param> <para ...

  8. ACE Editor 常用Api(转)

    ACE 是一个开源的.独立的.基于浏览器的代码编辑器,可以嵌入到任何web页面或JavaScript应用程序中.ACE支持超过60种语言语法高亮,并能够处理代码多达400万行的大型文档.ACE开发团队 ...

  9. unity踩坑集锦

    1.AB包加载,如果项目没有这个tag,那么就匹配不上,和代码一样.2.unity打包安卓topbar想显示出来怎么做?:不渲染安全区域外  3. unity编辑器报错 : Expanding inv ...

  10. 我在迁移我的IDEA的项目、模块等东西的过程中发生过的一部分问题的我的一部分的记录以及我的解决方案如下

    使用idea2019阶段报的一些错: 1.'xxxServlet' is not assignable to 'javax.servlet.Servlet' 解决方案:把tomcat加入classpt ...