cypress

how to send binary file to server with Cypress using request


I need before the test to upload directly from Cypress API to server an excel-table (without any input[type="file"], just plain file submission) and then it will be requested back with some other data and used by the test.

So i tried in different ways to make Cypress to use the file by fixture, readfile with different data-encodings, but neigther was working.

As soon as file is received successfully some rest of the code must run.

  before(() => {

  cy.fixture("data/catalog.xlsx", "binary")
    .then(content => {

      cy.wrap(Cypress.Blob.binaryStringToBlob(content, "utf8"))
        .then(blob => {

          const file = new File([blob], "catalog-table", {type: "utf8"});

          cy.request("POST", "http://localhost:28080/app/admin/api/catalog/import/xlsx", file)
            .then(res => {debugger; expect(res.ok).to.be.true})
            .as("fileSend");

          cy.wait("@fileSend")
            .then(() => {some other code to be executed});
        })
    })
})

also tried to add few more headers lines

          cy.request({
            method: "POST",
            url: "http://localhost:28080/app/admin/api/catalog/import/xlsx",
            headers: {
              contentType: false,
              processData: false,
            },
            cache: 'no-cache',
            body: file
          })

Solution

  • I found out that neither cy.request nor Cypress.$.ajax werent working at all with files.

    My problem was hidden in two issues:

    1. the way of handling the file before submission;
    2. faulty native cypress request method

    Here are some details to take into account:

    before(() => { //run before the tests
      cy.fixture(filePath, "binary")
    
        .then(Cypress.Blob.binaryStringToBlob)
        .then(blob => {
          const file = new File([blob], fileName);
    
          let data = new FormData();
    
          //settings for host server
          data.append("catalogName", fileName);
          data.append("xlsxFile", file);
    
          cy.form_request(url, data)
            .then(response => { some other code})
        })
    })
    
    

    Because Cypress.$.ajax was illegaly invoked but in the web its difficult to find out the source of problem. cypress crashed on formData preparation; I found that out from Network section in Devtool there was no any XHR request because it failed from the start.

    I found third way by native XHR workaround and there is the custom request cy.form_reques placed in commands.js:

    
    Cypress.Commands.add("form_request", (url, formData) => {
      return cy
        .server()
        .route("POST", url)
        .as("formRequest")
        .window()
        .then(win => {
          var xhr = new win.XMLHttpRequest();
          xhr.open("POST", url);
          xhr.send(formData);
        })
        .wait("@formRequest");
    });