如何使用赛普拉斯测试文件输入?

sid*_*shi 9 javascript testing integration-testing e2e-testing cypress

如何编写需要与文件Input DOM元素交互的e2e流测试?

如果它是文本输入,我可以与它交互(检查值,设置值)等作为它的DOM组件.但是如果我有一个文件输入元素,我猜测交互是有限的,直到我可以打开对话框来选择文件.我无法前进并选择我要上传的文件,因为对话框是本机的而不是某些浏览器元素.

那么我如何测试用户是否可以从我的网站正确上传文件?我正在使用赛普拉斯编写我的e2e测试.

Muh*_*lal 46

it('Testing picture uploading', () => {
    cy.fixture('testPicture.png').then(fileContent => {
        cy.get('input[type="file"]').attachFile({
            fileContent: fileContent.toString(),
            fileName: 'testPicture.png',
            mimeType: 'image/png'
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

Use cypress file upload package: https://www.npmjs.com/package/cypress-file-upload

Note: testPicture.png must be in fixture folder of cypress

  • 很难让它发挥作用。看来代码已经改变了。该函数现在称为“cy.get( ... ).attachFile()”,而不是“cy.get( ... ).upload()”。我已经编辑了原来的答案。 (4认同)
  • 我也遇到了麻烦。为了修复它,我必须将 then 语句链接在一起,例如 `cy.fixture(...).then( fc => {return Cypress.Blob.base64StringToBlob( fc ) }).then(fileContentasBlob => { cy.get ('输入[类型=“文件”]').attachFile({ ...... ` (2认同)

Luc*_*ade 18

对我来说,更简单的方法是使用这个cypress 文件上传包

安装它:

npm install --save-dev cypress-file-upload
Run Code Online (Sandbox Code Playgroud)

然后将此行添加到您的项目的cypress/support/commands.js

import 'cypress-file-upload';
Run Code Online (Sandbox Code Playgroud)

现在你可以这样做:

const fixtureFile = 'photo.png';
cy.get('[data-cy="file-input"]').attachFile(fixtureFile);
Run Code Online (Sandbox Code Playgroud)

photo.png 必须在 cypress/fixtures/

有关更多示例,请查看软件包 README 上的使用部分。

  • 直接解决! (3认同)
  • 哇!我尝试了包自述文件中的所有(更复杂的)示例,但这个 - 最简单的 - 是唯一有效的!谢谢你! (2认同)

Jav*_*les 13

使用这种方法/ hack你可以实际做到:https: //github.com/javieraviles/cypress-upload-file-post-form

它基于前述线程的不同答案https://github.com/cypress-io/cypress/issues/170

第一个场景(upload_file_to_form_spec.js):

我想在提交表单之前测试必须选择/上传文件的UI.在cypress支持文件夹中的"commands.js"文件中包含以下代码,因此可以在任何测试中使用命令cy.upload_file():
Cypress.Commands.add('upload_file', (fileName, fileType, selector) => {
    cy.get(selector).then(subject => {
        cy.fixture(fileName, 'hex').then((fileHex) => {

            const fileBytes = hexStringToByte(fileHex);
            const testFile = new File([fileBytes], fileName, {
                type: fileType
            });
            const dataTransfer = new DataTransfer()
            const el = subject[0]

            dataTransfer.items.add(testFile)
            el.files = dataTransfer.files
        })
    })
})

// UTILS
function hexStringToByte(str) {
    if (!str) {
        return new Uint8Array();
    }

    var a = [];
    for (var i = 0, len = str.length; i < len; i += 2) {
        a.push(parseInt(str.substr(i, 2), 16));
    }

    return new Uint8Array(a);
}
Run Code Online (Sandbox Code Playgroud)

然后,如果你想上传一个excel文件,填写其他输入并提交表单,测试将是这样的:

describe('Testing the excel form', function () {
    it ('Uploading the right file imports data from the excel successfully', function() {

    const testUrl = 'http://localhost:3000/excel_form';
    const fileName = 'your_file_name.xlsx';
    const fileType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
    const fileInput = 'input[type=file]';

    cy.visit(testUrl);
    cy.upload_file(fileName, fileType, fileInput);
    cy.get('#other_form_input2').type('input_content2');
    .
    .
    .
    cy.get('button').contains('Submit').click();

    cy.get('.result-dialog').should('contain', 'X elements from the excel where successfully imported');
})
Run Code Online (Sandbox Code Playgroud)

})


Jen*_*ane 8

赛普拉斯尚不支持测试文件输入元素.测试文件输入的唯一方法是:

  1. 发布原生事件(赛普拉斯在其路线图中有此事件).
  2. 了解应用程序如何使用File API处理文件上载,然后将其存根.它可能但不够通用,无法提供任何具体的建议.

有关详细信息,请参阅此公开问题.


Vis*_*hwa 7

就我而言,我进行了客户端和服务器端文件验证以检查文件是 JPEG 还是 PDF。所以我必须创建一个上传命令,它会从 Fixtures 读取二进制文件并准备一个带有文件扩展名的 blob。

Cypress.Commands.add('uploadFile', { prevSubject: true }, (subject, fileName, fileType = '') => {
  cy.fixture(fileName,'binary').then(content => {
    return Cypress.Blob.binaryStringToBlob(content, fileType).then(blob => {
      const el = subject[0];
      const testFile = new File([blob], fileName, {type: fileType});
      const dataTransfer = new DataTransfer();

      dataTransfer.items.add(testFile);
      el.files = dataTransfer.files;
      cy.wrap(subject).trigger('change', { force: true });
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

然后将其用作

cy.get('input[type=file]').uploadFile('smiling_pic.jpg', 'image/jpeg');
Run Code Online (Sandbox Code Playgroud)

smile_pic.jpg 将在 fixtures 文件夹中