跳到主要内容

认证

简介

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

核心概念

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

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

危险

浏览器状态文件可能包含敏感的 Cookie 和头部信息,这些信息可能被用于冒充您或您的测试账户。我们强烈建议不要将它们提交到私有或公共代码仓库中。

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

在每次测试前登录

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

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

page = context.new_page()
page.goto('https://github.com/login')

# Interact with login form
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()
# Continue with the test

在每次测试中重新登录会减慢测试执行速度。为了缓解这个问题,请转而重用现有的认证状态。

重用登录状态

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

Web 应用使用基于 Cookie 或基于 Token 的认证,认证状态通常存储在 Cookie 中,本地存储 (local storage) 中或 IndexedDB 中。Playwright 提供了 browser_context.storage_state() 方法,可用于从已认证的上下文检索存储状态,然后使用预填充的状态创建新的上下文。

Cookie、本地存储和 IndexedDB 状态可以在不同的浏览器之间使用。它们取决于您的应用程序的认证模型,可能需要 Cookie、本地存储或 IndexedDB 的某种组合。

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

# Save storage state into the file.
storage = context.storage_state(path="state.json")

# Create a new context with the saved storage state.
context = browser.new_context(storage_state="state.json")

高级场景

会话存储 (Session Storage)

重用认证状态涵盖了基于 Cookie本地存储 (local storage)IndexedDB 的认证。极少数情况下,会话存储 (session storage) 被用于存储与登录状态相关的信息。会话存储特定于某个域,并且在页面加载之间不会持久化。Playwright 没有提供持久化会话存储的 API,但以下代码片段可用于保存/加载会话存储。

import os
# Get session storage and store as env variable
session_storage = page.evaluate("() => JSON.stringify(sessionStorage)")
os.environ["SESSION_STORAGE"] = session_storage

# Set session storage in a new context
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 + "')")