跳至主要内容

身份验证

简介

Playwright 在称为 浏览器上下文 的隔离环境中执行测试。此隔离模型提高了可重复性并防止了级联测试失败。测试可以加载现有的已认证状态。这消除了在每个测试中进行身份验证的需要,并加快了测试执行速度。

核心概念

无论您选择哪种身份验证策略,您都可能将已认证的浏览器状态存储在文件系统上。

我们建议创建 playwright/.auth 目录并将其添加到您的 .gitignore 中。您的身份验证例程将生成已认证的浏览器状态并将其保存到此 playwright/.auth 目录中的一个文件中。稍后,测试将重用此状态并以已认证状态启动。

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

在每次测试之前登录

Playwright API 可以 自动化与登录表单的交互

以下示例登录 GitHub。执行这些步骤后,浏览器上下文将处于已认证状态。

Page page = context.newPage();
page.navigate("https://github.com/login");
// Interact with login form
page.getByLabel("Username or email address").fill("username");
page.getByLabel("Password").fill("password");
page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Sign in"))
.click();
// Continue with the test

对每次测试都重新登录可能会降低测试执行速度。为了缓解这种情况,请重用现有的身份验证状态。

重用已登录状态

Playwright 提供了一种在测试中重用已登录状态的方法。这样,您只需登录一次,然后即可跳过所有测试的登录步骤。

Web 应用程序使用基于 Cookie 或基于令牌的身份验证,其中已认证状态存储为 Cookie 或在 本地存储 中。Playwright 提供 BrowserContext.storageState() 方法,可用于从已认证的上下文中检索存储状态,然后创建具有预填充状态的新上下文。

Cookie 和本地存储状态可以在不同的浏览器之间使用。它们取决于您的应用程序的身份验证模型:某些应用程序可能需要 Cookie 和本地存储。

以下代码片段从已认证的上下文中检索状态,并使用该状态创建新的上下文。

// Save storage state into the file.
context.storageState(new BrowserContext.StorageStateOptions().setPath(Paths.get("state.json")));

// Create a new context with the saved storage state.
BrowserContext context = browser.newContext(
new Browser.NewContextOptions().setStorageStatePath(Paths.get("state.json")));

高级场景

会话存储

重用已认证状态涵盖了基于 Cookie本地存储 的身份验证。很少情况下,会话存储 用于存储与已登录状态关联的信息。会话存储特定于特定域,并且不会跨页面加载持续存在。Playwright 没有提供持久化会话存储的 API,但以下代码段可用于保存/加载会话存储。

// Get session storage and store as env variable
String sessionStorage = (String) page.evaluate("JSON.stringify(sessionStorage)");
System.getenv().put("SESSION_STORAGE", sessionStorage);

// Set session storage in a new context
String sessionStorage = System.getenv("SESSION_STORAGE");
context.addInitScript("(storage => {\n" +
" if (window.location.hostname === 'example.com') {\n" +
" const entries = JSON.parse(storage);\n" +
" for (const [key, value] of Object.entries(entries)) {\n" +
" window.sessionStorage.setItem(key, value);\n" +
" };\n" +
" }\n" +
"})('" + sessionStorage + "')");