大家好,我是阿萨。 写自动化,避免不了写鉴权的脚本。怎么用Playwright 去写鉴权的脚本呢?用 Playwright 编写的测试在隔离的干净环境中执行,称为浏览器上下文。这种隔离模式提高了可重复性,防止了测试失败。新的浏览器上下文可以加载现有的认证状态。这消除了在每个上下文中登录的需要,加快了测试的执行。
自动登录
Playwright API可以自动进行登录表格的交互。
下面的例子是自动登录到GitHub。一旦这些步骤被执行,浏览器上下文将被认证。
同步:
page = context.new_page()page.goto('https://github.com/login')# Interact with login formpage.get_by_text("Login").click()page.get_by_label("User Name").fill(USERNAME)page.get_by_label("Password").fill(PASSWORD)page.get_by_text('Submit').click()# Continue with the test
异步:
page = context.new_page()page = await context.new_page()await page.goto('https://github.com/login')# Interact with login formawait page.get_by_text("Login").click()await page.get_by_label("User Name").fill(USERNAME)await page.get_by_label("Password").fill(PASSWORD)await page.get_by_text('Submit').click()# Continue with the test
为每个测试重新进行登录会减慢测试的执行。为了避免这种情况,可以重用现有的认证状态。
重用登录状态
Playwright提供了一种方法来重用测试中的登录状态。这样,你可以只登录一次,然后跳过所有测试的登录步骤。
网络应用程序使用基于cookie或令牌的认证,其中认证状态以cookie或本地存储的形式存储。Playwright提供了browserContext.storageState([options])方法,可以用来从认证的上下文中检索存储状态,然后用预填充的状态创建新的上下文。
Cookies和本地存储状态可以在不同的浏览器中使用。它们取决于你的应用程序的认证模型:一些应用程序可能需要cookies和本地存储。
下面的代码片段从认证的上下文中检索状态,然后用该状态创建一个新的上下文。
同步:
# 将存储状态保存到文件中。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")
会话存储
罕见的是,会话存储被用于存储与登录状态相关的信息。会话存储是特定于某一特定领域的,并且不会跨页面加载持久化。Playwright没有提供持久化会话存储的API,但是下面的片段可以用来保存/加载会话存储。
同步:
import os# Get session storage and store as env variablesession_storage = page.evaluate("() => JSON.stringify(sessionStorage)")os.environ["SESSION_STORAGE"] = session_storage # Set session storage in a new contextsession_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# Get session storage and store as env variablesession_storage = await page.evaluate("() => JSON.stringify(sessionStorage)")os.environ["SESSION_STORAGE"] = session_storage # Set session storage in a new contextsession_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 + "')")
多因子认证
带有多因素认证(MFA)的账户不能完全自动化,需要人工干预。持久性认证可用于部分自动化的MFA场景。
持久性认证
请注意,持久性认证不适合CI环境,因为它依赖于一个磁盘位置。用户数据目录是针对浏览器类型的,不能跨浏览器类型共享。
用户数据目录可以通过browser_type.launch_persistent_context(user_data_dir, **kwargs) API来使用。
同步:
from playwright.sync_api import sync_playwright with sync_playwright() as p: user_data_dir = '/path/to/directory' browser = p.chromium.launch_persistent_context(user_data_dir, headless=False)# Execute login steps manually in the browser window
异步:
import asynciofrom playwright.async_api import async_playwright async def main(): async with async_playwright() as p: user_data_dir = '/path/to/directory' browser = await p.chromium.launch_persistent_context(user_data_dir, headless=False) # Execute login steps manually in the browser window asyncio.run(main())
生命周期
在磁盘上创建一个用户数据目录。
用用户数据目录启动一个持久的上下文,并登录MFA账户。
重复使用用户数据目录来运行自动化方案。