首页 > 解决方案 > Cypress_Test_Automation:如何为运行时创建的组件触发事件

问题描述

我正在使用 Cypress.io 来自动化一个基于反应页面的文件上传测试用例。文件上传的输入组件(type=file)是在页面渲染时在运行时创建的。

似乎该按钮(通过单击“选择文件”)打开了一个本机文件选择器,cypress Webdriver 似乎不支持与之交互,因此在这种情况下可能会触发一个模拟文件选择的事件。但是赛普拉斯无法找到 input(type=file),因为它不是 DOM 的一部分,这意味着 cy.get('input[type=file]') 返回 null。

你能给我一些想法吗? 此按钮打开本机文件选择器

我试过这个 -

const testfile = new File(['test data to upload'], 'upload.csv')

cy.get('input[type=file]').trigger('change', {
  force: true,
  data: testfile,
});

这不会带来任何运气,因为 CypressError: Timed out retrying: E​​xpected to find element: 'input[type=file]',但从未找到它。

页面源代码:

import React, { Component } from 'react'

interface Props {
  text?: string
  type?: string | undefined
  fileID?: string
  onFileSelected: (file: any) => void
}

interface State {
  name: string
}

export default class FileUpload extends Component<Props, State> {
  fileSelector = document.createElement('input')

  state: State = {
    name: '',
  }

  componentDidMount() {
    this.fileSelector = this.buildFileSelector()
  }

  buildFileSelector = () => {
    const { fileID, type } = this.props

    this.fileSelector.setAttribute('type', 'file')
    this.fileSelector.setAttribute('id', fileID || 'file')
    this.fileSelector.setAttribute('multiple', 'multiple')
    this.setAcceptType(type)
    this.fileSelector.onchange = this.handleFileChange
    return this.fileSelector
  }

  setAcceptType = (type: string | undefined) => {
    if (type) {
      type = type[0] === '.' ? type : type.replace(/^/, '.')
      this.fileSelector.setAttribute('accept', type)
    }
  }

  handleFileChange = (event: any) => {
    const file = event.target.files[0]
    if (file) {
      this.setState({ name: file.name })
      this.props.onFileSelected(file)
    }
  }

  render() {
    const { name } = this.state
    return (
      <div>
        <button
          onClick={(event: React.ChangeEvent<any>) => {
            event.preventDefault()
            this.fileSelector.click()
          }}
          style={{ marginRight: 10 }}
        >
          {this.props.text || 'Choose file'}
        </button>
        <label>{name || 'No file chosen'}</label>
      </div>
    )
  }
}

我期待收到有关如何在赛普拉斯中自动执行“选择文件”操作的建议。提前致谢。

标签: reactjsautomated-testscypress

解决方案


我通过将 input(type=file) 元素放入 DOM 来解决这个问题,以便 cypress 可以找到该元素并对其进行操作。

但是关于我之前遇到的问题,如果这仍然可以在柏树中处理,我仍然想听听你的一些见解。


推荐阅读