在Node.js环境下使用Playwright添加自定义实现方式
作者:勤奋的码农007
这篇文章主要介绍了在Node.js环境下使用Playwright添加自定义实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
方法1:直接创建实用工具函数(推荐)
原理:创建独立的工具函数,通过参数传入 page
对象操作页面
// utils/custom-actions.js module.exports = { async login(page, username, password) { await page.goto('https://example.com/login'); await page.fill('#username', username); await page.fill('#password', password); await page.click('#submit'); await page.waitForURL(/dashboard/); }, async captureScreenshot(page, fileName) { await page.screenshot({ path: `screenshots/${fileName}.png` }); } };
使用方式:
const { test } = require('@playwright/test'); const { login, captureScreenshot } = require('./utils/custom-actions'); test('Authentication test', async ({ page }) => { // 使用自定义方法 await login(page, 'test@email.com', 'p@ssw0rd'); await captureScreenshot(page, 'dashboard-view'); });
方法2:封装自定义 Page 类(通过组合模式)
原理:创建代理类包裹原始 page
对象,添加额外方法
// lib/custom-page.js module.exports = class CustomPage { constructor(page) { this.page = page; } async typeSlowly(selector, text, delay = 100) { for (const char of text) { await this.page.type(selector, char); await this.page.waitForTimeout(delay); } } async dragAndDrop(sourceSel, targetSel) { const source = await this.page.$(sourceSel); const target = await this.page.$(targetSel); await this.page.dragAndDrop(source, target); } };
使用方式:
const { test } = require('@playwright/test'); const CustomPage = require('./lib/custom-page'); test('Form test', async ({ page }) => { const customPage = new CustomPage(page); await customPage.typeSlowly('#comment', 'Hello World', 150); await customPage.dragAndDrop('#item1', '#drop-zone'); });
方法3:通过 Test Fixtures 扩展(Playwright 官方推荐)
原理:利用 Playwright 的 fixture 系统扩展测试上下文
// fixtures.js const base = require('@playwright/test'); const CustomPage = require('./lib/custom-page'); exports.test = base.test.extend({ customPage: async ({ page }, use) => { const customPage = new CustomPage(page); await use(customPage); } });
使用方式:
// tests.spec.js const { test } = require('./fixtures'); test('Advanced test', async ({ customPage }) => { await customPage.typeSlowly('#bio', 'Automation Engineer'); // 原始 page 仍然可用 await customPage.page.keyboard.press('Enter'); });
主要优势
- 无侵入性:不修改 Playwright 源码或原型
- 按需组合:可以混合使用原生 API 和自定义方法
- 维护性强:自定义逻辑集中管理
- TypeScript 支持:通过声明文件添加类型提示(如使用 TS)
最佳实践建议
- 将常用操作封装成独立功能(如登录、数据生成)
- 为复杂交互创建专用工具类(如表格操作、拖放序列)
- 在 fixtures 中初始化常用测试状态
- 对自定义方法添加错误处理和日志
- 使用
page.waitForFunction()
实现高级等待逻辑
// 高级:等待元素包含特定文本 async waitForText(selector, text, timeout = 5000) { await this.page.waitForFunction( ({ sel, txt }) => { const el = document.querySelector(sel); return el?.innerText?.includes(txt); }, { selector, text }, { timeout } ); }
这些方法既保持了 Playwright API 的原始完整性,又能有效扩展测试能力,特别适合复杂应用的测试场景。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。