侧边栏壁纸
  • 累计撰写 269 篇文章
  • 累计创建 141 个标签
  • 累计收到 16 条评论

目 录CONTENT

文章目录

自动化测试 -- playwright

Sherlock
2024-01-10 / 0 评论 / 0 点赞 / 133 阅读 / 0 字
温馨提示:
本文最后更新于2024-01-13,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

playwright

项目地址:https://github.com/microsoft/playwright-python
官方文档:https://playwright.dev/python/docs/intro

安装

系统要求
Python 3.8+
Windows 10+ or MacOS 12+ or Ubuntu 20.04+

pip install pytest-playwright

playwright install

如果版本过低,可升级python,需要3.8+
国内镜像下载地址 https://repo.huaweicloud.com/python/3.12.1/python-3.12.1-amd64.exe

使用

录制测试脚本

会启动一个 Chromium 浏览器,操作完成之后点击红色按钮结束录制即可。

playwright codegen https://xxx.net/login

编写测试脚本

from playwright.sync_api import Playwright, sync_playwright, expect
import requests
import json

def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://xxx.net/login")
    page.get_by_placeholder("请输入账号/手机号").click()
    page.get_by_placeholder("请输入账号/手机号").fill("xxx")
    page.get_by_placeholder("请输入账号/手机号").press("Tab")
    page.get_by_placeholder("请输入密码").fill("xxx")
    page.get_by_role("button", name="登录").click()
    # 此处手动登录,然后到个人信息页再获取cookie
    page.wait_for_timeout(3000)
    cookies = context.cookies()
    print(page.title(), end='\n')
    f = open('cookies.txt', 'w')
    json.dump(cookies, f)
    print('已获取cookies', end='\n')

    user_token = None
    zujuan_core = None
    for cookie in cookies:
        print(cookie)
        if cookie['name'] == 'user_token':
            user_token = cookie['value']
        elif cookie['name'] == 'zujuan-core':
            zujuan_core = cookie['value']

    print(user_token, end='\n')
    print(zujuan_core, end='\n')

    update_cookie_url = 'http://xxx/json_api';
    update_cookie_json_data = {'user_token': user_token, 'zujuan_core': zujuan_core}
    response = requests.post(url=update_cookie_url, json=update_cookie_json_data)
    f2 = open('response.txt', 'wb')
    #byte格式
    f2.write(response.content)
    print('已获取response')
    
    page.wait_for_timeout(2000)
    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

运行测试脚本

cd /Users/sherlock/dev/playwright

pytest test_example.py

debug 脚本

PWDEBUG=1 pytest -s test_example.py

可以打断点配合 debug

page.pause() 

批处理调用

@echo off
cd C:\spider\playwright
echo test_xkw
pytest test_xkw.py
echo finish

如果是java调用,还需要指定具体路径

@echo off
cd C:\spider\playwright
echo test_xkw
C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Scripts\pytest C:\spider\playwright\test_xkw.py
echo finish

选择器

page.get_by_placeholder("请输入密码").fill("000000ab")

page.get_by_role("button", name="登录").click()

#按文本内容搜索
hasNickname = page.get_by_text('伊春测试一中').count() > 0
#如果已登录状态,只需要前面刷新完页面即可
if not hasNickname:
    page.get_by_role("button", name="登录").click()
#...

css选择器文档:https://playwright.dev/python/docs/locators#locate-by-css-or-xpath

复杂的并不推荐使用

示例:

    #定位元素并获取文本内容
    content = page.locator('div.unusual').inner_html()
    # 发送企微 whbhool
    webhook_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
    json_data = {"msgtype": "text", "text": {"content" : "xxx:" + content }}
    requests.post(url=webhook_url, json=json_data)
    

截图

#整个页面截图
page.screenshot(path="example2.png")
#指定选择器截图
page.locator(".s-canvas").screenshot(path="example.png")

保存浏览器状态(会话之类的)

在编写UI自动化测试用例的时候,通常会采用每个测试用例前打开新页面重新进行登录,以减少用例间的影响,但是这种方式会使得测试用例的执行时间大幅度上升。
如果可以将登录状态保持住,开始测试用例的时候打开新页面,跳过登录直接进入到待测系统中,就可以大幅度提高测试执行效率。

from playwright.sync_api import Playwright, sync_playwright, expect
import requests
import os

def run(playwright: Playwright) -> None:
    ss_file = 'login_data.json'
    browser = playwright.chromium.launch(headless=False)

    # 判断是否存在状态文件,有的话就加载
    if os.path.isfile(ss_file):
        context = browser.new_context(storage_state=ss_file)
    else:
        context = browser.new_context()

    #context = browser.new_context()
    page = context.new_page()
    page.goto("https://xxx.com/login")

    # 通过title判断是否成功进入系统,如果没有需要进行登录,一般在第一次访问系统,或登录信息过期等原因会触发
    if '工时' not in page.title():
        page.get_by_placeholder("请输入账号/手机号").click()
        page.get_by_placeholder("请输入账号/手机号").fill("xxx")
        page.get_by_placeholder("请输入账号/手机号").press("Tab")
        page.get_by_placeholder("请输入密码").fill("xxx")
        page.get_by_placeholder("请输入密码").press("Tab")
        page.get_by_role("button", name="登录").click()
    
    # 保存状态文件
    storage = context.storage_state(path=ss_file)

    page.wait_for_timeout(1000)
    page.get_by_role("link").nth(1).click()

    #定位元素并获取文本内容
    content = page.locator('div.unusual').inner_html()

    webhook_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
    json_data = {"msgtype": "text", "text": {"content" : "xxx:" + content }}
    requests.post(url=webhook_url, json=json_data)
    page.wait_for_timeout(1000)

    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

指定外部浏览器

官方文档:https://playwright.dev/docs/api/class-browsertype#browser-type-connect-over-cdp

一般是使用chrome浏览器的debug模式来实现,首先需要以debug模式启动:

chrome.exe --remote-debugging-port=12345 -–start-maximized

mac下启动命令为:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222

常见可用参数:

  • -–incognito:隐私模式打开

    这里笔者主要就是想使用真实的浏览器,就不加了

  • -–start-maximized:窗口最大化
  • --user-data-dir:设置用户目录

    这里需要单独指定一个文件夹目录,不存在会新建,如果不显式指定该参数,运行会污染浏览器默认的配置文件;
    笔者这里使用了一个新的浏览器,就不加了

  • --new-window:直接打开网址

    可以不设置,打开空白标签页

修改py脚本

from playwright.sync_api import Playwright, sync_playwright, expect
import requests
import json

def run(playwright: Playwright) -> None:
    #browser = playwright.chromium.launch(headless=False)
    #context = browser.new_context()
    #page = context.new_page()
    ## 使用debug模式连接主机的chrome
    chromium = playwright.chromium
    browser = chromium.connect_over_cdp('http://localhost:12345')
    context = browser.contexts[0]
    #page = context.pages[0]
    page = context.new_page()
    page.goto("https://www.baidu.com")
    
    #。。。。省略
    
    # ---------------------
    ## 使用后一般不关闭窗口了,因为就是要模拟真实浏览器的效果
    #context.close()
    #browser.close()


with sync_playwright() as playwright:
    run(playwright)

还可以参考:

https://blog.csdn.net/lilongsy/article/details/130560129
https://zhuanlan.zhihu.com/p/573640396

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区