1. Playwright 文件上传与下载的实战痛点
在Web自动化测试中,文件传输操作一直是个让人头疼的环节。我最近在给某电商平台做自动化测试时,就遇到了这样的场景:需要批量上传商品主图,然后验证后台是否正确生成缩略图。传统方案要么无法准确判断上传完成状态,要么在下载文件时出现竞态条件导致测试失败。
Playwright作为新一代的测试框架,其实提供了相当完善的文件传输解决方案。但官方文档对这部分功能的说明比较分散,很多实用技巧藏在API的细节里。经过多个项目的实战积累,我总结出了这套覆盖90%实际场景的操作方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 文件上传的三种实战模式
2.1 标准input上传控件处理
最常见的上传场景是面对<input type="file">元素。Playwright的处理比Selenium优雅得多:
typescript复制// 单个文件上传
await page.locator('input#upload').setInputFiles('assets/photo1.jpg')
// 多文件上传
await page.locator('input#upload').setInputFiles([
'assets/photo1.jpg',
'assets/photo2.png'
])
关键细节:
- 文件路径可以是相对路径或绝对路径
- 支持所有浏览器,包括移动端模拟
- 自动等待元素可交互状态,无需额外等待
踩坑提醒:遇到动态生成的input元素时,建议先用
page.waitForSelector()确保元素加载完成
2.2 非标准上传控件的破解方案
很多现代前端框架会自定义上传组件,隐藏原生input元素。这时需要分步处理:
typescript复制// 1. 触发文件选择对话框
const [fileChooser] = await Promise.all([
page.waitForEvent('filechooser'),
page.locator('.custom-upload-button').click()
])
// 2. 设置文件
await fileChooser.setFiles('test-data/file.zip')
实战技巧:
- 某些组件需要先hover再点击,可以组合使用:
typescript复制await page.locator('.drop-zone').hover() await page.locator('.drop-zone').click() - 拖拽上传场景可以用
page.dragAndDrop()
2.3 大文件上传优化策略
当处理GB级大文件时,需要特殊优化:
typescript复制// 分片上传示例
const chunkSize = 5 * 1024 * 1024 // 5MB
const fileBuffer = fs.readFileSync('large-video.mp4')
for (let i = 0; i < fileBuffer.length; i += chunkSize) {
const chunk = fileBuffer.slice(i, i + chunkSize)
await page.evaluate((chunk) => {
// 通过API发送分片
uploadNextChunk
