在赛普拉斯测试 IonRange

问题描述 投票:0回答:3

有趣的是,这样一个标准组件中的这种标准行为是如此难以测试。

在我的 Ionic React 组件中给出一个 IonRange 元素:

<IonRange
  min={0}
  max={30}
  onIonInput={()=> console.log("changed")}
/>

当我手动测试 IonRange 时,我得到了预期的控制台输出。 然而,当我进行像这样的柏树测试时(几乎是从文档中复制过来的)

cy.get("ion-range")
  .as('range')
  .invoke('val', 10)
  .trigger('change')

我希望在输出中看到日志语句。

实际行为:范围旋钮跳至预期位置,但从未调用

onIonInout
回调。

我还尝试了其他触发器,例如

  .trigger('ion-change')
  .trigger('input')
  .trigger('ion-input')
  .trigger('range-change')
  .trigger('ionChange')
  .trigger('ionInput')

所有这些都会导致相同的行为。

我还尝试使用箭头键来解决问题。 这将是一个非常令人不满意的解决方案,因为它不能推广范围为 0 到 10,000 的情况。我还是尝试了一下:

cy.get("ion-range").type('{rightArrow}') // trows "this is a non-typable element"

范围旋钮跳到中心(奇怪)。

我最终得到的解决方法是:

cy.get("ion-range").click() // clicks in the centre 

(@SuchAnIgnorantThingToDo-UKR 也提到过) 然后我期望值 15。但是由于渲染分辨率的差异(即使使用设置的视口),结果在 15 和 16 之间变化。此外,考虑到我们可能想要断言特定值,这个解决方案非常不令人满意)

我回顾了以下内容:

如果您对这个非常琐碎的日常问题有任何想法,请告诉我。

reactjs testing ionic-framework range cypress
3个回答
3
投票

.click()
命令将更改值并触发事件处理程序,但它不如直接设置值那么精确。

cy.window()
  .its('console')
  .then((console) => {
    cy.spy(console, 'log').as('log')
  })

cy.get('ion-range')
  .click(300,0)

cy.get('@log') 
  .should('have.been.calledWith', 'changed', 31)
  .invoke('getCalls')
  .then((calls) => {
    // open the DevTools to see the dumped table
    console.table(calls)
    expect(calls[0].args).to.deep.eq(['changed', 31]) // not exact, a +1 pixel occurs
  })

来自

<IonRange onIonChange={({ detail })=> console.log("changed", detail.value)}></IonRange>

IonRange 似乎与您引用的两个链接示例具有不同的内部机制。

那些具有

<input>
底层,但 IonRange 没有。相反,它是一个基于模板的 Web 组件,它以自己的特定方式响应事件。


范围旋钮跳到中心(奇怪)

我得到了与

.click()
相同的结果,但没有指定要单击的坐标。我认为这是因为
.type()
内置了
.click()

如果不指定,默认点击位置是元素的中心。


1
投票

@SuchAnIgnorantThingToDo-UKR 已经非常详细地回答了。

我只是想添加如何测试拖动。你可以这样做:

describe('Components', () => {
  it('ion-range', () => {
    cy.visit('https://ionicframework.com/docs/usage/v7/range/basic/demo.html?ionic:mode=ios')

    cy.get('ion-range').as('slider')

    const waitTime = 200

    cy.get('@slider') //
      .trigger('mouseenter')
      .wait(waitTime)
      .trigger('mousedown', 100, 0)
      .wait(waitTime)
      .trigger('mousemove', 150, 1, { force: true })
      .wait(waitTime)
      .trigger('mousemove', 200, 1, { force: true })
      .wait(waitTime)
      .trigger('mousemove', 300, 1, { force: true })
      .wait(waitTime)
      .trigger('mouseup', 300, 1)
  })
})


0
投票

老问题,但您可以使用以下代码触发离子范围的内部机制:

cy.get('@slider').then(($range) => {
    const range = $range[0];

    range.dispatchEvent(new CustomEvent("ionInput", { detail: { value: 0 }, bubbles: true }));
    range.dispatchEvent(new CustomEvent("ionChange", { detail: { value: 0 }, bubbles: true }));
  });

并将值设置为您喜欢的值

© www.soinside.com 2019 - 2024. All rights reserved.