如何使用 cypress 将多个元素的值存储在数组列表中的一个根元素下

how to store multiple elements' value under one root element in list of array with cypress

对于结构如下的结果

<div class="results">
  <div class="result">
    <div class="name">x</div>
    <div class="price">99</div>
  </div>
<div class="result">
    <div class="name">y</div>
    <div class="price">88</div>
  </div>
</div>

我想像这样存储在数组列表中

var resultList = [{"name":"x","amount":"99"}, {"name":"y","amount":"88"}]

在 cypress 中,我在 cypress 中有以下代码,但它打印出 null,我不确定如何解决它?

let listOfResults = [];
let singleResult = {};
  cy.get('[class="results"]').each((resultItem) => {
    singleResult = {};

    //Retrive name
    cy.wrap(resultItem)
      .find('div[class$="name"]')
      .invoke("text")
      .then((val) => {
        cy.log("singleResult value for Title:" + val);
        singleResult["title"] = val;
        cy.log("singleResult::" + JSON.stringify(singleResult));//prints correctly
      });

   
    //Retrive price
    cy.wrap(resultItem)
      .find('div[class$="amount"]')
      .invoke("text")
      .then((val) => {
        cy.log("singleResult value for Title:" + val);
        singleResult["amount"] = val;
        cy.log("singleResult::" + JSON.stringify(singleResult));  //prints correctly          
      });
 });

 listOfResults.push(JSON.stringify(singleResult)); //singleResult became blank

 cy.log("list:" + JSON.stringify(listOfResults));

您必须在 .then() 中将提取器之后的代码包装起来,因为 Cypress 命令是异步的。

let listOfResults = [];
let singleResult = {};
cy.get('[class="results"]')
  .each((resultItem) => {
    ...
  })
  .then(() => {
    listOfResults.push(JSON.stringify(singleResult)); 
    cy.log("list:" + JSON.stringify(listOfResults));
  })

当您调用 cy.log() 时,它总是在 测试运行之前采用它的值 ,除非它在 ​​.then()。所以 cy.log("list:" + JSON.stringify(listOfResults)) 看到空 listOfResults.

还有三件事:

迭代class="结果"

cy.get('[class="results"]') 应该是 cy.get('[class="result"]') 因为 class="results" 是整体 div,但是你想迭代 class="result" div(假设你的削减 HTML 是准确的)

推入.each()

listOfResults.push(JSON.stringify(singleResult)) 应该在 .each() 内,因为您要推送每次迭代的 singleResult。但是您还需要 .then() 来执行此操作,以确保在填充 singleResult 后推送 (与上面相同的问题,异步命令).

不要字符串化

您不需要对日志进行字符串化,只需添加一个逗号即可。这样你就可以保留 easier/better 向下测试使用的对象结构。

const listOfResults = [];
// let singleResult = {};  // don't need this here

cy.get('[class="results"]').each((resultItem) => {

  const singleResult = {};   // declare it fresh each iteration

  //Retrive name
  cy.wrap(resultItem)
    .find('div[class$="name"]')   // also 'div.name'
    .invoke("text")
    .then((val) => {
      cy.log("singleResult value for Title:" + val);
      singleResult["title"] = val;
      cy.log("singleResult::", singleResult);
    });

  //Retrive price
  cy.wrap(resultItem)
    .find('div[class$="amount"]')  // also 'div.amount'
    .invoke("text")
    .then((val) => {
      cy.log("singleResult value for Title:" + val);
      singleResult["amount"] = val;         
      cy.log("singleResult::", singleResult);
    });

  // Now push to list
  cy.then(() => {
    listOfResults.push(singleResult)
  })
})
.then(() => {
  cy.log("list:", listOfResults);
})

或使用别名

const listOfResults = [];
cy.get('[class="result"]').each((resultItem) => {
  ...
})
.then(() => {
  cy.wrap(listOfResults').as('listOfResults')  // save for later in the test
})

// later on  
cy.get('@listOfResults')
  .then(listOfResults => {
    cy.log("list:", listOfResults) // logs the value of parameter
                                   // not the outer listOfResults
  })

您也可以为此使用写入文件。基本上,您在 fixtures 文件下创建一个空的 JSON,然后创建您想要的 JSON 的结构。 {flag: 'a+'} 将在文件末尾附加数据而不是替换内容。

cy.writeFile('cypress/fixtures/example.json', '') //Remove everything from the previous iteration
cy.writeFile('cypress/fixtures/example.json', '[') //Start Array
cy.get('[class="results"]').each((resultItem) => {
  //Retrive name
  cy.wrap(resultItem)
    .find('div[class$="name"]')
    .invoke('text')
    .then((val) => {
      cy.log('singleResult value for Title:' + val)
      cy.writeFile('cypress/fixtures/example.json', '{"name":', {flag: 'a+'})
      cy.writeFile('cypress/fixtures/example.json', `${val}`, {flag: 'a+'})
      cy.writeFile('cypress/fixtures/example.json', ',', {flag: 'a+'})
    })

  //Retrive price
  cy.wrap(resultItem)
    .find('div[class$="amount"]')
    .invoke('text')
    .then((price) => {
      cy.log('singleResult value for Title:' + price)
      cy.writeFile('cypress/fixtures/example.json', '"amount":', {flag: 'a+'})
      cy.writeFile('cypress/fixtures/example.json', `${price}`, {flag: 'a+'})
      cy.writeFile('cypress/fixtures/example.json', '},', {flag: 'a+'})
    })
})
cy.writeFile('cypress/fixtures/example.json', '\b', {flag: 'a+'}) //Remove last comma 
cy.writeFile('cypress/fixtures/example.json', ']', {flag: 'a+'}) //End Array

只是为了阐明如何将 JSON 值写入文件,因为我无法在评论中正确传达。

cy.writeFile('cypress/fixtures/example.json', `{ "name": "${val}" }`, {flag: 'a+'})
...
cy.writeFile('cypress/fixtures/example.json', `{ "amount": "${price}" }`, {flag: 'a+'})

没有引号,文件中的json无效,无法读取。

还有一个问题,数组最后的逗号有问题。如果我能弄清楚如何避免该问题,我会 post 更多吗?