Multipart formdata POST request just doesn't work in Cypress for me

爷,独闯天下 提交于 2019-12-23 19:03:07

问题


Nothing works for me. If I use cy.request(), I'm unable to send formdata with it which contains a text and an image. So I've to go via XHR route. So, in my command.js I've used the following code to create a command: -

Cypress.Commands.add("formrequest", (method, url, formData, done) => {
  cy.window().then(win => {
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.open(method, url, false);
      xhr.setRequestHeader("accept", "application/json");
      xhr.setRequestHeader("access-token", accesstoken);
      xhr.setRequestHeader("client", client);
      xhr.setRequestHeader("expiry", expiry);
      xhr.setRequestHeader("token-type", tokentype);
      xhr.setRequestHeader("uid", uid);
      xhr.setRequestHeader("Accept-Encoding", null);
      xhr.onload = function() {
        done(xhr);
      };
      xhr.onerror = function() {
        done(xhr);
      };
      xhr.send(formData);
    });
  });
});

Now, when I'm calling it I will first construct a BLOB and then use it in my formdata to later send the XHR request. Like this: -

it.only("Test XHR", () => {
    cy.AppLogin();
    cy.fixture("/images/clients/Golden JPEG.jpeg", "binary").then(imageBin => {
      // File in binary format gets converted to blob so it can be sent as Form data
      Cypress.Blob.binaryStringToBlob(imageBin, "image/jpeg").then(blob => {
        // Build up the form
        const formData = new FormData();

        formData.set("client[name]", "Test TER"); //adding a plain input to the form

        formData.set(
          "client[client_logo_attributes][content]",
          blob
          //"Bull Client.jpg"
        ); //adding a file to the form

        // Perform the request
        cy.formrequest(method, url, formData, function(response) {
          expect(response.status).to.eq(201);
        });
      });
    });
  });

Please note that cy.AppLogin() sets up the request headers like accesstoken, client, expiry, tokentype and uid.

Kindly refer to the attached file (XHRfromCypress.txt) for checking the XHR request being generated using the code provided above. Also attached is a file (XHRfromCypressUI.txt) for showing XHR request being made when I did run my cypress end-2-end test from application UI.

I'm constantly getting 405, Method not allowed error.

E2E test from UI

API Test

E2E test works but API test using above code simply doesn't work. I also tried cy.request() but as it is not shown in the developers tab I'm not sure I've done it correctly. Also, i'm doubtful about the way I used formdata in there. Means whether cy.request() can even accept dormdata.

I've both (E2E and API) XHR's exported, just in case those are needed.

Do I need to add any libraries to make XHR request? I've aonly added Cypress library in my project setup.

////////////////

Moving all code into Test Case neither fixes anything

it.only("POSTing", () => {
    cy.fixture("/images/clients/Golden JPEG.jpeg", "binary").then(imageBin => {
      Cypress.Blob.binaryStringToBlob(imageBin, "image/jpeg").then(blob => {
        data.set("client[name]", "Test TER fails");
        data.set("client[client_logo_attributes][content]", blob);
        xhr.open(method, url);
        xhr.setRequestHeader("accept", "application/json");
        xhr.setRequestHeader("access-token", accesstoken);
        xhr.setRequestHeader("client", client);
        xhr.setRequestHeader("expiry", expiry);
        xhr.setRequestHeader("token-type", tokentype);
        xhr.setRequestHeader("uid", uid);
        xhr.send(data);
      });
    });
  });

回答1:


Thanks Eric. It works for me following Eric's advise and instructions mentioned at github.com/javieraviles/cypress-upload-file-post-form

Cypress.Commands.add(
  "Post_Clients",
  (imagePath, imageType, attr1, attr2, attr1Val, done) => {
    cy.fixture(imagePath, "binary").then(imageBin => {
      Cypress.Blob.binaryStringToBlob(imageBin, imageType).then(blob => {
        const xhr = new XMLHttpRequest();
        xhr.withCredentials = true;
        const data = new FormData();
        data.set(attr1, attr1Val);
        data.set(attr2, blob);
        xhr.open("POST", "https://api.teamapp.myhelpling.com/admin/clients");
        xhr.setRequestHeader("accept", "application/json");
        xhr.setRequestHeader("access-token", accesstoken);
        xhr.setRequestHeader("client", client);
        xhr.setRequestHeader("expiry", expiry);
        xhr.setRequestHeader("token-type", tokentype);
        xhr.setRequestHeader("uid", uid);
        xhr.onload = function() {
          done(xhr);
        };
        xhr.onerror = function() {
          done(xhr);
        };
        xhr.send(data);
      });
    });
  }
);


it.only("API POSTing TEST", () => {
    cy.Post_Clients(
      "/images/clients/Golden JPEG.jpeg",
      "image/jpeg",
      "client[name]",
      "client[client_logo_attributes][content]",
      "Test Attr 1 Value is Hi!!!",
      response => {
        cy.writeFile(
          "cypress/fixtures/POST API OUTPUT DATA/Client.json",
          response.
        );
        expect(response.status).to.eq(201);
      }
    );
  });


来源:https://stackoverflow.com/questions/54939625/multipart-formdata-post-request-just-doesnt-work-in-cypress-for-me

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!