认证
简介
Playwright 在称为 browser contexts 的隔离环境中执行测试。这种隔离模型提高了可重复性并防止了测试之间的级联失败。测试可以加载现有的认证状态。
核心概念
无论你选择哪种认证策略,都可能需要将认证后的浏览器状态存储在文件系统中。
我们建议创建 playwright/.auth
目录并将其添加到你的 .gitignore
文件中。你的认证例程将生成认证后的浏览器状态并保存到该目录中的文件中。稍后,测试将重用此状态并以已认证的身份开始。
浏览器状态文件可能包含敏感的 cookie 和 header,这些信息可能被用来冒充你或你的测试账户。我们强烈不建议将它们提交到私有或公共仓库中。
- Bash
- PowerShell
- Batch
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 = context.new_page()
page.goto('https://github.com/login')
# 与登录表单交互
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()
# 继续测试
page = await context.new_page()
await page.goto('https://github.com/login')
# 与登录表单交互
await page.get_by_label("Username or email address").fill("username")
await page.get_by_label("Password").fill("password")
await page.get_by_role("button", name="Sign in").click()
# 继续测试
为每个测试重新登录可能会减慢测试执行速度。为了避免这种情况,请重用现有的认证状态。
重用已登录状态
Playwright 提供了一种在测试中重用已登录状态的方法。这样你只需登录一次,然后跳过所有测试的登录步骤。
Web 应用程序使用基于 cookie 或 token 的认证方式,其中认证状态作为 cookies,存储在 local storage 或 IndexedDB 中。Playwright 提供了 browser_context.storage_state() 方法,可用于从已认证的上下文中检索存储状态,然后使用预填充的状态创建新的上下文。
Cookie、本地存储和 IndexedDB 状态可以在不同浏览器间使用。它们依赖于你的应用程序的认证模型,这可能需要一些 cookies、本地存储或 IndexedDB 的组合。
以下代码片段从已认证的上下文中检索状态,并使用该状态创建一个新的上下文。
- 同步
- 异步
# 将存储状态保存到文件中。
storage = context.storage_state(path="state.json")
# 使用保存的存储状态创建一个新的上下文。
context = browser.new_context(storage_state="state.json")
# 将存储状态保存到文件中。
storage = await context.storage_state(path="state.json")
# 使用保存的存储状态创建一个新的上下文。
context = await browser.new_context(storage_state="state.json")
高级场景
Session storage
重用认证状态涵盖了基于 cookies、本地存储 和 IndexedDB 的身份验证。很少情况下,会使用 session storage 来存储与登录状态相关的信息。Session storage 特定于特定域名,不会跨页面加载持久化。Playwright 不提供持久化 session storage 的 API,但可以使用以下代码片段来保存/加载 session storage。
- 同步
- 异步
import os
# 获取 session storage 并存储为环境变量
session_storage = page.evaluate("() => JSON.stringify(sessionStorage)")
os.environ["SESSION_STORAGE"] = session_storage
# 在新上下文中设置 session storage
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 + "')")
import os
# 获取 session storage 并存储为环境变量
session_storage = await page.evaluate("() => JSON.stringify(sessionStorage)")
os.environ["SESSION_STORAGE"] = session_storage
# 在新上下文中设置 session storage
session_storage = os.environ["SESSION_STORAGE"]
await 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 + "')")