量角器使用browser.wait的正确方法来控制测试流程

时间:2018-07-23 16:11:26

标签: protractor

我为browser.wait编写了一些功能。我的问题是,当我运行测试时,由于量角器运行得太快,它们不一致地通过了测试。为了解决这个问题,我使用了browser.sleep。这可行,但是效率不高。例如,如果我的连接速度较慢,则这些browser.sleep语句可能变得不可靠。所以我已经开始使用browser.wait。这是我使用的等待功能的示例。

EC = Expected Conditions;
myForm = element(by.id('myForm');
button1 = element(by.id('btn1');
waitForBtn = this.EC.elementToBeClickable(button1)
formIsVisible = this.EC.visibilityOf(myForm)

//Test
it(should click the button and bring up the form), () => {
    browser.wait(page.waitForBtn, 3000);
    page.button1.click()
    browser.wait(page.formIsVisible, 3000);
    expect(page.getMyForm().isDisplayed).toBeTruthy(); 

该测试可以隔离使用,但是当与其他测试结合使用时,有时测试会失败并返回错误"element" is not clickable at point...。即使具有这些等待功能,我也会收到此错误。它似乎总是用于单击元素。

我的问题是:运行多个测试时,量角器等待的最佳方法是什么,以使量角器不会太快地执行测试并错过元素?。谢谢。 编辑: 这是解决方案。

用于单击元素的助手功能。

 async function sendClick(el: ElementFinder): Promise<void> {
    try {

      let result = await forCondition(function() { return el.isDisplayed() });
      if(!result || !await el.isEnabled()) {
        throw new Error('element disabled');
      }

      await browser.executeScript('arguments[0].click();', el.getWebElement());
    } catch(error) {
      console.warn('element:', el.locator().toString(), 'is not clickable', error.message);
    }
  }

export async function forCondition(condition: () => any | PromiseLike<boolean>, timeout = 20000): Promise<boolean> {
try {
  return await browser.wait(condition, timeout);
} catch (err) {
  console.log('Condition: false');
  return false;
}

}

1 个答案:

答案 0 :(得分:1)

我不能告诉你最好的方法,但这是一种方法:)

通常,当元素与另一个元素重叠时,或者如果元素尚未完成渲染,就会引起类似element" is not clickable at point...的错误。

1)为防止出现element is not clickable错误,应使用javascript进行单击。缺点之一是元素总是会被点击。意味着您必须手动检查元素是否可单击,并且仅应单击。 “适当的”点击功能可能如下所示:

async function sendClick(el: ElementFinder): Promise<void> {
  try {

    // forCondition() is a custom function and listed below..
    let result = await forCondition(function() { return el.isDisplayed() });
    if(!result || !await el.isEnabled()) {
      throw new Error('element disabled');
    }

    // click via javascript
    await browser.executeScript('arguments[0].click();', el.getWebElement());
  } catch(error) {
    console.warn('element:', el.locator().toString(), 'is not clickable', error.message);
  }
}

以上功能等待元素显示,如果启用,请单击它。

以下是辅助函数:

forCondition(),等待条件满足。您无法向forCondition()添加更多逻辑以确保页面已加载(例如,直到微调框消失或类似的情况。)

export async function forCondition(condition: () => boolean | PromiseLike<boolean>, timeout = 20000): Promise<boolean> {
  try {
    // add function which waits until page is loaded here..
    return await browser.wait(condition, timeout);
  } catch (err) {
    logger.silly('Condition: false');
    return false;
  }
}

在测试中,它看起来如下:

it('should click element', async function() {
  let button = element(by.id('myButton');

  // it's waited until button appears and clicks it if possible.
  await sendClick(button);
});

如果您始终使用这些帮助器功能,则可以轻松添加检查以等待页面加载或其他自定义逻辑。

让我知道是否有任何不清楚的地方。