1.簡介
在介紹selenium的時(shí)候,宏哥也介紹過等待,是因?yàn)樵谀承┰爻霈F(xiàn)后,才可以進(jìn)行操作。有時(shí)候我們自己忘記添加等待時(shí)間后,查了半天代碼確定就是沒有問題,奇怪的就是獲取不到元素。然后搞了好久,或者經(jīng)過別人的提示才恍然大悟沒有添加等待時(shí)間。而playwright為了避免我們犯這么low的錯(cuò)誤,它對(duì)元素執(zhí)行操作前,會(huì)進(jìn)行一系列可操作性檢查,以確保這些行動(dòng)按預(yù)期運(yùn)行。它會(huì)自動(dòng)等待所有相關(guān)檢查通過,然后才執(zhí)行請(qǐng)求的操作。如果所需的檢查未在給定的范圍內(nèi)通過則拋出timeout,操作將失敗并顯示TimeoutError。正是由于playwright添加了默認(rèn)等待時(shí)間才會(huì)增加腳本穩(wěn)定性。
2.自動(dòng)等待
什么是playwright的自動(dòng)等待?在官網(wǎng)我們可以看到這樣一段話:
Auto-wait. Playwright waits for elements to be actionable prior to performing actions. It also has a rich set of introspection events. The combination of the two eliminates the need for artificial timeouts - the primary cause of flaky tests.
翻譯過來的大概意思就是說:自動(dòng)等待:playwright對(duì)元素執(zhí)行操作前,會(huì)進(jìn)行一系列可操作性檢查,以確保這些行動(dòng)按預(yù)期運(yùn)行。它會(huì)自動(dòng)等待所有相關(guān)檢查通過,然后才執(zhí)行請(qǐng)求的操作。如果所需的檢查未在給定的范圍內(nèi)通過則拋出timeout,操作將失敗并顯示TimeoutError。
如元素點(diǎn)擊操作,在操作元素之前需要預(yù)判:
以下是針對(duì)每個(gè)操作執(zhí)行的可操作性檢查的完整列表:
| Action | Attached | Visible | Stable | Receives Events | Enabled | Editable |
|---|---|---|---|---|---|---|
| check | Yes | Yes | Yes | Yes | Yes | - |
| click | Yes | Yes | Yes | Yes | Yes | - |
| dblclick | Yes | Yes | Yes | Yes | Yes | - |
| setChecked | Yes | Yes | Yes | Yes | Yes | - |
| tap | Yes | Yes | Yes | Yes | Yes | - |
| uncheck | Yes | Yes | Yes | Yes | Yes | - |
| hover | Yes | Yes | Yes | Yes | - | - |
| scrollIntoViewIfNeeded | Yes | - | Yes | - | - | - |
| screenshot | Yes | Yes | Yes | - | - | - |
| fill | Yes | Yes | - | - | Yes | Yes |
| selectText | Yes | Yes | - | - | - | - |
| dispatchEvent | Yes | - | - | - | - | - |
| focus | Yes | - | - | - | - | - |
| getAttribute | Yes | - | - | - | - | - |
| innerText | Yes | - | - | - | - | - |
| innerHTML | Yes | - | - | - | - | - |
| press | Yes | - | - | - | - | - |
| setInputFiles | Yes | - | - | - | - | - |
| selectOption | Yes | Yes | - | - | Yes | - |
| textContent | Yes | - | - | - | - | - |
| type | Yes | - | - | - | - | - |
3.slow_mo
通過前邊的學(xué)習(xí)和實(shí)踐,想必大家和宏哥有同樣的感覺吧:Playwright 打開瀏覽器運(yùn)行腳本的速度那就是一個(gè)字:快!相對(duì)于selenium,playwright執(zhí)行速度會(huì)更快,眨眼間就完事了。因此為了便于我們查看執(zhí)行的過程,我們可以加上等待來減緩執(zhí)行,但是與selenium不同,playwright通過slow_mo (單位是毫秒)減慢執(zhí)行速度,它的作用范圍是全局的,從啟動(dòng)瀏覽器到操作元素每個(gè)動(dòng)作都會(huì)有等待間隔,方便在出現(xiàn)問題的時(shí)候看到頁面操作情況。使用方法如下:
chromium.launch(headless=False, slow_mo=50)
3.1牛刀小試
宏哥就按照上邊的方法實(shí)踐一下,看一下是否真的可以減緩執(zhí)行速度。
3.1.1參考代碼
# coding=utf-8??
# 1.先設(shè)置編碼,utf-8可支持中英文,如上,一般放在第一行
# 2.注釋:包括記錄創(chuàng)建時(shí)間,創(chuàng)建人,項(xiàng)目名稱。
'''
Created on 2023-05-25
@author: 北京-宏哥 QQ交流群:705269076
公眾號(hào):北京宏哥
Project: 《《最新出爐》系列初窺篇-Python+Playwright自動(dòng)化測試-4-playwright自動(dòng)等待及擴(kuò)展
'''
# 3.導(dǎo)入模塊
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False, slow_mo=5000)
page = browser.new_page()
page.goto("https://www.baidu.com")
print(page.title())
page.fill('#kw', "北京-宏哥")
page.click('#su')
browser.close()
3.1.2運(yùn)行代碼
1.運(yùn)行代碼,右鍵Run'test',控制臺(tái)輸出,如下圖所示:

2.代碼的執(zhí)行過程,如下圖所示:

4.time.sleep()
與selenium不同,playwright不再支持time.sleep(),而是使用page.wait_for_timeout()來實(shí)現(xiàn)等待,當(dāng)我們調(diào)試時(shí)需要等待,即可使用該方法。Playwright 在查找元素的時(shí)候具有自動(dòng)等待功能,如果你在調(diào)試的時(shí)候需要使用等待,你應(yīng)該使用page.wait_for_timeout(5000) 代替 time.sleep(5)并且最好不要等待超時(shí)。
注:請(qǐng)使用 wait( wait_for_timeout) 方法而不是time模塊。這是因?yàn)槲覀儍?nèi)部依賴于異步操作,并且在使用時(shí)time.sleep(5)無法正確處理它們。
4.1牛刀小試
宏哥就按照上邊的方法實(shí)踐一下。
4.1.1參考代碼
# coding=utf-8??
# 1.先設(shè)置編碼,utf-8可支持中英文,如上,一般放在第一行
# 2.注釋:包括記錄創(chuàng)建時(shí)間,創(chuàng)建人,項(xiàng)目名稱。
'''
Created on 2023-05-25
@author: 北京-宏哥 QQ交流群:705269076
公眾號(hào):北京宏哥
Project: 《《最新出爐》系列初窺篇-Python+Playwright自動(dòng)化測試-4-playwright自動(dòng)等待及擴(kuò)展
'''
# 3.導(dǎo)入模塊
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False, slow_mo=1000)
page = browser.new_page()
page.goto("https://www.baidu.com")
print(page.title())
# 等待5秒
page.wait_for_timeout(5000)
page.fill('#kw', "北京-宏哥")
page.click('#su')
# 等待3秒
page.wait_for_timeout(3000)
browser.close()
4.1.2運(yùn)行代碼
1.運(yùn)行代碼,右鍵Run'test',控制臺(tái)輸出,如下圖所示:

2.代碼的執(zhí)行過程,如下圖所示:

5.小結(jié)
本文主要介紹了一些playwright的使用與selenium有一些不同,我們需要注意不同點(diǎn),比如playwright默認(rèn)是無頭模式運(yùn)行以及等待的改變。下一篇文章我們將介紹playwright定位元素的方法。
好了,今天時(shí)間也不早了,宏哥就講解和分享到這里,感謝您耐心的閱讀,希望對(duì)您有所幫助。
5.1自行設(shè)置等待
即使 Playwright 已經(jīng)做了充分準(zhǔn)備,但是也并不完全穩(wěn)定,在實(shí)際項(xiàng)目中依舊容易出現(xiàn)因頁面加載導(dǎo)致事件沒有生效等問題,為了避免這些問題,需要自行設(shè)置等待。
# 固定等待1秒
page.wait_for_timeout(1000)
# 等待事件
page.wait_for_event(event)
# 等待加載狀態(tài)
page.get_by_role("button").click()
page.wait_for_load_state()