量角器:如何等待findElements?

时间:2018-05-03 18:18:06

标签: angular protractor

我有一个搜索字段,当用户点击输入时,它有一个带有一堆复选框的表。我需要等待加载结果,然后单击表格第一行的复选框。

这分为2个测试用例,第一个执行搜索,第二个单击结果第一行中的复选框,执行其他操作。

 // Test #2      
 it('should perform the Search', () => {
    po.searchAutocomplete.sendKeys('\n');
  });

 // Test #3
  it('3  : should Activate and Inactivate a Program', () => {
    const r = browser.driver.findElements(by.tagName('p-checkbox'));

    browser.driver.wait(EC.presenceOf(r[0]));

    r[0].click();

    browser.sleep(2000).then(() => {
    });

    r[0].click();  
  });

  // Test #4
  it('4  : should navigate to Create New', () => {
    po.createNewButton.click();
  });

所以,这里存在同步问题 - 我的测试#2成功运行但是测试#3立即开始在这里运行。如果搜索结果太慢,那么我得到一个错误,该复选框不存在,如果它及时返回它没关系。此外,有时第二次click()导致对象未附加到当前页面,因为测试#4中的“新建”导航到另一页。

看起来r [0] .clicks的承诺在页面导航到另一个视图后返回po.createNewButton.click()导致对象没有附加到当前页面错误。

我需要同步所有这些操作。我放入了browser.wait,但这不起作用,它只是被忽略了。

我该如何解决这个问题?

编辑 - 感谢以下建议。这是我改变并使其发挥作用的原因:)

在我的应用程序中有一个时钟计时器在我的标题中使用Observable.interval,此外我还有一个计时器,它正在ping服务器以获得固定间隔的一些数据。因为它们总是在运行并且永远不会完成它会导致Protractor中的各种超时与element.all语法,这就是为什么我切换到browser.driver.findElement语法,但由于它的异步性质(由海报确定)下面 - 谢谢!)使代码变得困难。

我将计时器包装在以下代码中:

this.ngZone.runOutsideAngular(() => {   // Required to prevent interference with Protractor
  this.updateTimer = Observable.interval(UPDATE_INTERVAL).publish();
  this.updateTimer.subscribe(v => {
    this.doSomething();
  });
});

现在,我可以使用element.all而不会超时!

1 个答案:

答案 0 :(得分:4)

这种情况正在发生,因为您正在使用driver commands来获取元素。驱动程序命令不等待角度异步任务完成。例如,HTTP请求,您的案例中的数据加载。 (默认情况下,量角器将等待角度异步任务结束,然后再继续执行队列中的下一个承诺。)

如果您的应用程序中始终存在异步活动,则使用driver命令才有意义。例如timer

而不是

browser.driver.findElements(by.tagName('p-checkbox'));

使用:

element.all(by.tagName('p-checkbox'));

现在,每当你使用browser.wait()时,你必须等待条件变得真实,并在等待结束时放入其余的代码:

browser.wait(EC.presenceOf(r[0])).then(() => {
   ...// wait is over. Rest of my code here.
})

建议:请将测试itsfits相互独立。如果第一个it失败怎么办?那么后续的it也会失败?

  

编辑:测试时间超时的原因

在你的评论中,你说你禁用了计时器?你确定没有其他计时器在运行吗?量角器可能会在两种情况下显示此类消息:

  1. 有'在您的应用程序中运行的计时器和量角器等待它完成但超时。
  2. 您已添加等待使用浏览器等待检查presenseOf and element or isElement Clickable, etc,但该元素从未出现在您已添加等待的页面上。
  3. 如果计时器正在运行(哈丁没有正确阅读您的评论。如果以上列表中的点号2对您不对,则下面是一个解决方案。)

    如果你正在超时,那么你的应用程序中肯定有一些计时器在后台运行。由于各种原因,我们通常在应用程序中使用它,一个常见原因是在应用程序中某些特定的不活动时间间隔后从应用程序中注销用户。

    既然你已经超时了,那么你有两种选择。

    1. 使用驱动程序命令。

    2. 禁用角度等待,然后使用量角器命令。

      browser.waitForAngularEnabled(false/true).then(() => {.. rest of codes with specific checking of element's existance, their clickability, etc and then perform the actual opration. })

    3. 两者都同样麻烦,因为现在你必须等待一切。你不能使用protractors默认等待角度finish page loads, HTTP requests, etc,因为如果你使用它,那么你将永远等待直到超时。

      我在这种情况下所做的是:

      为应用程序添加一种方法,以便为特定测试用户禁用运行计时器。我们使用特定的测试用户进行量角器测试用例,当用户登录时,该用户可以选择禁用计时器。 (An extra dom element which when clicked, removes the timer)。所以当用户点击登录按钮时,我禁用angular wait,(我的应用程序中的计时器仅在登录后启动)然后我在应用程序中进行特定等待,直到我看到是否存在额外的DOM元素和isClickable,如果为true,那么我点击它。点击后,我重新启用角度等待。在此之后,我可以利用量角器自动等待元素出现。希望这会有所帮助。