认证
简介
Playwright在称为browser contexts的隔离环境中执行测试。这种隔离模式提高了可重现性并防止级联测试失败。测试可以加载现有的认证状态,这消除了在每个测试中进行认证的需要,并加快了测试执行速度。
核心概念
无论您选择哪种身份验证策略,都可能需要将经过身份验证的浏览器状态存储在文件系统中。
我们建议创建playwright/.auth
目录并将其添加到您的.gitignore
中。您的身份验证流程将生成经过验证的浏览器状态,并将其保存到此playwright/.auth
目录中的文件中。之后,测试将重用此状态并直接以已验证状态启动。
- Bash
- PowerShell
- 批量处理
mkdir -p playwright/.auth
echo $'\nplaywright/.auth' >> .gitignore
New-Item -ItemType Directory -Force -Path playwright\.auth
Add-Content -path .gitignore "`r`nplaywright/.auth"
md playwright\.auth
echo. >> .gitignore
echo "playwright/.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或基于token的认证方式,认证状态以cookies形式存储,或在local storage或IndexedDB中。Playwright提供了BrowserContext.storageState()方法,可用于从已认证的上下文中获取存储状态,然后创建带有预填充状态的新上下文。
Cookies、本地存储和IndexedDB状态可以在不同浏览器之间共享。它们取决于您应用程序的身份验证模型,可能需要结合使用cookies、本地存储或IndexedDB。
以下代码片段从一个已认证的上下文中获取状态,并使用该状态创建一个新的上下文。
// 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")));
高级场景
会话存储
复用认证状态涵盖基于cookies、local storage和IndexedDB的认证。极少数情况下,session storage会用于存储与登录状态相关的信息。会话存储是特定于某个域的,且不会在页面加载之间持久化。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 + "')");