Web自動化測試之playwright:概述


playwright是由微軟開發的Web UI自動化測試工具, 支持Node.js、Python、C# 和 Java語言,本文將介紹playwright的特性以及它的簡單使用。

playwright特性

playwright具有以下特點:

一、支持所有主流瀏覽器

  • 支持所有主流瀏覽器:基於Chromium內核的Google Chrome 和 Microsoft Edge瀏覽器), WebKit內核的Apple Safari 和 Mozilla Firefox瀏覽器,不支持IE11。
  • 跨平台:Windows、Linux 和macOS
  • 可用於模擬移動端WEB應用的測試,不支持在真機上測試。
  • 支持無頭模式(默認)和有頭模式

二、快速可靠的執行

  • 自動等待元素
  • Playwright基於Websocket協議,可以接受瀏覽器(服務端)的信號。selenium采用的是HTTP協議,只能客戶端發起請求。
  • 瀏覽器上下文並行:單個瀏覽器實例下創建多個瀏覽器上下文,每個瀏覽器上下文可以處理多個頁面。
  • 有彈性的元素選擇:可以使用文本、可訪問標簽選擇元素。

三、強大的自動化能力

  • playwright是一個進程外自動化驅動程序,它不受頁面內JavaScript執行范圍的限制,可以自動化控制多個頁面。
  • 強大的網絡控制:Playwright 引入了上下文范圍的網絡攔截來存根和模擬網絡請求。
  • 現代web特性:支持Shadow DOM選擇,元素位置定位,頁面提示處理,Web Worker等Web API。
  • 覆蓋所有場景:支持文件下載、上傳、OOPIF(out-of-process iframes),輸入、點擊,暗黑模式等。

安裝

Playwright有Node.js、Python、C# 和 Java語言版本,本文介紹Python版本的Playwright使用方法。

Playwright的Python版本倉庫地址:https://github.com/microsoft/playwright-python

官方文檔地址:https://playwright.dev/python/docs/intro

Playwright安裝簡單,pip安裝時會自動下載瀏覽器驅動:

pip install playwright
playwright install # 安裝支持的瀏覽器:cr, chromium, ff, firefox, wk 和 webkit
playwright install chromium # 安裝指定的chromium瀏覽器

安裝時會自動下載瀏覽器依賴,windows系統在%USERPROFILE%\AppData\Local\ms-playwright 路徑下。

命令行工具

腳本錄制

在命令行窗口使用如下語法格式進行腳本錄制:

npx playwright codegen [options] [url]

options參數:

  • -o, --output <file name> :保存生成腳本
  • --target <language> :生成的腳本語言,可以設置javascript, test, python, python-async和csharp,默認為python。
  • -b, --browser <browserType> :要使用的瀏覽器,可以選擇cr, chromium, ff, firefox, wk和webkit,默認chromium。
  • --channel <channel>:chromium版本,比如chrome, chrome-beta, msedge-dev等,
  • --color-scheme <scheme>:模擬器的顏色主題,可選擇light 或者 dark樣式。
  • --device <deviceName> :模擬的設備,比如iPhone 11。
  • --save-storage <filename> :保存上下文狀態,用於保存cookies 和localStorage,可用它來實現重用。例如playwright codegen --save-storage=auth.json
  • --load-storage <filename> :加載--save-storage 保存的數據,重用認證數據。
  • --proxy-server <proxy> :指定代理服務器
  • --timezone <time zone> : 指定時區
  • --geolocation <coordinates> :指定地理位置坐標
  • --lang <language> :指定語言/地區,比如中國大陸:zh-CN
  • --timeout <timeout> :超時時間,定位毫秒,默認10000ms
  • --user-agent <ua string> :用戶代理
  • --viewport-size <size> :瀏覽器窗口大小
  • -h, --help :查看幫助信息

示例:模擬iPhone 12 Pro設備打開百度,使用Chromium驅動,生成的腳本語言設置為python,保存名稱為test_playwright.py:

playwright codegen -o test_playwright.py --target python  -b chromium --device="iPhone 12 Pro" https://www.baidu.com/

對頁面進行的操作會生成對應腳本代碼。

打開網頁

語法格式:

npx playwright open [options] [url]

除了沒有 -o--target options參數外,playwright open 支持 playwright codegen 的其它參數。

playwright open https://www.baidu.com/ # 默認使用Chromium打開
playwright wk https://www.baidu.com/ # 使用WebKit打開
playwright open --device="iPhone 12 Pro" https://www.baidu.com/ # 使用iPhone 12 Pro模擬器打開

截圖

語法格式:

npx playwright screenshot [options] <url> <filename>

options參數和 playwright codegen 的選項類似,可以使用 playwright screenshot --help 命令查看。

playwright screenshot --device="iPhone 12 Pro" -b wk https://www.baidu.com/ baidu-iphone.png # 截取顯示的頁面
playwright screenshot --full-page --device="iPhone 12 Pro" -b wk https://www.baidu.com/ baidu-iphone-full-page.png # 截取當前全部頁面

同步和異步API

Playwright支持同步和異步兩種API,使用異步API需要導入asyncio庫,它是一個可以用來實現Python協程的庫,更詳細介紹可參考Python協程

下面介紹如何使用python語言編寫簡單的playwright自動化腳本。

一共有2條測試用例,用例1步驟如下:

  1. chrome瀏覽器打開百度
  2. 搜索框輸入“test”
  3. 點擊百度一下搜索
  4. 點擊搜索結果的第2頁

用例2步驟:

  1. chrome瀏覽器打開搜狗搜索
  2. 搜索框輸入“test”
  3. 點擊搜狗搜索
  4. 點擊搜索結果的第2頁

1、同步方式

import time
from playwright.sync_api import sync_playwright

def testcase1():
    print('testcase1 start')
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.goto("https://www.baidu.com/")
        print(page.title())
        page.fill("input[name=\"wd\"]", "test")
        page.click("text=百度一下")
        page.click("#page >> text=2")
        browser.close()
    print('testcase1 done')

def testcase2():
    print('testcase2 start')
    with sync_playwright() as p:
        browser2 = p.chromium.launch(headless=False)
        page2 = browser2.new_page()
        page2.goto("https://www.sogou.com/")
        print(page2.title())
        page2.fill("input[name=\"query\"]", "test")
        page2.click("text=搜狗搜索")
        page2.click("#sogou_page_2")
        browser2.close()
    print('testcase2 done')

start = time.time()
testcase1()
testcase2()
end = time.time()
print('Running time: %s Seconds'%(end-start))

執行結果:

testcase1 start
百度一下,你就知道
testcase1 done
testcase2 start
搜狗搜索引擎 - 上網從搜狗開始
testcase2 done
Running time: 11.476110458374023 Seconds

2、異步方式


import asyncio
import time

from playwright.async_api import async_playwright

async def testcase1():
    print('testcase1 start')
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto("https://www.baidu.com/")
        print(await page.title())
        await page.fill("input[name=\"wd\"]", "test")
        await page.click("text=百度一下")
        await page.click("#page >> text=2")
        await browser.close()
    print('testcase1 done')

async def testcase2():
    print('testcase2 start')
    async with async_playwright() as p:
        browser2 = await p.chromium.launch(headless=False)
        page2 = await browser2.new_page()
        await page2.goto("https://www.sogou.com/")
        print(await page2.title())
        await page2.fill("input[name=\"query\"]", "test")
        await page2.click("text=搜狗搜索")
        await page2.click("#sogou_page_2")
        await browser2.close()
    print('testcase2 done')

async def main():
    task1 = asyncio.create_task(testcase1())
    task2 = asyncio.create_task(testcase2())
    tasks = [task1,task2]
    print('before await')
    await asyncio.gather(*tasks)

start = time.time()
asyncio.run(main())
end = time.time()
print('Running time: %s Seconds'%(end-start))

執行結果:

before await
testcase1 start
testcase2 start
百度一下,你就知道
搜狗搜索引擎 - 上網從搜狗開始
testcase1 done
testcase2 done
Running time: 6.0248863697052 Seconds

可以看到,使用異步編程的方式可以顯著提升測試效率。

瀏覽器

前面提到過,Playwright支持所有主流瀏覽器,下面介紹4種瀏覽器的啟動方法:

# chrome
browser = p.chromium.launch(channel="chrome", headless=False)
# Microsoft Edge
browser = p.chromium.launch(channel="msedge", headless=False)
# firefox
browser = p.firefox.launch(headless=False)
# webkit
browser = p.webkit.launch(headless=False)

瀏覽器上下文

在進行web自動化控制之前需要對瀏覽器進行實例化,比如:

browser = p.chromium.launch(channel="chrome", headless=False)

browser是一個Chromium實例,創建實例其實是比較耗費資源的,Playwright支持在一個browser實例下創建多個瀏覽器上下文(BrowserContext),BrowserContext的創建速度很快,並且比創建browser實例消耗資源更少。對於多頁面場景可以使用創建瀏覽器上下文的方式。

import asyncio

from playwright.async_api import async_playwright

async def testcase1():
    print('testcase1 start')
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto("https://www.baidu.com/")
        print(await page.title())
        await page.fill("input[name=\"wd\"]", "test")
        await page.click("text=百度一下")
        await page.click("#page >> text=2")

        context = await browser.new_context()
        page2 = await context.new_page()
        await page2.goto("https://www.sogou.com/")
        print(await page2.title())
        await page2.fill("input[name=\"query\"]", "test")
        await page2.click("text=搜狗搜索")
        await page2.click("#sogou_page_2")
        print(await page.title())
    print('testcase1 done')

asyncio.run(testcase1())

多頁面

一個瀏覽器上下文可以有多個頁面,也就是多個窗口。

async def testcase2():
    print('testcase2 start')
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        context = await browser.new_context()
        page1 = await context.new_page()
        await page1.goto("https://www.sogou.com/")
        print(await page1.title())
        await page1.fill("input[name=\"query\"]", "test")
        await page1.click("text=搜狗搜索")
        await page1.click("#sogou_page_2")

        page2 = await context.new_page()
        await page2.goto("https://www.baidu.com/")
        print(await page2.title())
    print('testcase2 done')

斷言

Python中可以使用assert 進行斷言:

assert page.title() == "百度一下,你就知道"

除了使用assert斷言以外,還可以使用功能更加強大的斷言方法Hamcrest ,具有豐富的斷言匹配器。

Hamcrest文檔:https://pyhamcrest.readthedocs.io/en/v2.0.2/tutorial/

安裝PyHamcrest:

pip install PyHamcrest
from hamcrest import *

assert_that(page.title(), equal_to("百度一下,你就知道"))

playwright Robot Framework庫

如果你使用robot framework來管理和編寫測試用例,可以使用robotframework-browser測試庫。

browser測試庫的github地址:https://github.com/MarketSquare/robotframework-browser, 安裝方法參考README.md文檔。

關鍵字使用說明文檔:https://marketsquare.github.io/robotframework-browser/Browser.html

安裝失敗:
https://github.com/MarketSquare/robotframework-browser/issues/682

可能是node版本太高,可以使用node v12.9.1版本

常見報錯

Node版本問題

Node.js is only supported on Windows 8.1, Windows Server 2012 R2, or higher.
Setting the NODE_SKIP_PLATFORM_CHECK environment variable to 1 skips this
check, but Node.js might not execute correctly. Any issues encountered on
unsupported platforms will not be fixed.Traceback (most recent call last):
  File "test.py", line 112, in <module>
    p = RobotPlaywright()
  File "test.py", line 29, in __init__
    self.playwright = sync_playwright().start()
  File "D:\attrobot3\lib\site-packages\playwright\sync_api\_context_manager.py",
 line 76, in start
    return self.__enter__()
  File "D:\attrobot3\lib\site-packages\playwright\sync_api\_context_manager.py",
 line 71, in __enter__
    playwright = self._playwright
AttributeError: 'PlaywrightContextManager' object has no attribute '_playwright'

Task was destroyed but it is pending!
task: <Task pending coro=<Connection.run.<locals>.init() running at D:\attrobot3
\lib\site-packages\playwright\_impl\_connection.py:175> wait_for=<Future pending
 cb=[<TaskWakeupMethWrapper object at 0x0000000003199288>()]>>

如果是windows7系統,錯誤原因可能是node版本太高,v12.16.2以上版本不支持win7,node歷史版本下載地址:https://nodejs.org/dist/

卸載安裝低版本后再次執行腳本,如果還是報上面的錯誤,可以嘗試設置系統變量 NODE_SKIP_PLATFORM_CHECK 繞過校驗。

set NODE_SKIP_PLATFORM_CHECK=1

安裝msedge報錯

$ playwright install msedge
無法加載文件 C:\Program Files\Python37\Lib\site-packages\playwright\driver\package\bin\reinstall_msedge_stable_win.ps1,因為在此系統中禁止執行腳本。有關詳細信息,請參閱 "get-help about_signing"。
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordE
   xception
    + FullyQualifiedErrorId : RuntimeException

解決方案:
打開 Windows PowerShell,執行如下命令:

set-ExecutionPolicy RemoteSigned

重新執行 playwright install msedge 命令安裝。

--THE END--


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM