protractor中的browser.ignoreSynchronization是什么?

67

我经常看到有人建议使用以下代码:

browser.ignoreSynchronization=true;  // or false

但我不明白为什么我们需要它?

3个回答

81
简单的回答是,这使得 Protractor 不会等待 Angular 承诺(例如来自 $http 或 $timeout 的承诺)解决,如果您正在测试 $http 或 $timeout 期间的行为(例如“加载”消息),或者测试非 Angular 站点或页面(例如单独的登录页面),则可能需要这样做。
例如,要测试设置请求期间加载消息的按钮,您可以在获取元素并检查其内容时将其设置为 true。
element(by.css('button[type="submit"]')).click();
browser.ignoreSynchronization = true;
expect(element(by.css('.message')).getText().toBe('Loading...');    
browser.ignoreSynchronization = false;
expect(element(by.css('.message')).getText().toBe('Loaded'); 

更详细的答案是将其设置为true意味着随后对控制流的添加/注入不会再添加browser.waitForAngular。在某些情况下,了解控制流以及何时/如何添加/注入它很重要。例如,如果您正在使用browser.wait测试多阶段过程,则传递给wait的函数会在测试中的其余函数添加到控制流之后被注入到控制流中。

element(by.css('button[type="submit"]')).click();
browser.ignoreSynchronization = true;
expect(element(by.css('.message')).getText().toBe('Stage 1');
browser.wait(function () {
   // This function is added to the control flow after the final
   // browser.ignoreSynchronization = false in the test
   // so we need to set it again here 
   browser.ignoreSynchronization = true;
   return element(by.cssContainingText('.message', 'Stage 2')).isPresent().then(function(isPresent) { 
     // Cleanup so later tests have the default value of false
     browser.ignoreSynchronization = false;
     return !isPresent;
   });
});
expect(element(by.css('.message')).getText().toBe('Stage 2');
browser.ignoreSynchronization = false;
expect(element(by.css('.message')).getText().toBe('Stage 3');

使用标准的webdriver API 直接访问是使用 browser.ignoreSynchronization 的替代方法。

element(by.css('button[type="submit"]')).click();
expect(browser.driver.findElement(by.css('.message')).getText().toBe('Loading...');    
expect(element(by.css('.message')).getText().toBe('Loaded'); 

直接使用驱动程序方法查找元素意味着系统将尝试在等待任何正在进行的$http请求完成之前查找它们,就像设置browser.ignoreSynchronization = true一样。


21

该设置控制Protractor是否应等待页面上的Angular。它没有得到很好的文档支持,但这里是来自代码的文档字符串

/**
   * If true, Protractor will not attempt to synchronize with the page before
   * performing actions. This can be harmful because Protractor will not wait
   * until $timeouts and $http calls have been processed, which can cause
   * tests to become flaky. This should be used only when necessary, such as
   * when a page continuously polls an API using $timeout.
   *
   * @type {boolean}
   */

换句话说,如果你正在针对一个非 Angular 网站进行测试,请将 ignoreSynchronization 设置为 true。作为一个现实世界的例子,请看我在从 Angular 页面打开非 Angular 页面时遇到的其中一个挑战:Non-angular page opened after a click


4

2021答案

browser.ignoreSynchronization已经过时了。确切地说

自从protractor v5.3.0发布以来,这个命令在2018年1月25日就被废弃了

取而代之的是应该使用browser.waitForAngularEnabled()

但它到底是做什么的以及ignoreSynchronization曾经做了什么,它启用了Protractor内置的处理等待Angular应用程序的功能。想象一下,你单击登录按钮,您不需要使用“等待10秒”命令或“等待加载动画消失”等命令,理论上所有这些都应该由Protractor自带处理

但实际上,有太多边缘情况不能依赖此功能,必须禁用此功能,因为它会使脚本挂起。 这就是当await browser.waitForAngularEnabled(false)发挥作用时。 或者await browser.waitForAngularEnabled(true)来重新启用它

阅读如何使用它


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接