将上传的文件发送到赛普拉斯的后端

时间:2018-12-20 14:05:25

标签: javascript cypress ng-file-upload

我正在使用赛普拉斯的应用程序,但通过将上传的文件发送到后端遇到了问题。它发送一个空的FormData

我正在使用https://github.com/cypress-io/cypress/issues/170处的代码来处理文件上传,即:

 return cy.get('input[type=file]').then(subject => {
    return cy
        .fixture('blueprint.xlsx', 'base64')
        .then(Cypress.Blob.base64StringToBlob)
        .then(blob => {
            const el = <HTMLInputElement>subject[0]
            if (el != null) {
                const testFile = new File([blob], 'blueprint.xlsx')
                const dataTransfer = new DataTransfer()
                dataTransfer.items.add(testFile)
                el.files = dataTransfer.files
            }
            return subject
        })
}) 

当我调试API调用时,该文件已设置好,它位于fixtures文件夹中,并且一切正常,但是该调用没有任何formdata(应该是该文件),并以400 Bad Request错误结束。

为什么formdata为空?这是赛普拉斯的问题吗?有没有办法将我的装置文件发送到后端?

3 个答案:

答案 0 :(得分:1)

您的代码似乎可以在ng-file-upload demo page上正常运行。

我还测试了一个'xlsx'文件,没有发现问题。

describe('Angular file upload Demo', () => {

  /*
    To run these tests, add a file 'logo.png' to /cypress/fixtures
  */

  it('uploads the fixture file', () => {
    cy.visit('https://angular-file-upload.appspot.com/')
    cy.get('[name=userName]').type('myLogo')

    cy.get('[name=file]').then(subject => {
      return cy.fixture('logo.png', 'base64')
        .then(Cypress.Blob.base64StringToBlob)
        .then(blob => {
          console.log('blob', blob)
          const el = subject[0]
          if (el != null) {
            const testFile = new File([blob], 'logo.png')
            const dataTransfer = new DataTransfer()
            dataTransfer.items.add(testFile)
            el.files = dataTransfer.files
          }
          return subject          
        })
    })

    cy.contains('button', 'Submit').click()

    cy.contains('.progress', '100%')
    cy.contains('body', 'Upload Successful')
  })

  Cypress.Commands.add('uploadFile', { prevSubject: 'element' }, (subject, fileName) => {
    console.log('subject', subject)
    return cy.fixture(fileName, 'base64')
      .then(Cypress.Blob.base64StringToBlob)
      .then(blob => {
        console.log('blob', blob)
        const el = subject[0]
        if (el != null) {
          const testFile = new File([blob], fileName)
          const dataTransfer = new DataTransfer()
          dataTransfer.items.add(testFile)
          el.files = dataTransfer.files
        }
        return subject          
      })
    }
  )

  it('uploads the file via custom command', () => {
    cy.visit('https://angular-file-upload.appspot.com/')
    cy.get('[name=userName]').type('myLogo')

    cy.get('[name=file]').uploadFile('logo.png')

    cy.contains('button', 'Submit').click()

    cy.contains('.progress', '100%')
    cy.contains('body', 'Upload Successful')
  })

})

答案 1 :(得分:0)

经过数小时的尝试,我找到了使ng-file-upload工作的解决方法。

我想,至少我的问题是关于未作为Blob实例传递的文件。

我在柏树一侧使用了与乔纳斯相同的片段。

解决方法是在上载功能中添加一个检查,以管理select和drop指令中的更改。

function upload() {
    if (!Upload.isFile(file)) {
      file = new File([file], file.name, { type: file.type })
    }

    Upload.upload({
        url: "/api/upload",
        data: {
          file: file
        }
    })
    .then(/* ... */)
    /* ... */
}

这只是一种解决方法,我不太喜欢。

我不知道为什么会这样,只有当我使用赛普拉斯进行测试时,它才会发生在我身上,所以我不喜欢在生产代码中添加它。

有人可以帮我理解为什么会这样吗?

有人知道为什么传递到上载函数中的文件实例似乎是文件实例,但事实并非如此吗?

答案 2 :(得分:0)

我使用“ cypress”:“ 3.3.1”

以下代码对我有用,

const fixturePath = 'test.png';
const mimeType = 'application/png';
const filename = 'test.png';

cy.getTestElement('testUploadFrontID')
  .get('input[type=file')
  .eq(0)
  .then(subject => {
    cy.fixture(fixturePath, 'base64').then(front => {
      Cypress.Blob.base64StringToBlob(front, mimeType).then(function(blob) {
        var testfile = new File([blob], filename, { type: mimeType });
        var dataTransfer = new DataTransfer();
        var fileInput = subject[0];

        dataTransfer.items.add(testfile);
        fileInput.files = dataTransfer.files;

        cy.wrap(subject).trigger('change', { force: true });
      });
    });
  });

getTestElement 是我自己添加的命令,

Cypress.Commands.add(`getTestElement`, selector =>
cy.get(`[data-testid="${selector}"]`)
);