【问题标题】:detox: tap button only if exists排毒:仅在存在时点击按钮
【发布时间】:2018-03-14 23:28:27
【问题描述】:

在我的测试中,我想模拟点击“取消升级”按钮,只有当它显示时:

it('should be in home menu', async () => {
  await waitFor(element(by.id('cancelUpgrade')))
    .toBeVisible()
    .withTimeout(2000);
  await element(by.id('cancelUpgrade')).tap();
});

它返回预期的错误Error: Cannot find UI element.

https://github.com/wix/detox

【问题讨论】:

标签: javascript testing automated-tests detox


【解决方案1】:

你可以将 tap 包裹在 try/catch 块中:

it('should be in home menu', async () => {
  await waitFor(element(by.id('cancelUpgrade')))
    .toBeVisible()
    .withTimeout(2000);
  try {
    await element(by.id('cancelUpgrade')).tap();
  } catch (e) {}
  // continue your tests
});

不是最好的方法,但我认为这是目前在排毒中可能的方法。

【讨论】:

  • 您能否解释一下您的做法与 OP 有何不同以及您的示例为何按预期工作?
  • 只是为了提供有关此解决方案为何有效的更多信息。来自 detox 文档:“注意:waitFor 在超时时不会抛出,而是会继续到下一行。”因此,如果按钮不可用,.tap() 将抛出,并且在这种情况下它会被 catch 默默吞噬。
  • 另外,FWIW,您可以使用try/catch“技巧”在catch 块中放置备用代码路径。
【解决方案2】:

我怀疑我们可以将此模式与toExist 一起使用

it('should be in home menu', async () => {
  await waitFor(element(by.id('cancelUpgrade')))
    .toBeVisible()
    .withTimeout(2000);
  try {
    await expect(element(by.id('cancelUpgrade'))).toExist();
  } catch (e) {}
  // continue your tests
});

如果你不需要等待:

it('should be in home menu', async () => {
  try {
    await expect(element(by.id('cancelUpgrade'))).toExist();
  } catch (e) {}
  // continue your tests
});

【讨论】:

    【解决方案3】:

    这可能不是最好的解决方案,但我创建了一个名为 waitForElement 的 util 函数,它起作用了。

    export const sleep = async (milliseconds) =>
       new Promise((resolve) => setTimeout(resolve, milliseconds));
    
    /**
     * Wait for element to be available in the UI hierarchy
     * @param {Detox.Element} appElement detox element
     * @param {Number} timeout Timeout in milliseconds
     * @param {Number} maxRetries
     * @returns {Object}
     * {
     *   found: <Boolean>, // Determines if element was found
     *   retryCount: <Number> // Number of tries to find the element
     * }
     */
    export const waitForElement = async (appElement, timeout, maxRetries = 5) => {
      let found = false;
      let retryCount = 0;
    
      while (!found && retryCount < maxRetries) {
        try {
          await expect(appElement).toExist();
          found = true;
        } catch (err) {
          retryCount += 1;
          if (retryCount < maxRetries) {
            await sleep(timeout);
          } else {
            throw err;
          }
        }
      }
    
      return {found, retryCount};
    };
    

    使用示例:

    it('should be in home menu', async () => {
        const cancelUpgradeElement = element(by.id('cancelUpgrade'));
        await waitForElement(cancelUpgradeElement, 2000);
        await cancelUpgradeElement.tap();
    });
    

    【讨论】:

      猜你喜欢
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 2012-06-21
      • 2018-05-03
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多