Playwright 文件操作

Playwright 文件操作(2025 年最新版)

Playwright 本身是浏览器自动化工具,主要在浏览器环境中运行,但它提供了便捷的 API 来处理文件上传文件下载。此外,在 Node.js 环境中,你可以结合 Node.js 的 fs 模块实现更复杂的本地文件读写操作。下面详细讲解常见文件操作场景。

1. 文件上传(File Upload)

最常见的两种上传方式:

方式一:直接设置 input[type=”file”](推荐,最稳定)

// tests/upload.spec.ts
import { test, expect } from '@playwright/test';
import path from 'path';

test('单个文件上传', async ({ page }) => {
  await page.goto('https://example.com/upload');

  // 准备本地文件路径(相对项目根目录)
  const filePath = path.join(__dirname, '../files/avatar.jpg');

  // 设置文件(自动触发 change 事件)
  await page.getByLabel('上传头像').setInputFiles(filePath);

  // 验证上传成功
  await expect(page.getByText('上传成功')).toBeVisible();
});

方式二:上传多个文件

await page.getByLabel('批量上传').setInputFiles([
  path.join(__dirname, '../files/file1.pdf'),
  path.join(__dirname, '../files/file2.png'),
]);

方式三:清空已选择的文件

await page.getByLabel('上传文件').setInputFiles([]);  // 清空

方式四:拖拽上传(模拟 Drag & Drop)

// 创建 DataTransfer 对象模拟拖拽
await page.evaluate(async ({ filePath }) => {
  const input = document.querySelector('input[type="file"]') as HTMLInputElement;
  const file = await fetch(filePath).then(r => r.blob()).then(b => new File([b], 'test.jpg'));
  const dt = new DataTransfer();
  dt.items.add(file);
  input.files = dt.files;
  input.dispatchEvent(new Event('change', { bubbles: true }));
}, { filePath: 'http://example.com/test.jpg' });  // 或本地路径需特殊处理

2. 文件下载(File Download)

test('文件下载并验证', async ({ page }) => {
  // 监听下载事件
  const [download] = await Promise.all([
    page.waitForEvent('download'),  // 等待下载开始
    page.getByRole('link', { name: '下载报告' }).click(),
  ]);

  // 获取下载对象
  console.log('文件名:', download.suggestedFilename());  // e.g., report.pdf

  // 保存到指定路径(推荐)
  const downloadPath = path.join(__dirname, '../downloads');
  await download.saveAs(path.join(downloadPath, download.suggestedFilename()));

  // 或获取临时路径(headless 模式下有效)
  const tempPath = await download.path();

  // 验证文件存在(结合 Node.js fs)
  const fs = require('fs');
  expect(fs.existsSync(tempPath)).toBeTruthy();

  // 可选:取消下载
  // await download.cancel();
});

注意

  • 在 headless 模式下,下载的文件保存在临时目录,download.path() 可用。
  • 在 headed 模式下,默认弹出系统保存对话框,download.path() 会返回 null。建议测试时统一使用 headless。

3. 结合 Node.js fs 进行本地文件操作

Playwright 测试运行在 Node.js 环境中,可以自由使用 fs 模块读写文件,常用于:

  • 准备测试数据
  • 验证下载文件内容
  • 生成临时文件
import fs from 'fs';
import path from 'path';

test('验证下载文件内容', async ({ page }) => {
  // ...触发下载代码同上

  const savedPath = path.join(__dirname, '../downloads/report.pdf');
  await download.saveAs(savedPath);

  // 读取文件内容验证
  const buffer = fs.readFileSync(savedPath);
  expect(buffer.length).toBeGreaterThan(1000);  // 大于 1KB

  // 或验证文件类型(PDF 开头 %PDF)
  expect(buffer.toString('utf8', 0, 5)).toBe('%PDF-');

  // 测试后清理
  fs.unlinkSync(savedPath);
});

4. playwright.config.ts 中配置下载路径(可选)

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    // 统一设置下载目录
    downloadsPath: 'downloads',
  },
});

然后 download.path() 会直接返回该目录下的路径。

5. Python 版文件操作示例

from playwright.sync_api import sync_playwright
import os

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://example.com/upload")

    # 上传
    page.get_by_label("选择文件").set_input_files("tests/files/test.pdf")

    # 下载
    with page.expect_download() as download_info:
        page.get_by_text("下载").click()
    download = download_info.value
    download.save_as("downloads/myfile.pdf")

    # 验证文件大小
    assert os.path.getsize("downloads/myfile.pdf") > 1000

    browser.close()

最佳实践总结

  • 上传:优先用 setInputFiles() + 绝对路径(path.join(__dirname, ...))。
  • 下载:始终用 page.waitForEvent('download') + saveAs() 保存到自定义目录,便于验证。
  • 文件路径:使用 path.join() 避免跨平台问题。
  • 清理:测试结束后删除临时文件,保持环境干净。
  • CI/CD:确保下载目录有写权限。

这些操作能让你轻松处理文件相关的测试场景(如表单上传、报告导出)。如果需要完整示例项目或处理压缩文件/大文件下载的进阶技巧,随时告诉我!

文章已创建 3420

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部