【问题标题】:Uploading multipart/form-data from text file using Cypress使用赛普拉斯从文本文件上传 multipart/form-data
【发布时间】:2021-10-10 00:49:51
【问题描述】:

我整天都在做这件事,我真的需要朝着正确的方向轻推。

我的依赖是 -

  "dependencies": {
    "typescript": "^4.3.5",
    "cypress": "^8.1.0",
    "cypress-file-upload": "^5.0.8"
  } 

我有一个叫uploadBlob.txt的夹具

这就是它的样子-

------WebKitFormBoundary7BhOPSS0NpEAppSA
Content-Disposition: form-data; name="UploadedFileName"

Prod_CA.ACI
------WebKitFormBoundary7BhOPSS0NpEAppSA
Content-Disposition: form-data; name="OrderId"

7815968_13735
------WebKitFormBoundary7BhOPSS0NpEAppSA
Content-Disposition: form-data; name="Options[orderid]"

7815968_13735
------WebKitFormBoundary7BhOPSS0NpEAppSA
Content-Disposition: form-data; name="Options[clientcode]"

1135
------WebKitFormBoundary7BhOPSS0NpEAppSA
Content-Disposition: form-data; name="Options[vendorserviceurl]"

[... 80+ More Items ...]

------WebKitFormBoundary7BhOPSS0NpEAppSA--

我想做的是这样的-

Cypress.Commands.add("formRequest", (info: ReqInfo) => {
    cy.readFile("./fixtures/uploadBlob.txt", "utf-8").then(fixture => {
        const blob = Cypress.Blob.binaryStringToBlob(fixture, "application/text");
        const formData = new FormData();
        formData.append('file', blob, "uploadBlob.txt");

        return cy.request({
            url: info.url,
            method: info.method,
            headers: info.headers,
            form: true,
            body: formData
        })
    })
});

info 看起来像这样 -

let info : ReqInfo = {
   method: "POST",
   url : 'https://uat-delivery.acisky.com/Delivery/bkfs/Start',
   headers: {
       'Authority': 'uat-delivery.acisky.com',
       'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7BhOPSS0NpEAppSA',
       'Path': '/DeliveryUpload/bkfs/UploadFile',
       'sec-fetch-dest': 'empty',
       'sec-fetch-mode': 'cors',
       'sec-fetch-site': 'same-origin',
       }
 }

这是我得到的错误 -

From Node.js Internals:
  TypeError [ERR_INVALID_ARG_TYPE] [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined
      at Function.from (buffer.js:333:9)
      at Object.sendPromise 

最后我基于这些尝试了XMLHttpRequest() 的多次迭代 -

例如-

Cypress.Commands.add("formRequest", (info: ReqInfo) => {
    cy.readFile("./fixtures/uploadBlob.txt", "utf-8").then(fixture => {
        const blob = Cypress.Blob.binaryStringToBlob(fixture, "application/text");
        const formData = new FormData();
        formData.append('file', blob, "uploadBlob.txt");

        const xhr = new XMLHttpRequest();
        xhr.responseType = 'text';
        xhr.onload = function () {
            if (xhr.readyState === xhr.DONE) {
                if (xhr.status === 200) {
                    console.log(xhr.response);
                    console.log(xhr.responseText);
                }
            }
        };

        xhr.open(info.method, info.url);
        xhr.setRequestHeader("accept", "application/json");
        xhr.setRequestHeader("content-Type", "multipart/form-data");
        xhr.setRequestHeader('Authority', 'uat-delivery.acisky.com'),
        xhr.send(formData);

    })

但在这里我得到了错误-

{"errors":["No file found in request"]}

即使我可以看到ReadFile 工作正常。

我使用WebKitBoundry 使用 readFile/fixture 路线的原因是因为有超过 80 个“字段”,并且在未来,我们将需要该文件的 20-30 个变体。

如果有人对如何完成这项任务有任何想法,我会很乐意提供帮助。

谢谢

【问题讨论】:

  • 在哪里可以找到the first argument must be.... 问题的解决方案?我遇到了同样的问题。
  • @Edward - 我刚刚发布了我的答案,希望对您有所帮助。

标签: typescript xmlhttprequest cypress


【解决方案1】:

下面的例子可以帮助你:

    cy.fixture("xml.xml", 'binary')
        .then((file) => Cypress.Blob.binaryStringToBlob(file))
        .then((blob) => {

            var formdata = new FormData();
            formdata.append("file", blob, "xml.xml");

            cy.request({
                url: "/api",
                method: "POST",
                headers: {
                    Authorization: `bearer ${token}`,
                    'content-type': 'multipart/form-data'
                },
                body: formdata
            }).its('status').should('be.equal', 200)
        })

为了在cypress中使用multipart/form-data,我们需要创建一个上面调用FormData的实例。

【讨论】:

    【解决方案2】:

    我将发布更新,以防有人遇到我的解决方法。

            it('Should Upload the ACI document', () => {
    
                let url = format(aci_url, ENV.env, workOrder.workOrderId, integrator.postfix)
    
                cy.visitURL(url).enter().then(iFrame => {
                    iFrame().find(UploadDocPage.pageBody).then(input => {
                            cy.fixture("./files/" + UploadDocPage.fixtureName, 'binary')
                                .then(Cypress.Blob.binaryStringToBlob)
                                .then(fileContent => {
                                    cy.wrap(input).attachFile({
                                        fileContent: fileContent,
                                        filePath: UploadDocPage.fixtureName
                                 }).task("log", `Document Attached`)
                            })
                        }).wait(5000)
    
                    iFrame().waitForElement(UploadDocPage.goButton).click({force: true})
                    iFrame().waitForElement(UploadDocPage.deliverButton).click({force: true})
                    cy.task("log", `Document Sent`)
                })
            })
    

    使这变得更加困难的是它位于 iFrame() 中。

    该文件是一个 ACI 文档(“TestFile.ACI”) - 本质上,它将夹具作为二进制文件,将其转换为 blob 字符串,然后将字符串发送到“输入”。

    【讨论】:

      猜你喜欢
      • 2020-03-01
      • 2015-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-14
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多