使用 cypress 定期检索和比较元素的样式属性

Posted

技术标签:

【中文标题】使用 cypress 定期检索和比较元素的样式属性【英文标题】:Retrieve and compare the style attribute of an element periodically using using cypress 【发布时间】:2021-04-23 12:30:57 【问题描述】:

我有一个跨越时间刻度的时间指示器,指示器的样式属性值每 x 毫秒不断变化,我需要获取、存储和比较之前捕获的值大于最新值。

初始值:

最新值:

逻辑是,从一个点(左 10)开始,它每秒向左移动(左 -0、-1、-2、-3 ...)

我尝试了几种方法,其中一种方法是在同一个 'cy.then' 中捕获,但在这种情况下,元素不会具有最近的值。到目前为止,我试过这个。它获取值并在正则表达式的帮助下,我得到了一个“可比较”的值,但我如何存储/比较这些值?此外,如果我们需要比较两个以上的值,最好的方法是什么?

const BTN_CONTROL_TIMEINDICATOR = '#currentTimeIndicator'
  static verifyTimeLapse() 
        //wip
        var initialVal, nextVal
        initialVal = this.getAnyValueOfAnElement(BTN_CONTROL_TIMEINDICATOR)
        cy.wait(500)
        nextVal = this.getAnyValueOfAnElement(BTN_CONTROL_TIMEINDICATOR)
        cy.log(initialVal > nextVal) 
    

  static getAnyValueOfAnElement(element) 
        //wip
        cy.get(element)
           .then(($ele) => 
               const val=$ele.attr('style').replace(/[^\d.-]/g, '')
               cy.log(val)
               // return does not work 
            )
    

cy.log:

【问题讨论】:

【参考方案1】:

页面对象不能很好地与赛普拉斯命令队列一起使用,这是您可以使用自定义命令执行的操作。

/* Get the numeric value of CSS left in px */
Cypress.Commands.add('getTimescaleValue', () => 
  cy.get('#currentTimeIndicator')
    .then($el => +$el[0].style.left.replace('px',''))
)

/* Get a sequence of time scale values */
Cypress.Commands.add('getTimescaleValues', (numValues, waitBetween) => 
  const values = [];
  Cypress._.times(numValues, () =>           // repeat inner commands n times
    cy.getTimescaleValue()
      .then(value => values.push(value))      // save value
      .wait(waitBetween)
  )
  return cy.wrap(values);
)

/* Assert a sequence of values are in descending order */
Cypress.Commands.add('valuesAreDescending',  prevSubject: true , (values) => 
  values.reduce((prev, current) => 
    if (prev)                        // skip first (no prev to compare)
      expect(prev).to.be.gt(current)  // assert pairs of values 
    
    return current
  );
)


it('check the timeline', () => 
  cy.getTimescaleValues( numValues: 10, waitBetween: 100 )
    .valuesAreDescending()
)

日志

assert expected 63 to be above 58
assert expected 58 to be above 48
assert expected 48 to be above 43
assert expected 43 to be above 33
assert expected 33 to be above 23
assert expected 23 to be above 18
assert expected 18 to be above 13
assert expected 13 to be above 3
assert expected 3 to be above -2

经过测试

<div id="currentTimeIndicator" style="left:63px">Target</div>
<script>
  const timer = setInterval(() => 
    const div = document.querySelector('#currentTimeIndicator')
    const left = +div.style.left.replace('px', '');
    if (left < 0) 
      clearInterval(timer)
      return
    
    const next = (left - 5) + 'px';
    div.style.left = next;
  , 100)
</script>

如果您的应用使用setInterval() 进行计时,您应该能够使用cy.clock()cy.tick() 而不是.wait(waitBetween) 以获得更精确的采样和更快的测试执行。

【讨论】:

它就像一个魅力,感谢您用 cmets 解释它。【参考方案2】:

我不知道初始值是从哪里来的。但在它改变之前,也许是在页面加载时,也许是作为点击的第一份工作等等,你可以做这样的事情:

let item = document.querySelector("#currentTimeIndicator");
item.dataset.left = parseFloat(item.style.left);

console.log(item);
&lt;div id="currentTimeIndicator" style="left:-20px"&gt;&lt;/div&gt;

【讨论】:

是的,它显示 Uncaught TypeError: Cannot read property 'dataset' of null at :2:6 因此,当您调用该代码时,没有可供选择的项目。应该是时间问题。

以上是关于使用 cypress 定期检索和比较元素的样式属性的主要内容,如果未能解决你的问题,请参考以下文章

Cypress学习4-table表格元素(别名使用Aliasing)

Cypress学习4-table表格元素(别名使用Aliasing)

如何将 CDN 样式表链接导入 Cypress 组件测试运行程序

如何使用 Cypress.io 检查元素是不是存在

Cypress 组件测试、ReactJS 和 TailwindCSS

赛普拉斯:如何将文本值/文本元素与 .each() 进行比较