Playwright for Python 的基本使用与常用交互API-使用笔记
Playwright for Python 的基本使用与常用交互API-使用笔记
安装
安装分为只做自动化,和做自动化测试两种
# 做自动化时
pip install playwright
# 做测试框架时
pip install pytest-playwright
# 只安装chromium引擎(或者firefox、WebKit)
playwright install chromium
只做自动化起手式(同步或异步)
安装 playwright后,使用playwright的起手式方法
from playwright.sync_api import sync_playwright
# 同步
def start_playwright():
with sync_playwright() as p:
browser = p.chromium.launch(headless=False) # gui 有头
page = browser.new_page()
page.goto("http://playwright.dev") # 打开页面
print(page.title())
browser.close()
start_sync_playwright()
import asyncio
from playwright.async_api import async_playwright
# 异步
async def start_async_playwright():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False) # gui 有头
page = await browser.new_page()
await page.goto("http://playwright.dev") # 打开页面
print(await page.title())
await browser.close()
asyncio.run(start_async_playwright())
自动化测试起手式(同步或异步)
# 同步
from playwright.sync_api import Page, expect
def test_has_title(page: Page):
page.goto("https://playwright.dev/")
expect(page).to_have_title(re.compile("Playwright"))
def test_get_started_link(page: Page):
page.goto("https://playwright.dev/")
page.get_by_role("link", name="Get started").click()
expect(page.get_by_role("heading", name="Installation")).to_be_visible()
异步 API,适合高并发测试场景。需在 Pytest 配置中启用异步支持:如pytest-asyncio 插件
# 异步
import pytest
from playwright.async_api import Page, expect
import asyncio
@pytest.mark.asyncio
async def test_has_title(page: Page):
await page.goto("https://playwright.dev/")
await expect(page).to_have_title(re.compile("Playwright"))
@pytest.mark.asyncio
async def test_get_started_link(page: Page):
await page.goto("https://playwright.dev/")
await page.get_by_role("link", name="Get started").click()
await expect(page.get_by_role("heading", name="Installation")).to_be_visible()
常用交互API
1.点击或拖放相关
# 单击
page.click("button#submit")
# 双击
page.dblclick("img#preview")
page.click("img#preview", click_count=2)
# 元素悬停
page.hover("div.tooltip")
# 元素拖动
page.drag_and_drop("#source", "#target")
# 多元素链式点击
tags = page.locator(selector: str)
for i in range(tags.count()):
tags.nth(i).click()
page.wait_for_timeout(200) # 间隔200ms
2.输入或选择相关
# 填充输入框或文本域的值
page.fill("#username", "username")
# 将焦点设置到指定元素上
page.focus("input#email")
# 在下拉框中选择单个或多个选项
page.select_option("select#option", "option")
# 逐字符输入文本,模拟键盘事件
page.type("#password", "password")
3.元素定位交互与提取
# 创建 Locator 对象,用于可靠定位和交互
locator = page.locator("input[name='email']")
locator.click()
# 通过 ARIA 角色和名称定位元素
page.get_by_role("button", name="Submit").click()
# 提取元素的指定属性值(如 href)
href = page.get_attribute("a#link", "href")
# 提取元素的可见文本内容
text = page.inner_text("h1.title")
# 提取元素的完整标签文本(包括隐藏子元素文本)
full_text = page.text_content("p.description")
4.等待相关
# 等待指定元素可见(必须可见、非隐藏状态)
page.wait_for_selector("text=Thank you", timeout=5000)
# expect(page.get_by_text("Welcome")).to_be_visible() # 断言的方式
# 等待元素消失(隐藏或从 DOM 中移除)
page.wait_for_selector("#loading-spinner", state="hidden")
# expect(page.locator("#alert")).to_be_hidden(timeout=5000) # 断言的方式
# 等待元素可点击(附加到 DOM 且启用)
locator = page.locator("button#submit")
locator.wait_for(state="attached")
# expect(page.get_by_role("button")).to_be_enabled() # 断言的方式
# 等待指定文本出现(元素中包含该文本)
page.wait_for_selector('text="Order confirmed"')
# expect(page.locator("div.content")).to_have_text("Loading complete") # 断言的方式
# 等待页面达到指定加载状态(如 "load")
page.wait_for_load_state("load")
# 等待页面 URL 匹配指定模式
page.wait_for_url("**/dashboard")
# 等待 JavaScript 表达式返回真值
page.wait_for_function("() => document.querySelector('loaded')")
5.文件上传下载
# 设置文件输入元素的文件路径(上传)
page.set_input_files("input[type=file]", "example.pdf")
# 监听文件选择对话框事件,用于上传
def handle_filechooser(fc): fc.set_files("/tmp/report.pdf")
page.on("filechooser", handle_filechooser)
page.click('input[type="file"]')
# 等待下载开始,返回 Download 对象
with page.expect_download() as download_info:
page.click("Download")
download = download_info.value
download.save_as("file.pdf")
6.断言
from playwright.sync_api import expect
# 断言元素存在且可见
expect(page.get_by_role("button")).to_be_visible()
# 断言元素存在但是隐藏
expect(page.locator("#alert")).to_be_hidden()
# 断言元素文本部分匹配
expect(page.locator("div.content")).to_contain_text("Welcome")
# 断言元素文本精确匹配
expect(page.locator("h1")).to_have_text("Exact Title")
# 断言元素属性存在且值匹配
expect(page.locator("a#link")).to_have_attribute("href", "https://example.com")
# 断言元素属性不存在
expect(page.locator("input#email")).not_to_have_attribute("disabled")
# 断言页面标题匹配
expect(page).to_have_title("My Page")
# 断言当前网页 URL 匹配
expect(page).to_have_url("**/dashboard")
# 断言链接元素文本匹配
expect(page.get_by_role("link", name="Home")).to_have_text("Home")
# 断言元素启用
expect(page.get_by_role("button")).to_be_enabled()
# 延迟断言:等待指定超时后检查条件
expect(page.locator("#loading").not_to_be_visible(), timeout=10000).to_be_true()
7.切换 frame 框架
# 创建针对 iframe 内元素的 Locator
frame_loc = page.frame_locator("iframe#embed")
frame_loc.locator("button").click()
# 根据名称或 URL 获取 Frame 对象
frame = page.frame(name="frame-name")
frame.click("button#action")
# 获取页面所有 Frame 的列表
for frame in page.frames:
print(frame.url)
# 从 ElementHandle 获取 iframe 的内容 Frame
iframe = page.query_selector("iframe")
frame = iframe.content_frame()
frame.click("submit")
本文来自博客园作者:星尘的博客,转载请注明出处:https://www.cnblogs.com/yqbaowo/p/19160290

浙公网安备 33010602011771号