上下文:我在第1页中有一个具有innerText的元素,在第2页中有另一个具有innerText的元素。而且我需要在第3页中比较这两个值。因此,我需要找到一种将这些值全局保存到变量中的方法,以便它们可以稍后使用。

我尝试过的事情:

试用1:无效,因为page1value范围仅限于cy.get()

  cy.get('#selector').invoke('text').then(text => {
      const page1value = text
  })

试用版2:不能像我每次尝试在外部打印该值时一样工作,它是未定义的或用于初始化它的值。
it('TC Name', () => {

    let page1value,
        cy.get('#selector').invoke('text').then(text => {
            page1value = text
        })

    cy.log(page1value) //comes as undefined

})

试用3:使用.as()及其未定义的名称。
let page1value;
cy.get('#selector').invoke('text').as('page1value');
cy.log(page1value) //comes as undefined

如果有人能告诉我我做错了那太好了。

最佳答案

Cypress 命令被推入(排队)到队列中(称为命令队列---基本上是一个数组),然后串行执行(一个接一个),然后异步执行。

尽管您的cy.log()也将异步执行,但在上一条命令之后,将命令传递到队列时,您传递给它的值(page1value)会被同步传递/求值(在回调传递时进行评估)在测试开始时将it()称为-)。

这只是常规的JavaScript行为,与 Cypress 无关。所有命令cy.*只是cy对象上的方法(函数),它们会立即被调用。没有立即被调用(执行)的是每个命令执行的逻辑(例如,在DOM中查询您提供给cy.get()的选择器,在调用cy.log('string')时登录到命令日志等)。

因此,在您的第二个示例中:

  • 您声明page1value
  • 然后,您立即将命令cy.get()cy.invokecy.then()放入队列。
  • 然后,您还立即将cy.log放入队列,并向其传递page1value(目前仍为undefined)。
  • 将所有命令放入队列后,它们从上到下开始执行。当cy.then命令轮流执行时,分配了page1value变量,但在其余测试中不再使用(读取)该变量(回想一下,您在上一测试中将其传递给cy.log命令时已经读取了该变量)步)。

  • 因此,您要做的是:
    cy.get('#selector').invoke('text').then(text => {
      cy.log(text);
    });
    

    在第三个示例中,如果您对某些东西使用别名,则需要使用另一个命令来访问该值(请记住,所有内容都是异步的,因此您无法像在执行同步操作那样访问异步设置的值)。这种情况cy.get('@aliasName'):
    cy.get('#selector').invoke('text').as('page1value');
    cy.get('@page1value').then( value => {
      cy.log(value);
    });
    

    请注意,为简单起见,以上说明略微不准确且不详尽(幕后发生了更多事情)。但是,作为工作原理的介绍,他们应该这样做。

    无论如何,您绝对应该阅读Introduction to Cypress

    您也可以看看我的较早答案,这些答案涉及相关概念:
  • How to use a variable as a parameter in an API call in Cypress
  • In Cypress when to use Custom Command vs Task?
  • 09-10 00:34
    查看更多