playwright在稱為瀏覽器上下文的隔離環境中執行測試。這種隔離模型提高了可重復性,并防止了級聯測試失敗。測試可以加載現有的經過身份驗證的狀態。這消除了在每次測試中進行身份驗證的需要,并加快了測試執行速度。
每次測試前登錄
以下示例登錄到 GitHub。執行這些步驟后,將對瀏覽器上下文進行身份驗證。
- 同步
page = context.new_page()
page.goto('https://github.com/login')# Interact with login form
page.get_by_label("Username or email address").fill("username")
page.get_by_label("Password").fill("password")
page.get_by_role("button", name="Sign in").click()
# Continue with the test
為每個測試重做登錄可能會減慢測試執行速度。若要緩解此問題,可以重用現有身份驗證狀態。
重復使用已登錄狀態
Web 應用使用基于 Cookie 或基于令牌的身份驗證,其中經過身份驗證的狀態存儲為?Cookie?或存儲在本地存儲中。
?
在控制臺使用localStorage可以打印出cookie。
?
Playwright 提供了?browserContext.storageState([options])?方法,可以將該cookie保存到本地文件中。
context = browser.new_context(storage_state="state.json")
示例:
將cookie保存至state.json文件中
from playwright.sync_api import Playwright, expectdef run(playwright: Playwright) -> None:browser = playwright.chromium.launch(headless=False)context = browser.new_context()page = context.new_page()page.goto("https://pity.fun/#/user/login")page.get_by_placeholder("用戶名: tester").click()page.get_by_placeholder("用戶名: tester").fill("tester")page.get_by_placeholder("密碼: tester").fill("tester")page.get_by_role("button", name="登 錄").click()expect(page.get_by_title("工作臺")).to_be_visible()# 保存storage state 到指定的文件storage = context.storage_state(path="state.json")# ---------------------context.close()browser.close()with sync_playwright() as playwright:run(playwright)
?
從state.json獲取cookie,在創建上下文時使用該cookie進行登錄
from playwright.sync_api import Playwright, sync_playwrightdef run(playwright: Playwright) -> None:browser = playwright.chromium.launch(headless=False)# 加載本地cookies,免登陸context = browser.new_context(storage_state="state.json")# 打開頁面繼續操作page = context.new_page()page.goto('https://pity.fun')page.pause() # 打斷點看是不是已經登錄了context.close()browser.close()with sync_playwright() as playwright:run(playwright)
高級方案
會話存儲
重用經過身份驗證的狀態包括?Cookie?和基于本地存儲的身份驗證。很少使用會話存儲來存儲與登錄狀態關聯的信息。會話存儲特定于特定域,不會在頁面加載期間持久化。Playwright 不提供用于持久保存會話存儲的 API,但以下代碼片段可用于保存/加載會話存儲。
import os
# Get session storage and store as env variable
session_storage = page.evaluate("() => JSON.stringify(sessionStorage)")
os.environ["SESSION_STORAGE"] = session_storage# Set session storage in a new context
session_storage = os.environ["SESSION_STORAGE"]
context.add_init_script("""(storage => {if (window.location.hostname === 'example.com') {const entries = JSON.parse(storage)for (const [key, value] of Object.entries(entries)) {window.sessionStorage.setItem(key, value)}}
})('""" + session_storage + "')")