Javascript 调试量角器以解决角度同步问题的规范方法

Javascript 调试量角器以解决角度同步问题的规范方法,javascript,angularjs,selenium,protractor,Javascript,Angularjs,Selenium,Protractor,问题描述: 最近,在量角器端到端测试中打开应用程序中的一个页面时,我们遇到了一个臭名昭著的错误: 失败:等待异步角度任务在50秒后完成时超时。这可能是因为当前页面不是角度应用程序 这发生在浏览器上。get(“/some/page/”调用我们的一个测试: describe("Test", function () { beforeEach(function () { browser.get("/some/page/"); }); it("should tes

问题描述:

最近,在量角器端到端测试中打开应用程序中的一个页面时,我们遇到了一个臭名昭著的错误:

失败:等待异步角度任务在50秒后完成时超时。这可能是因为当前页面不是角度应用程序

这发生在
浏览器上。get(“/some/page/”调用我们的一个测试:

describe("Test", function () {
    beforeEach(function () {
        browser.get("/some/page/");
    });

    it("should test something", function () {
        // ...
    });
)};
而且,我们的案例中奇怪的是,在Angular web应用程序中,错误没有被抛出到任何其他页面上——量角器与Angular同步没有任何问题<代码>ng应用程序
位置方面的内容在所有页面上都是相同的-
ng应用程序
在根
html
标记上定义:

<html class="ng-scope" lang="en-us" ng-app="myApp" ng-strict-di="">

行为是一致的-每次使用
browser.get()
导航到此页面时,都会出现此错误。每当我们导航到应用程序中的任何其他页面时,同步都会起作用

请注意,当然,我们可以关闭此页面的同步,并将其视为非角度,但这只能被视为一种解决方法

问题:

还有什么会导致量角器角度同步失败?我们应该检查什么

一般来说,在量角器中调试同步问题的推荐方法是什么


使用当前最新的量角器5.5.1,Angular 1.5.6。

好的,所以这个问题引起了我的兴趣,所以我想出了一个关于如何确定量角器正在等待什么的编程解决方案:

var _injector = angular.element(document).injector();
var _$browser = _injector.get('$browser');
var _$http = _injector.get('$http');
var pendingTimeout = true;

//this is actually method that protractor is using while waiting to sync
//if callback is called immediately that means there are no $timeout or $http calls
_$browser.notifyWhenNoOutstandingRequests(function callback () {
  pendingTimeout = false
});

setTimeout(function () {
  //this is to differentiate between $http and timeouts from the "notifyWhenNoOutstandingRequests" method
  if (_$http.pendingRequests.length) {
    console.log('Outstanding $http requests', _$http.pendingRequests.length)
  } else if (pendingTimeout) {
    console.log('Outstanding timeout')
  } else {
    console.log('All fine in Angular, it has to be something else')
  }
}, 100)

在plunker中,您可以尝试超时和$http调用,我的延迟端点将在解析调用之前等待10秒,希望这将对您有所帮助

我同意@maurycy的观点,即问题与$http/$timeout有关。简单的修复方法通常是将$timeout替换为$interval,如下所述:

建议:

合并这些正常默认值:
所有脚本时间:60000,//1分钟
茉莉花:{
defaultTimeoutInterval:300000
//5分钟。允许在整个同步超时期间执行5条命令。
}

如果您想找到$http/$timeout的罪魁祸首,我将使用角度装饰器来应用这些服务的自定义逻辑。这也是模拟angular服务访问第三方服务的好方法。


我想有同步问题<代码>https://github.com/angular/protractor/blob/master/docs/timeouts.md#how-禁用等待角度调整。他们告诉我们的解决方案是关闭同步,或者可能使用
driver.browser.get()
而不是
browser.get()
@KishanPatel谢谢,但正如我在问题中提到的,我理解我们可以关闭同步,并将页面视为非角度-这是一种解决方法,它可以工作,但我们正在试图找出为什么同步不适用于此特定页面以及调试此类问题的一般指导原则。您的错误清楚地表明,它可以同步,因为,出现这种情况有两个原因
$http
$timeout
-量角器将等待这两个服务完成。如果它是由
$timeout
引起的,那么您应该简单地将其替换为
$interval
,至于
$http
,没有解决方法,除非您想编写一个XHR服务并使用它而不是
$http
@maurycy对了,很好的一点-我们以前听说过
$timeout
问题(请不要回忆起与
$http
相关的问题)。但是,我如何确定问题的确切原因?如何通过调试来检测同步失败的原因?谢谢。
//DISCLOSURE: Unlinted & Untested.
beforeAll(() => {
  browser.addMockModule('culpritMock', () => {
    angular.module('culpritMock', [])
      .config(['$httpProvider',
        $httpProvider => $httpProvider.interceptors.push('httpCounterInterceptor')
      ])
      .factory('httpCounterInterceptor', ['$q', '$window', ($q, $window) => {
        if ($window.httpCounterInterceptor == null) {
          $window.httpCounterInterceptor = {};
        }
        return {
          request: config => {
            $window.httpCounterInterceptor[config.url] = 'started';
            return config;
          },
          response: response => {
            $window.httpCounterInterceptor[response.config.url] = 'completed';
            return response;
          },
          responseError: rejection => {
            $window.httpCounterInterceptor[rejection.config.url] = 'error';
            return $q.reject(rejection);
          }
        };
      }])
      .decorator('$timeout', ['$delegate', $delegate => {
        const originalTimeout = $delegate;
        function modifiedTimeout() {
          console.log(arguments);
         return originalTimeout.apply(null, arguments);
        }
        modifiedTimeout.cancel = function(promise) {
          return $delegate.cancel(promise);
        }
        return modifiedTimeout;
      }]);
  });
});