Playwright Inspector 录制代码的 AI 复用指南:从录制到智能脚本生成
1. 引言:当自动化测试遇上 AI 助手
在 Web 自动化测试领域,Playwright Inspector 是一个强大的可视化录制工具,它允许测试人员通过浏览器操作自动生成可执行的测试脚本。然而,这些录制生成的代码往往是“一次性”的——它们忠实地记录了操作步骤,但缺乏灵活性、可维护性,也难以应对动态变化的页面元素。
随着 AI 编程助手(如 GitHub Copilot、Cursor、通义灵码等)的普及,我们迎来了新的机遇:将 Playwright Inspector 录制的“原始代码”转化为可供 AI 理解、重构和智能复用的高质量“素材”。本文旨在提供一套完整的技术方案,教你如何清洗、结构化录制代码,并利用 AI 将其转化为可维护、可扩展的自动化测试资产。
2. Playwright Inspector 录制代码的典型问题
直接使用 Inspector 录制的代码,通常存在以下痛点,阻碍了 AI 的有效理解和复用:
- 硬编码定位器:过度依赖
page.locator('text=Submit')或冗长的 CSS 选择器,一旦页面文本或结构微调,脚本立即失效。 - 缺乏抽象与模块化:所有操作线性堆叠在一个长函数中,没有提取公共操作(如登录、导航)为可复用的函数或 Page Object。
- 脆弱的等待与断言:依赖固定的
page.waitForTimeout(3000),而非更健壮的等待策略(如waitForSelector、waitForLoadState)。 - 数据与逻辑耦合:测试数据(如用户名、搜索关键词)直接写在操作中,难以进行数据驱动测试。
- 注释与上下文缺失:生成的代码缺少说明“为什么这么做”的注释,AI 难以推断业务意图。
3. 预处理:将录制代码转化为 AI 友好的“原料”
在将代码喂给 AI 之前,我们需要进行初步清洗和标注。
3.1 提取核心操作流
删除所有 page.waitForTimeout 语句,并用 // TODO: 替换为更健壮的等待策略 注释标记其位置。这向 AI 发出了明确的优化指令。
录制原始代码示例:
await page.goto('https://example.com/login');
await page.waitForTimeout(2000); // 脆弱等待
await page.locator('input[name="username"]').fill('testuser');
await page.locator('input[name="password"]').fill('password123');
await page.locator('button:has-text("Sign In")').click();
await page.waitForTimeout(5000); // 脆弱等待
预处理后:
await page.goto('https://example.com/login');
// TODO: 替换为更健壮的等待策略,例如等待登录表单可见
await page.locator('input[name="username"]').fill('testuser');
await page.locator('input[name="password"]').fill('password123');
await page.locator('button:has-text("Sign In")').click();
// TODO: 替换为更健壮的等待策略,例如等待页面导航完成
3.2 添加语义化注释
在关键业务步骤前后添加注释,说明意图而非操作。
// 步骤1: 导航至登录页面
await page.goto('https://example.com/login');
// 步骤2: 填写用户凭证
await page.locator('input[name="username"]').fill('testuser');
await page.locator('input[name="password"]').fill('password123');
// 步骤3: 提交登录表单
await page.locator('button:has-text("Sign In")').click();
4. 核心策略:指导 AI 重构与复用录制代码
准备好“原料”后,你可以向 AI 助手提出以下类型的指令,进行智能化重构。
4.1 指令类型一:转换为 Page Object 模式
你的提示词:
“将下面这段 Playwright 录制代码重构为 Page Object 模式。请创建一个
LoginPage类,包含所有定位器和操作方法(如goto、fillUsername、submit)。将测试步骤提取到一个单独的测试函数中。”
AI 可能生成的结果:
// LoginPage.js
class LoginPage {
constructor(page) {
this.page = page;
this.usernameInput = page.locator('input[name="username"]');
this.passwordInput = page.locator('input[name="password"]');
this.submitButton = page.locator('button:has-text("Sign In")');
}
async goto() {
await this.page.goto('https://example.com/login');
}
async login(username, password) {
await this.usernameInput.fill(username);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
// test.spec.js
const { test, expect } = require('@playwright/test');
test('用户登录流程', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('testuser', 'password123');
// 添加断言...
});
4.2 指令类型二:增强定位器与等待策略
你的提示词:
“优化下面代码中的定位器和等待策略。将文本定位器改为更具弹性的属性定位器(如
data-testid)。将所有waitForTimeout替换为Playwright推荐的显式等待(如waitForSelector,waitForLoadState)。”
AI 可能生成的结果:
// 优化前:await page.locator('button:has-text("Submit")').click();
// 优化后:假设按钮有 data-testid 属性
await page.locator('[data-testid="submit-button"]').click();
// 优化前:await page.waitForTimeout(5000);
// 优化后:等待某个成功元素出现
await page.waitForSelector('.welcome-message', { state: 'visible' });
// 或者等待网络请求完成
await page.waitForLoadState('networkidle');
4.3 指令类型三:实现数据驱动测试
你的提示词:
“将下面的登录脚本改造成数据驱动测试。从外部 JSON 文件或数组读取多组用户名和密码进行测试,并为每次循环添加清晰的日志输出。”
AI 可能生成的结果:
const testData = [
{ username: 'standard_user', password: 'secret_sauce', expected: 'success' },
{ username: 'locked_user', password: 'secret_sauce', expected: 'error' },
];
for (const data of testData) {
test(`登录测试 - ${data.username}`, async ({ page }) => {
console.log(`正在测试用户: ${data.username}`);
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login(data.username, data.password);
if (data.expected === 'success') {
await expect(page).toHaveURL(/dashboard/);
} else {
await expect(page.locator('.error-message')).toBeVisible();
}
});
}
5. 高级技巧:构建可复用的 AI 提示模板
将最佳实践固化为提示模板,实现“一次设计,多次复用”。
5.1 定位器优化模板
你是一个 Playwright 测试专家。请优化以下代码片段中的定位器:
1. 优先使用 `data-testid`、`role` 或 `aria-label` 等语义化属性。
2. 其次考虑稳定的 CSS 选择器(如 `[name="..."]`)。
3. 尽量避免使用包含动态文本(如 `:has-text()`)的定位器。
4. 为每个优化后的定位器添加一行注释,说明优化原因。
代码片段:
[粘贴你的录制代码]
5.2 完整流程重构模板
请基于以下 Playwright Inspector 录制代码,执行以下重构任务:
1. **提取 Page Object**:识别出独立的页面或组件,为其创建类。
2. **封装业务操作**:将连续的操作步骤封装为语义化的方法(如 `loginAsAdmin`)。
3. **替换脆弱等待**:移除所有 `waitForTimeout`,改用显式等待。
4. **添加关键断言**:在业务流程的关键节点(如表单提交后、页面跳转后)插入合理的断言。
5. **输出最终代码**:包含重构后的 Page Object 类和一段使用它的测试用例。
原始录制代码:
[粘贴你的完整录制代码]
6. 实践案例:从录制到 AI 增强的完整工作流
场景:录制一个在电商网站搜索商品并加入购物车的流程。
-
录制原始代码 (Playwright Inspector 生成):
await page.goto('https://shop.example.com'); await page.locator('#search-box').fill('laptop'); await page.locator('button.search-button').click(); await page.waitForTimeout(3000); await page.locator('.product-item:has-text("Gaming Laptop") >> button.add-to-cart').click(); await page.waitForTimeout(2000); -
人工预处理:添加注释,标记待优化点。
-
使用 AI 提示模板(5.2):将代码和提示词提交给 AI 助手。
-
获得 AI 重构代码:
// ProductSearchPage.js class ProductSearchPage { constructor(page) { this.page = page; this.searchInput = page.locator('#search-box'); this.searchButton = page.locator('button.search-button'); } async searchProduct(keyword) { await this.searchInput.fill(keyword); await this.searchButton.click(); await this.page.waitForSelector('.product-list', { state: 'visible' }); } } // ProductListingPage.js class ProductListingPage { constructor(page) { this.page = page; } async addProductToCart(productName) { const productItem = this.page.locator(`.product-item:has-text("${productName}")`); const addButton = productItem.locator('button.add-to-cart'); await addButton.click(); await this.page.waitForSelector('.cart-notification', { state: 'visible' }); } } // test.spec.js test('搜索并添加商品到购物车', async ({ page }) => { const searchPage = new ProductSearchPage(page); const listingPage = new ProductListingPage(page); await page.goto('https://shop.example.com'); await searchPage.searchProduct('laptop'); await listingPage.addProductToCart('Gaming Laptop'); await expect(page.locator('.cart-count')).toHaveText('1'); });
7. 总结与最佳实践
- 录制是起点,而非终点:将 Playwright Inspector 视为“操作记录仪”,其产出需要经过加工才能成为资产。
- 预处理是关键:花几分钟添加注释和标记,能极大提升 AI 的理解和输出质量。
- 提供明确指令:AI 需要方向。使用“重构为 Page Object”、“优化定位器”、“实现数据驱动”等具体动词。
- 迭代与验证:AI 生成的代码需要人工审查和运行验证。将其集成到你的 CI/CD 流水线中,确保功能正确。
- 积累提示库:将成功的 AI 交互保存为模板,逐步形成属于你团队的“AI 增强测试开发工作流”。
通过结合 Playwright Inspector 的便捷录制与 AI 助手的智能重构能力,你可以将原本繁琐、脆弱的脚本维护工作,转变为高效、可持续的自动化测试资产建设过程。
更多推荐




所有评论(0)