使用Cypress处理React重新渲染

时间:2020-10-16 09:26:06

标签: reactjs cypress react-select

我有两个react-select Select并排放置。选择一个更新状态并确定第二个Select中的值。

我的cypress测试做到了:

// select an option in the first select - this works
cy.get('div[class*="container"]').contains('Select 1').click()
cy.get('div[class*="option"]').contains('Select 1 Option 1').click()

// select an option in the second select - this doesn't work
cy.get('div[class*="container"]').contains('Select 2').click() // <<< error occurs here
cy.get('div[class*="option"]').contains('Select 2 Option 1').click()

因此,成功选择了第一个Select中的选项。但是第二个不是-我收到此错误:

Timed out retrying: cy.click() failed because this element is detached from the DOM.

我在cy.wait(10)设置第二个get之前尝试过Select,是的,这是不好的做法,但是即使如此,它也不能解决问题。如何正确执行此操作?

编辑:

这是Select s的实现的抽象:

const [state, setState] = useState([
  {
    select: '', option: ''
  }
])

const options = {
  "Select 1": [
    "Select 1 Option 1",
    "Select 1 Option 2"
  ],
  "Select 2": [
    "Select 2 Option 1",
    "Select 2 Option 2"
  ]
}

return (
  {state.map((row, index) => {
    <Select
      options={Object.keys(options)}
      value={row.select}
      onValueChange={value => setState({
        ...state,
        select: value
      })}
    />
    <Select
      options={options[row.select]}
      value={row.option}
      onValueChange={value => setState({
        ...state,
        option: value
      })}
    />
  })}
)

当然,react-select不能接受字符串数组作为options,因此在我的实际实现中,我有一个函数将每个字符串转换为{label: '', value: ''}对象,但这是此图不是必需的。

上面的想法是,当我选择第一个Select的值时,视图会重新渲染,因为state发生了变化。

1 个答案:

答案 0 :(得分:1)

从您的抽象中有点难以猜测,但您似乎没有更新设置第二个选择值的 state.option 的值。我不确定你的默认状态是什么,但从你上面的代码片段中,cypress 找不到任何一个选择,因为当你这样做时 cy.get('div[class*="container"]').contains('Select 1') 没有任何 DOM 元素实际上会包含匹配的字符串 Select 1 .

因为你提到第一个 cy 命令有效,我不确定 Select 是如何初始化的,所以这有点猜测。

看看这里:https://codesandbox.io/s/compassionate-moon-ss4z9?file=/src/App.js