元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
入门指南
Playwright安装与配置
环境要求与验证
第一个自动化测试脚本
▶
核心概念
Browser对象详解
Page对象操作指南
Frame与上下文管理
网络请求拦截与Mock
▶
元素定位与操作
CSS选择器实战
XPath高级定位技巧
文本定位与正则匹配
动态元素等待策略
▶
高级操作指南
文件上传下载处理
多标签页与弹窗管理
浏览器上下文隔离
设备模拟与地理定位
▶
测试框架集成
Jest集成配置
Mocha测试报告生成
持续集成CI/CD配置
▶
最佳实践
测试用例组织结构
性能优化策略
跨浏览器测试方案
▶
疑难解答
常见错误代码解析
元素定位失败分析
浏览器启动问题排查
▶
录制功能指南
录制功能基础入门
录制脚本生成与编辑
高级录制配置与技巧
录制脚本调试与优化
发布时间:
2025-03-27 19:18
↑
☰
# 文本定位与正则匹配 本文将详细介绍如何在Playwright中使用文本内容和正则表达式定位元素,帮助你掌握更精确的元素定位方法。 ## 文本定位基础 ### 1. 精确文本匹配 ```typescript // 使用文本定位 await page.getByText('登录').click(); // 使用标签文本定位 await page.getByLabel('用户名').fill('admin'); // 使用占位符文本定位 await page.getByPlaceholder('请输入密码').fill('123456'); ``` ### 2. 部分文本匹配 ```typescript // 包含文本匹配 await page.getByText('欢迎', { exact: false }).click(); // 使用正则表达式 await page.getByText(/欢迎.*用户/).click(); // 忽略大小写 await page.getByText('LOGIN', { exact: false }).click(); ``` ## 高级文本定位 ### 1. 组合定位 ```typescript // 文本和角色组合 await page.getByRole('button', { name: '提交' }).click(); // 文本和选择器组合 await page.locator('button', { hasText: '提交' }).click(); // 多重文本条件 await page.locator('div', { hasText: '标题', has: page.getByText('详细信息') }).click(); ``` ### 2. 正则表达式 ```typescript // 匹配数字 await page.getByText(/\d+/).click(); // 匹配邮箱 await page.getByText(/[\w.-]+@[\w.-]+\.[\w]{2,}/).click(); // 匹配日期 await page.getByText(/\d{4}-\d{2}-\d{2}/).click(); ``` ## 文本验证 ### 1. 基本验证 ```typescript // 验证文本存在 await expect(page.getByText('成功')).toBeVisible(); // 验证文本内容 await expect(page.getByRole('heading')).toHaveText('欢迎登录'); // 验证部分文本 await expect(page.locator('.message')).toContainText('成功'); ``` ### 2. 高级验证 ```typescript // 验证多个文本 await expect(page.locator('.list')).toHaveText([ '项目1', '项目2', '项目3' ]); // 验证文本数量 await expect(page.getByText('错误')).toHaveCount(2); // 验证文本属性 await expect(page.getByText('链接')).toHaveAttribute('href', /http/); ``` ## 最佳实践 ### 1. 文本定位策略 ```typescript // 创建可重用的定位器 class TextLocators { constructor(page) { this.page = page; } async clickButton(text) { await this.page.getByRole('button', { name: text }).click(); } async fillInput(label, value) { await this.page.getByLabel(label).fill(value); } } ``` ### 2. 错误处理 ```typescript // 处理文本不存在 try { await page.getByText('加载中').waitFor({ state: 'hidden' }); await page.getByText('完成').click(); } catch (error) { console.error('文本元素未找到:', error); } // 等待文本出现 await page.waitForSelector('text=加载完成'); ``` ## 调试技巧 ### 1. 文本查找 ```typescript // 打印页面文本 const text = await page.textContent('body'); console.log('页面文本:', text); // 查找所有匹配文本 const elements = await page.getByText('错误').all(); console.log('找到的元素数量:', elements.length); ``` ### 2. 定位调试 ```typescript // 高亮显示元素 await page.getByText('目标').highlight(); // 检查文本是否可见 const isVisible = await page.getByText('按钮').isVisible(); console.log('文本是否可见:', isVisible); ``` ## 常见问题 ### 1. 动态文本 ```typescript // 等待动态文本 await page.waitForSelector('text=加载完成', { state: 'visible', timeout: 5000 }); // 处理变化的文本 await page.waitForFunction( text => document.body.textContent.includes(text), '动态内容' ); ``` ### 2. 特殊字符 ```typescript // 处理空白字符 await page.getByText('Hello World', { exact: true }).click(); // 处理特殊符号 await page.getByText('$100.00').click(); // 处理换行符 await page.getByText('多行\n文本').click(); ``` ## 下一步 1. 学习[动态元素等待策略](/article/playwright/element-locators/waiting-strategies) 2. 了解[文件上传下载处理](/article/playwright/advanced/file-transfer) 3. 探索[多标签页与弹窗管理](/article/playwright/advanced/tab-management) ## 参考资料 - [Playwright文本选择器](https://playwright.dev/docs/selectors#text-selector) - [Playwright正则表达式](https://playwright.dev/docs/selectors#regex) - [Playwright定位器API](https://playwright.dev/docs/api/class-locator) ## 文本定位基础 ### 1. 精确文本匹配 ```typescript // 使用文本定位 await page.getByText('登录').click(); // 指定标签的文本定位 await page.getByRole('button', { name: '提交' }).click(); // 使用标签文本定位 await page.getByLabel('用户名').fill('admin'); // 使用占位符文本定位 await page.getByPlaceholder('请输入密码').fill('123456'); ``` ### 2. 部分文本匹配 ```typescript // 包含特定文本 await page.locator('div:has-text("欢迎")').click(); // 文本开头匹配 await page.locator('text=^欢迎').click(); // 文本结尾匹配 await page.locator('text=用户$').click(); // 忽略大小写匹配 await page.getByText('Login', { exact: false }).click(); ``` ## 正则表达式匹配 ### 1. 基本正则匹配 ```typescript // 使用正则表达式定位 await page.getByText(/登录|注册/).click(); // 匹配数字 await page.getByText(/\d+/).click(); // 匹配邮箱格式 await page.getByText(/[\w.-]+@[\w.-]+\.[\w.-]+/).click(); // 匹配电话号码 await page.getByText(/\d{3}-\d{8}|\d{4}-\d{7}/).click(); ``` ### 2. 高级正则匹配 ```typescript // 组合匹配 await page.locator('div').filter({ hasText: /^用户[\d]+$/ }).click(); // 多模式匹配 await page.locator('text=/成功|完成|确认/').click(); // 否定匹配 await page.locator('div:not(:has-text("错误"))').click(); // 条件匹配 await page.locator('button').filter({ hasText: /提交/, has: page.locator('[type="submit"]') }).click(); ``` ## 实战技巧 ### 1. 组合定位策略 ```typescript // 结合属性和文本 await page.locator('button[type="submit"]:has-text("登录")').click(); // 结合类名和文本 await page.locator('.btn-primary:has-text("确认")').click(); // 结合多个文本条件 await page.locator('div').filter({ hasText: /标题/, hasNotText: /已删除/ }).click(); ``` ### 2. 动态文本处理 ```typescript // 处理动态生成的文本 const userId = '12345'; await page.getByText(new RegExp(`用户${userId}`)).click(); // 处理格式化文本 const date = new Date().toLocaleDateString(); await page.getByText(new RegExp(date)).click(); // 处理多语言文本 const texts = ['登录', 'Login', '登入']; await page.getByText(new RegExp(texts.join('|'))).click(); ``` ## 性能优化 ### 1. 选择器优化 ```typescript // 使用更精确的选择器 // 不推荐 await page.getByText('点击').click(); // 推荐 await page.getByRole('button', { name: '点击' }).click(); // 缓存选择器 const loginButton = page.getByText('登录'); await loginButton.click(); ``` ### 2. 等待策略 ```typescript // 等待文本出现 await page.waitForSelector('text=加载完成'); // 等待文本消失 await page.waitForSelector('text=加载中', { state: 'hidden' }); // 等待正则匹配的文本 await page.waitForSelector('text=/成功|完成/'); ``` ## 调试技巧 ### 1. 文本验证 ```typescript // 检查文本是否存在 const hasText = await page.getByText('欢迎').isVisible(); // 获取匹配的文本内容 const texts = await page.locator('div').allTextContents(); console.log('找到的文本:', texts); // 验证文本格式 const text = await page.locator('div').textContent(); const isValid = /^\d{4}-\d{2}-\d{2}$/.test(text); ``` ### 2. 正则调试 ```typescript // 测试正则表达式 const pattern = /用户\d+/; const text = await page.locator('div').textContent(); console.log('正则匹配结果:', pattern.test(text)); // 提取匹配内容 const matches = text.match(pattern); console.log('匹配的内容:', matches); ``` ## 常见问题 ### 1. 文本匹配失败 ```typescript // 处理空白字符 await page.getByText('登 录', { exact: false }).click(); // 处理特殊字符 await page.getByText(new RegExp('价格:\\d+\\.\\d{2}')).click(); // 处理换行符 await page.getByText('欢迎\n登录').click(); ``` ### 2. 性能问题 ```typescript // 避免过于宽泛的正则 // 不推荐 await page.getByText(/.*/).click(); // 推荐 await page.getByText(/^用户\d+$/).click(); // 使用更具体的选择器 await page.getByRole('button', { name: /登录/ }).click(); ``` ## 下一步 1. 学习[动态元素等待策略](/article/playwright/element-locators/waiting-strategies) 2. 了解[文件上传下载处理](/article/playwright/advanced/file-transfer) 3. 探索[多标签页与弹窗管理](/article/playwright/advanced/tab-management) ## 参考资料 - [Playwright文本选择器](https://playwright.dev/docs/selectors#text-selector) - [JavaScript正则表达式](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions) - [Playwright定位器API](https://playwright.dev/docs/api/class-locator)