排毒:仅在存在时点击按钮

detox: tap button only if exists

在我的测试中,我想模拟点击 "cancelUpgrade" 按钮,只有当它显示时:

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

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

https://github.com/wix/detox

您可以在 try/catch 块中包装 tap:

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
});

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

我怀疑我们可以将此模式与 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
});

它可能不是最好的解决方案,但我创建了一个名为 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();
});