Cypress - 从函数设置全局变量

use*_*127 7 javascript asynchronous cypress

我有以下流程:

1)在一页上我得到一个字段的值:

 var myID;
 cy.get('#MYID').
        then(($txt) => {
            myID=  $txt.text();
        })
       .should('not.equal', null); 
Run Code Online (Sandbox Code Playgroud)

2)然后我导航到一个新页面并尝试检查这个新页面是否包含此 id:

cy.get('#myTable').find('td').contains(myID);
Run Code Online (Sandbox Code Playgroud)

它说 myID 未定义。我知道第一个函数是异步的,并且阅读文档它说我可以使用别名。别名的问题是它需要位于 beforeEach() 函数中,这不会成为我无法在这个测试用例中使用的长篇故事。我尝试使用 async/await 但它似乎对我不起作用,因为它仍然未定义。

Ric*_*sen 5

这里的基本问题是 Cypress 命令与创建它们的测试代码异步运行。如果将控制台日志放入代码中,您可以看到这一点,

var myID;
cy.get('#MYID')
  .then(($txt) => {
    myID=  $txt.text();
    console.log('1', myID);
  })
 .should('not.equal', null); 

console.log('2', myID);
Run Code Online (Sandbox Code Playgroud)

这打印出来

2 undefined
1 myText
Run Code Online (Sandbox Code Playgroud)

您可以使用别名来克服这个问题,并在命令链中传递一个值。

请参阅文档的这一部分,其中显示了您在“请勿使用此示例”中使用的类似代码模式。

但是别名会在测试之间被清除,因此您应该设置一个beforeEach()来获取每个测试所需 ID 的新副本。

获取文本值的方式还有另一个问题。

如果没有 return 语句,该.then()命令会将其收到的任何主题传递给下一个命令。参见当时-产量

此外,回调函数中最后一个 Cypress 命令的结果将作为新的 subject 产生,如果没有 return ,则流入下一个命令。

因此,.should('not.equal', null)测试的是元素不为空,而不是文本不为空。

更好的方法是.invoke('text')which 相当于$txt.text()并产生 的文本值.should()

.should('not.equal', null)不会测试内容是否存在,因为空元素会从element.text(). .should('not.equal', '')代替使用。

通过别名保存

2 undefined
1 myText
Run Code Online (Sandbox Code Playgroud)

通过对变量的设置进行排队来保存

如果访问第 1 页很耗时,则别名模式可能并不理想。

在这种情况下,您可以通过自定义命令保存变量。不同之处在于,您在其中的代码被.then()移动到排队的命令中,因此不会发生异步问题。

describe('grabbing ID for use in multiple tests', () => {

  beforeEach(() => {
    cy.visit('my-page-1.html')
    cy.get('#MYID')
      .invoke('text')
      .as('mySavedID')
  })

  it('ID should not be null', () => {

    cy.get('@mySavedID')
      .should('not.equal', '')

  })

  it('ID should be found in table', () => {

    cy.visit('app/navigate-to-new-page-2.html');
    cy.get('@mySavedID').then(myID => {
      cy.get('#myTable').find('td').contains(myID);
    })

  })
})
Run Code Online (Sandbox Code Playgroud)

注意
如果两个页面位于同一域(例如 SPA 的两个页面),则上述内容有效。否则,当遇到新域时,测试运行程序会自行重置,并且所有 javascript 变量都会丢失。