You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cypress使用attachFile()实现图片/视频拖拽上传失败如何解决

Cypress 拖拽上传媒体文件问题排查与解决

问题描述

尝试了多种方案在Cypress中通过attachFile()实现图片或视频文件的拖拽上传、普通附件上传,运行测试后图片无法加载到模态框中,添加按钮始终处于禁用状态,最终测试失败。

已尝试的方案

方案1:基础attachFile拖拽自定义命令

Cypress.Commands.add('uploadMedia', (mediaType) => {
  cy.wait(2000)
  const fileName = 'Cover.jpg'
  cy.fixture('Cover.jpg').then(Cypress.Blob.base64StringToBlob)
  .then((fileContent) =>
  {
      cy.get(newStoryPage.getDragAndDropFiles()).attachFile(
      {
          fileContent, fileName, mimeType: 'image/jpg'},
          {subjectType: 'drag-n-drop'
      })
  })
})

方案2:指定拖拽事件的attachFile实现

cy.fixture('Cover.jpg').then(jpg => {
  const files = [
      { fileName: 'Cover.jpg', fileContent: jpg, mimeType: 'image/jpg' }
    ]
    newStoryPage.getDragAndDropFiles().attachFile(files, {subjectType: 'drag-n-drop', events: ['dragenter', 'drop'] })
  })

方案3:自定义dropFile拖拽命令

Cypress.Commands.add('dropFile', {prevSubject: false}, (fileName) =>
{
          Cypress.log({name: 'dropFile'})
      return cy.fixture(fileName, 'base64').then(Cypress.Blob.base64StringToBlob).then((blob) =>
      {
          return cy.window().then((win) =>
          {
              const file = new win.File([blob], fileName)
              const dataTransfer = new win.DataTransfer()
              dataTransfer.items.add(file)
              return cy.document().trigger('drop', {dataTransfer})
          })
      })
  }
)

关联代码

拖拽区域元素获取逻辑

class NewStoryPage {
  getDragAndDropFiles() {
    return cy.get("div[class*='upload-file-ui']")
  }
}

自定义命令调用代码

import NewStoryPage from '../../support/pageobjects/NewStoryPage'
const newStoryPage = new NewStoryPage()
class Create {
  uploadImage() {
      newStoryPage.getDragAndDropFiles().trigger('dragenter')
      cy.dropFile('Cover.jpg')
      newStoryPage.getAddButton().click()
  }
}
export default Create

页面对应HTML结构

<div class="jsx-3861824103 upload-file-ui">
<span class="jsx-3993537252 icon">
<svg viewBox="0 0 32 32" class="jsx-3993537252">
<path d="M31.8 16.704c0 3.489-2.765 6.296-5.238 6.296H24v-1h2.562c1.92 0 4.238-2.362 4.238-5.296a5.359 5.359 0 0 0-3.607-5.097l-.407-.138-.581-.198-.087-.608-.06-.425A7.953 7.953 0 0 0 18.462 3.2a7.647 7.647 0 0 0-6.683 4.187l-.259.488-.37.696-.763-.197-.535-.138a3.474 3.474 0 0 0-.874-.13 2.943 2.943 0 0 0-3.024 2.766l-.022.404-.031.573-.51.262-.357.183A5.173 5.173 0 0 0 2.2 16.897c0 2.653 2.166 5.085 4.545 5.103H11v1H6.737C3.733 22.978 1.2 19.988 1.2 16.897a6.169 6.169 0 0 1 3.378-5.493l.357-.183.022-.402a3.93 3.93 0 0 1 4.022-3.713 4.432 4.432 0 0 1 1.125.162l.534.138.26-.488A8.645 8.645 0 0 1 18.462 2.2a8.956 8.956 0 0 1 8.584 7.897l.06.425.408.138a6.358 6.358 0 0 1 4.285 6.044zM18 14.707l2.646 2.646.707-.707-3.853-3.853-3.854 3.854.707.707L17 14.707V30h1z" class="jsx-3993537252">
</path>
</svg>
</span>
<div class="jsx-3861824103 upload-section">
<p class="jsx-3861824103 upload-title">Drag and drop a file here</p>
<div class="jsx-3861824103 upload-description">Only include media in your story that you have permission to use and will not violate copyright laws if published.<span class="jsx-3861824103">&nbsp;</span>
<a rel="noopener noreferrer" target="_blank" class="jsx-181317841">
<span class="jsx-181317841">Learn more</span>
</a>
</div>
</div>
<button type="button" class="jsx-4157471165 button default primary">Browse your files</button>
<p class="jsx-3861824103 upload-types">Supported file types: .jpg, .png, .gif, .svg</p>
</div>

失败运行截图

attachFile() DragAndDrop

可行解决方案

问题主要出在三个核心点:自定义drop事件触发对象错误、拖拽事件链不全、MIME类型不符合规范、未等待文件处理完成就点击按钮,对应修复方案如下:

方案A:使用cypress-file-upload插件原生能力(推荐)

如果你使用的是v5+版本的cypress-file-upload插件,直接调整调用逻辑即可:

uploadImage() {
  // 先确认拖拽区域可见
  newStoryPage.getDragAndDropFiles()
    .should('be.visible')
    // 插件会自动补全完整拖拽事件链
    .attachFile('Cover.jpg', {
      subjectType: 'drag-n-drop',
      mimeType: 'image/jpeg', // 修正为标准jpg MIME类型
      force: true
    })
  // 等待按钮变为可点击状态再操作,不要用硬等待
  newStoryPage.getAddButton()
    .should('not.be.disabled', { timeout: 10000 })
    .click()
}

方案B:调整自定义dropFile命令

如果不想依赖插件,修改自定义命令,将事件触发到目标拖拽元素而非全局document:

// 支持链式调用的自定义drop命令
Cypress.Commands.add('dropFile', {prevSubject: 'element'}, (subject, fileName, mimeType = 'image/jpeg') => {
  Cypress.log({name: 'dropFile'})
  return cy.fixture(fileName, 'base64')
    .then(Cypress.Blob.base64StringToBlob)
    .then((blob) => {
      return cy.window().then((win) => {
        const file = new win.File([blob], fileName, { type: mimeType })
        const dataTransfer = new win.DataTransfer()
        dataTransfer.items.add(file)
        // 触发完整的拖拽事件流,匹配前端组件监听逻辑
        return cy.wrap(subject)
          .trigger('dragenter', { dataTransfer, force: true, bubbles: true })
          .trigger('dragover', { dataTransfer, force: true, bubbles: true })
          .trigger('drop', { dataTransfer, force: true, bubbles: true })
          .trigger('dragleave', { force: true, bubbles: true })
      })
    })
})
// 调用逻辑调整
uploadImage() {
  newStoryPage.getDragAndDropFiles()
    .should('be.visible')
    .dropFile('Cover.jpg')
  newStoryPage.getAddButton()
    .should('not.be.disabled', { timeout: 10000 })
    .click()
}

前置检查项

  • 确认Cover.jpg文件已放在cypress/fixtures目录下
  • 如果上传其他格式文件,对应修改MIME类型即可

内容的提问来源于stack exchange,提问作者user2367924

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:36:00