【问题标题】:How to ensure first iteration of a loop is finished before executing second iteration?如何确保在执行第二次迭代之前完成循环的第一次迭代?
【发布时间】:2020-07-02 05:12:56
【问题描述】:
cy.document().then(document => {
  const arra = [...document.querySelectorAll('.instances__action')];

  for (let i = 1; i <= arra.length; i++) {
    let state = document.querySelector(
      `#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody > tr:nth-child(${i}) > td:nth-child(3) > span`
    ).innerText;

    if (state !== 'Finished') {
      document
        .querySelector(
          `#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody > tr:nth-child(${i}) > td:nth-child(7) > div > button.ant-btn.ant-btn-primary.ant-btn-sm`
        )
        .click();
    } else {
      continue;
    }
  }
});

在这里,假设arra.length 是 2。在每次单击迭代按钮时。 我想一次做一个。首先,它应该检查状态是否为finished。 如果状态是not finished,它应该按下按钮并等待状态变为完成。 之后,它应该进入下一个迭代。在我当前的实现中,它在第一次迭代完成之前进入第二次迭代。

【问题讨论】:

    标签: javascript for-loop while-loop automation cypress


    【解决方案1】:

    在将文本设置为Finished 的代码部分,让它调用循环中分配给的Promise 构造函数的resolve 函数。然后,在循环中,构造 Promise 和 await 它。例如:

    let resolveFn = () => undefined;
    
    // ...
    // Run loop:
    (async () => {
      // ...
      for ( // ...
      // ...
        if (state !== 'Finished') {
          const prom = new Promise(resolve => resolveFn = resolve);
          document.querySelector(...).click();
          await prom;
        }
    }
    })();
    
    // ...
    
    function clickHandler() {
      // ...
      // At the point where you assign "Finished", call the resolveFn:
      span.textContent = 'Finished';
      resolveFn();
    }
    

    如果您无法控制分配 Finished 文本的代码,则观察文本更改的另一种可能性是使用 MutationObserver,例如:

    if (state !== 'Finished') {
      document.querySelector(...);.click();
      await new Promise((resolve) => {
        new MutationObserver((_, observer) => {
          if (span.textContent === 'Finished') {
            observer.disconnect();
            resolve();
          }
        })
          .observe(span, { childList: true });
      });
    }
    

    【讨论】:

    • 我试过你的第二个 sn-p。但它只执行第一次迭代,没有别的。实际上它是一个柏树测试用例。主要目标是依次单击开始按钮(我映射到数组中)(但确保单击按钮后第一个变为“完成”状态)gist.github.com/ashiqdev/93213ce26494fdbab8478dd722bc30ea
    • 您没有完全复制代码。使用if (span.textContent === 'Finished') {查看答案中的代码,但您有if (span === 'Finished') {,这永远不会是真的,因为span是一个永远不会重新分配的HTMLElement,而不是一个字符串
    • 好吧,同样的事情也会发生。有两个requested 状态。第一个运行正常。比我在 cypress Error: Cypress command timeout of '6000ms' exceeded. (and Mocha's done() called multiple times) 编辑代码中得到这个错误:gist.github.com/ashiqdev/93213ce26494fdbab8478dd722bc30ea
    • 听起来像if (span.innerText === 'Finished') { 永远不会满足 - 您应该查看分配范围的内容的点。或者如果 span 完全从 DOM 中删除,您需要重新选择它。
    • 顺便说一句,您可能应该never ever use innerText - 改用标准(更可预测,更快)textContent
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多