使用 Playwright 處理自動化測試中的身份認證問題

在 Web 自動化測試中,身份認證(如登錄、Token 驗證)是高頻且關鍵的環節。重複執行登錄操作不僅降低測試效率,還可能因狀態殘留導致測試失敗。Playwright 通過靈活的瀏覽器上下文(Browser Context)管理和狀態持久化機制,提供了高效的身份認證解決方案。

Playwright 身份認證的核心原理 

瀏覽器上下文(Browser Context)

Playwright 在隔離的瀏覽器上下文中執行測試,每個上下文包含獨立的 Cookie、LocalStorage 和 Session Storage,確保測試間的獨立性。通過複用已認證的上下文狀態,可避免重複登錄。

認證狀態存儲

Playwright 支持將認證狀態持久化爲文件(如 JSON),存儲以下內容:

推薦將狀態文件保存在 playwright/.auth 目錄並添加到 .gitignore,防止敏感信息泄露。


基礎方法:複用認證狀態 

使用 storage_state 持久化狀態

通過 browser_context.storage_state() 方法保存認證狀態,並在新上下文中加載:

# 同步模式示例
from playwright.sync_api import sync_playwright

def test_authenticated_flow():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        # 創建已認證的上下文
        auth_context = browser.new_context()
        auth_page = auth_context.new_page()
        auth_page.goto("https://example.com/login")
        # 執行登錄操作...
        
        # 保存狀態到文件
        auth_context.storage_state(path="auth_state.json")
        
        # 創建新上下文並加載狀態
        new_context = browser.new_context(storage_state="auth_state.json")
        new_page = new_context.new_page()
        new_page.goto("https://example.com/dashboard")
        # 驗證認證狀態...

異步模式實現

異步代碼適用於高併發場景,需結合 async/await 語法:

# 異步模式示例
import asyncio
from playwright.async_api import async_playwright

asyncdef async_auth():
    asyncwith async_playwright() as p:
        browser = await p.chromium.launch()
        auth_context = await browser.new_context()
        auth_page = await auth_context.new_page()
        await auth_page.goto("https://example.com/login")
        # 異步登錄操作...
        
        await auth_context.storage_state(path="async_auth_state.json")
        
        new_context = await browser.new_context(storage_state="async_auth_state.json")
        new_page = await new_context.new_page()
        await new_page.goto("https://example.com/dashboard")

Session Storage 與動態注入 

某些應用使用 Session Storage 存儲臨時 Token,但 Playwright 默認不持久化該狀態。需通過 JavaScript 手動保存和注入:

保存 Session Storage

def save_session_storage(page):
    session_data = page.evaluate("() => JSON.stringify(sessionStorage)")
    with open("session_storage.json""w") as f:
        f.write(session_data)

加載 Session Storage

def load_session_storage(context, hostname):
    with open("session_storage.json""r") as f:
        session_data = f.read()
    context.add_init_script(f"""
        (storage => {{
            if (window.location.hostname === '{hostname}') {{
                const entries = JSON.parse(storage);
                Object.entries(entries).forEach(([key, value]) => {{
                    window.sessionStorage.setItem(key, value);
                }});
            }}
        }})('{session_data}')
    """)

自動化登錄與腳本錄製 

4 使用 playwright codegen 錄製登錄流程

通過命令行工具自動生成登錄腳本並保存認證狀態:

# 錄製並保存認證狀態
playwright codegen --save-storage=auth.json https://example.com/login

# 複用認證狀態啓動瀏覽器
playwright open --load-storage=auth.json https://example.com/dashboard

集成到測試框架(Pytest)

通過 Fixture 實現全局認證狀態管理:

# conftest.py
import pytest
from playwright.sync_api import Page, BrowserContext

@pytest.fixture(scope="session")
def auth_context(browser: BrowserContext):
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://example.com/login")
    page.fill("#username""user@example.com")
    page.fill("#password""password123")
    page.click("#submit")
    context.storage_state(path="auth_state.json")
    yield context
    context.close()

@pytest.fixture
def authenticated_page(auth_context):
    return auth_context.new_page()
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/l3gpmz5nFjnqSDai_U_i8A