Skip to main content

Authentication

簡介

Playwright 在名為瀏覽器情境的隔離環境中執行測試。這種隔離模型提高了可重現性並防止連鎖測試失敗。測試可以載入現有的已驗證狀態,這消除了在每個測試中進行驗證的需要,並加快了測試執行速度。

核心概念

無論您選擇哪種驗證策略,您都可能會將已驗證的瀏覽器狀態儲存在檔案系統上。

我們建議建立 playwright/.auth 目錄並將其加入您的 .gitignore。您的驗證程序將產生已驗證的瀏覽器狀態,並將其儲存到此 playwright/.auth 目錄中的檔案。稍後,測試將重用此狀態並以已驗證的方式開始。

danger

瀏覽器狀態檔案可能包含敏感的 cookies 和標頭,這些可能被用來冒充您或您的測試帳戶。我們強烈建議不要將它們提交到私人或公共儲存庫。

mkdir -p playwright/.auth
echo $'\nplaywright/.auth' >> .gitignore

在每個測試前登入

Playwright API 可以自動化互動登入表單。

以下範例登入 GitHub。一旦執行這些步驟,瀏覽器情境將會被驗證。

var page = await context.NewPageAsync();
await page.GotoAsync("https://github.com/login");
// 與登入表單互動
await page.GetByLabel("Username or email address").FillAsync("username");
await page.GetByLabel("Password").FillAsync("password");
await page.GetByRole(AriaRole.Button, new() { Name = "Sign in" }).ClickAsync();
// 繼續進行測試

為每個測試重新登入可能會減慢測試執行速度。為了減輕這種情況,請重用現有的驗證狀態。

重用已登入狀態

Playwright 提供了一種在測試中重用已登入狀態的方法。這樣您只需登入一次,然後跳過所有測試的登入步驟。

Web 應用程式使用基於 cookie 或基於 token 的驗證,其中已驗證狀態儲存為 cookies本地儲存IndexedDB。Playwright 提供 BrowserContext.StorageStateAsync() 方法,可用於從已驗證的情境檢索儲存狀態,然後建立具有預填充狀態的新情境。

Cookies、本地儲存和 IndexedDB 狀態可以跨不同瀏覽器使用。它們取決於您應用程式的驗證模型,可能需要 cookies、本地儲存或 IndexedDB 的某種組合。

以下程式碼片段從已驗證的情境檢索狀態並使用該狀態建立新情境。

// 將儲存狀態儲存到檔案中。
// 測試在 <TestProject>\bin\Debug\netX.0\ 中執行,因此使用相對路徑來參考在專案根目錄中建立的 playwright/.auth
await context.StorageStateAsync(new()
{
Path = "../../../playwright/.auth/state.json"
});

// 使用已儲存的儲存狀態建立新情境。
var context = await browser.NewContextAsync(new()
{
StorageStatePath = "../../../playwright/.auth/state.json"
});

進階情境

Session storage

重用已驗證狀態涵蓋基於 cookies本地儲存IndexedDB 的驗證。很少情況下,session storage 用於儲存與已登入狀態相關的資訊。Session storage 特定於特定網域,不會跨頁面載入持續存在。Playwright 不提供持續存儲 session storage 的 API,但可以使用以下程式碼片段來儲存/載入 session storage。

// 取得 session storage 並儲存為環境變數
var sessionStorage = await page.EvaluateAsync<string>("() => JSON.stringify(sessionStorage)");
Environment.SetEnvironmentVariable("SESSION_STORAGE", sessionStorage);

// 在新情境中設定 session storage
var loadedSessionStorage = Environment.GetEnvironmentVariable("SESSION_STORAGE");
await context.AddInitScriptAsync(@"(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);
}
}
})('" + loadedSessionStorage + "')");