用 Cypress 移动滑块

IT技术 reactjs cypress
2021-05-15 16:17:13

我有一个来自 rc-slider 的 Slider 组件,我需要 Cypress 来设置它的值。

<Slider
 min={5000}
 max={40000}
 step={500}
 value={this.state.input.amount}
 defaultValue={this.state.input.amount}
 className="sliderBorrow"
 onChange={(value) => this.updateInput("amount",value)} 
 data-cy={"input-slider"}
 />

这是我的赛普拉斯代码:

it.only("Changing slider", () => {
    cy.visit("/");
    cy.get(".sliderBorrow")
      .invoke("val", 23000)
      .trigger("change")
      .click({ force: true })
  });

到目前为止我尝试过的方法不起作用。滑块的起点是20000,试运行后到22000,不管我传什么值,任何数字范围。

看起来它以前可以工作,如何与 Cypress 中的范围输入(滑块)正确交互?但不是了。

3个回答

答案非常非常简单。我发现解决方案是巧合地为我的另一个测试(日期选择器)按下 Enter 键,并意识到按向左或向右箭头键适用于滑块。您也可以使用props获得相同的结果。您唯一需要做的就是添加此依赖项:cypress-react-selector 和以下说明:cypress-react-selector

使用示例 {rightarrow}

it("using arrow keys", () => {
  cy.visit("localhost:3000");

  const currentValue  = 20000;
  const targetValue = 35000;
  const increment = 500;
  const steps = (targetValue - currentValue) / increment;
  const arrows = '{rightarrow}'.repeat(steps); 

  cy.get('.rc-slider-handle')
    .should('have.attr', 'aria-valuenow', 20000)
    .type(arrows)

  cy.get('.rc-slider-handle')
    .should('have.attr', 'aria-valuenow', 35000)

})

@darkseid 的回答帮助我找到了最佳解决方案。

有两个步骤

  1. 单击滑块的圆圈,将当前焦点移动到滑块上。
  2. 按键盘箭头按钮达到您想要的值。

我的滑块在滑块上的值之间跳转,因此这种方法会起作用。(我正在使用离子范围滑块)

这种方法不需要任何额外的依赖。

滑块图像

// Move the focus to slider, by clicking on the slider's circle element
cy.get(".irs-handle.single").click({ multiple: true, force: true });
// Press right arrow two times
cy.get(".irs-handle.single").type(
  "{rightarrow}{rightarrow}"
);

您可以使用Application actions来解决这个问题,前提是您可以稍微修改应用程序源代码。

应用程序操作为测试提供了一个进入应用程序的挂钩,可用于修改应用程序的内部状态。

我使用setValueuseState()钩子公开的 Function 组件对其进行了测试
您已经使用了 Class 组件,所以我想您会this.updateInput()改为公开,例如

  if (window.Cypress) {
    window.app = { updateInput: this.updateInput };
  }

应用程序:index.js

import React, { useState } from 'react';
import { render } from 'react-dom';
import './style.css';

import Slider from 'rc-slider';
import 'rc-slider/assets/index.css';

function App() {

  const [value, setValue] = useState(20000);

  // Expose the setValue() method so that Cypress can set the app state
  if (window.Cypress) {
    window.app = { setValue };
  }

  return (
    <div className="App">
      <Slider
        min={5000}
        max={40000}
        step={500}
        value={value}
        defaultValue={value}
        className="sliderBorrow"
        onChange={val => setValue(val)}
        data-cy={"input-slider"}
      />
      <div style={{ marginTop: 40 }}><b>Selected Value: </b>{value}</div>
    </div>
  );
}

render(<App />, document.getElementById('root'));

测试:slider.spec.js

我发现在测试中断言值的最简单方法是使用aria-valuenow滑块句柄属性,但您可能有另一种方法来测试该值是否在页面上发生了明显变化。

describe('Slider', () => {

  it("Changing slider", () => {
    cy.visit("localhost:3000");

    cy.get('.rc-slider-handle')
      .should('have.attr', 'aria-valuenow', 20000)

    cy.window().then(win => {
      win.app.setValue(35000);
    })

    cy.get('.rc-slider-handle')
      .should('have.attr', 'aria-valuenow', 35000)

  })
})