Skip to content

Cypress - 文件上传

Cypress 通过 .selectFile() 命令提供了模拟文件上传的原生支持。此命令可用于 <input type="file"> 元素,以触发文件选择,就像用户操作一样。

对于大多数标准的文件上传场景,内置的 .selectFile() 命令就足够了并且是推荐使用的。将要上传的文件放在你的 cypress/fixtures 文件夹中以便轻松访问。

.selectFile() 命令可以接受:

  • fixture 文件的路径:cy.get('input[type="file"]').selectFile('cypress/fixtures/my-image.png')
  • Fixture 选项:cy.get('input[type="file"]').selectFile({ contents: 'cypress/fixtures/my-document.pdf', fileName: 'report.pdf', mimeType: 'application/pdf' })
  • 文件内容(Buffer 或字符串):cy.get('input[type="file"]').selectFile({ contents: Cypress.Buffer.from('file content'), fileName: 'example.txt', mimeType: 'text/plain' })
  • 对于多文件上传,可以传入文件数组(如果输入元素支持)。

假设你的 cypress/fixtures 文件夹中有一个名为 avatar.png 的文件。

以下是如何在 Cypress 测试中使用 .selectFile() 命令实现文件上传:

describe('File Upload Test', () => {
it('Successfully uploads a file', () => {
// Path to the file in the fixtures folder
// fixture 文件夹中文件的路径
const fixtureFile = 'avatar.png';
// Visit the page with the file upload form
// 访问带有文件上传表单的页面
cy.visit('https://the-internet.herokuapp.com/upload');
// Select the file using the input element's ID
// 使用输入元素的 ID 选择文件
cy.get('#file-upload').selectFile(`cypress/fixtures/${fixtureFile}`);
// Click the submit button
// 点击提交按钮
cy.get('#file-submit').click();
// Verify that the file was uploaded
// 验证文件是否已上传
cy.get('#uploaded-files').should('contain.text', 'avatar.png');
});
});

此测试运行时:

  • Cypress 导航到上传页面。
  • 它找到 ID 为 file-upload 的 <input type="file"> 元素。
  • .selectFile() 命令将 cypress/fixtures 文件夹中的 avatar.png 文件附加到此输入元素。
  • 然后 Cypress 点击提交按钮。
  • 最后,它验证文本 ‘avatar.png’ 是否出现在 ID 为 uploaded-files 的元素中,从而确认上传成功。

Test Runner 将显示这些步骤,如果上传成功,断言将通过。你不会看到原生的操作系统文件对话框;Cypress 是通过代码方式处理文件附加的。

对于较旧的项目或非常特定的边缘情况(例如 .selectFile() 不直接支持的拖放上传),cypress-file-upload 插件曾是常见的解决方案。虽然现在更推荐使用 .selectFile(),但了解这个插件也很有用。

要使用它,首先需要安装:

npm install --save-dev cypress-file-upload

然后,在你的 cypress/support/e2e.js(或 commands.js)文件中导入它:

cypress/support/e2e.js
import 'cypress-file-upload';

该插件提供了一个 .attachFile() 命令,用法类似:cy.get('#file-upload').attachFile(fixtureFile);

然而,应始终优先尝试使用原生的 .selectFile() 命令,因为它由 Cypress 团队维护并直接集成到核心中。