量角器中的 browser.ignoreSynchronization 是什么?

What is browser.ignoreSynchronization in protractor?

我在人们建议使用的地方看到了很多次:

browser.ignoreSynchronization=true;  // or false

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

此设置控制量角器是否应在页面上等待 angular。它没有正确记录,但这里是 documentation string from the code:

/**
   * 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 页面时遇到的挑战之一:.

简单的答案是它让量角器不等待 Angular promises,例如来自 $http$timeout 的那些,如果你是在 $http$timeout 期间测试行为(例如 "loading" 消息),或测试非 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 意味着随后的 additions/injections 到控制流也不会添加 browser.waitForAngular。在某些情况下,了解控制流和 when/how 事情 added/injected 很重要。例如,如果您使用 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');

使用 browser.ignoreSynchronization 的替代方法是直接访问标准网络驱动程序 API

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.

2021 年答案

browser.ignoreSynchronization 这些天什么都不是。字面意思

此命令已于 2018 年 1 月 25 日量角器 v5.3.0 发布时弃用

应该使用 browser.waitForAngularEnabled()

但是它所做的和 ignoreSynchronization 过去所做的一样,它启用 Protractor 的内置处理以等待 angular 应用程序。想象一下,您单击登录按钮,并且不需要使用 'sleep for 10 seconds' 命令或 'wait until loading animation is gone' 等。理论上所有这些都应该由开箱即用的量角器处理

但在现实中,当你不能依赖这个时,有太多的边缘情况,不得不禁用这个特性,因为它会使脚本挂起。这就是 await browser.waitForAngularEnabled(false) 发挥作用的时候。或者 await browser.waitForAngularEnabled(true) 重新启用它

阅读how it can be used