2017-03-17 10 views
11

問題の説明発行:Canonicalの方法は

を分度器、エンドツーエンドのテストで我々のアプリケーション内のいずれかのページを開いている間に私たちは最近、この悪名高いエラーを持っています:

失敗:50秒後に非同期角度タスクが終了するのを待ってタイムアウトしました。これは、現在のページがAngularアプリケーションではないためです。

これが私たちの試験の一つでbrowser.get("/some/page/");の呼び出しで発生:

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

    it("should test something", function() { 
     // ... 
    }); 
)}; 

そして、私たちのケースについて奇妙な何であるか、エラーが私たちのアンギュラウェブで他のページにはスローされないということですアプリケーション - 分度器はAngularと同期しても問題ありません。 - ng-app場所ごとの物事はすべてのページで同じですng-appがルートhtmlタグに定義されています

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

挙動が一致している - 私たちはbrowser.get()でこのページに移動するたびに、我々はこのエラーを取得します。アプリ内の他のページに移動するたびに、同期が機能します。

もちろん、このページの同期をオフにして角度のないものとして扱うことができますが、これは回避策としてしか考えられないことに注意してください。

質問:

分度器ツー角度同期が失敗し他に何を引き起こす可能性がありますか?私たちは何を確認すべきですか?

そして、一般に分度器の同期問題をデバッグするにはどうすればよいですか?

最新の分度器5.5.1を使用すると、角度1.5.6。

+0

シンクの問題があります。 'https:// github.com/angle/protractor/blob/master/docs/timeouts.md#how-to-disable-waiting-for-angular'を参照してください。彼らが言っている解決策は、同期をオフにするか、おそらく 'browser.get()'の代わりに 'driver.browser.get()'を使うことです。 –

+0

@KishanPatelありがとうございましたが、質問で言及したように、同期をオフにしてページを非角型として扱うことができると理解しています。これは回避策であり、うまくいくはずですが、この特定のページおよびこのような問題をデバッグするための一般的なガイドラインでは機能しません。 – alecxe

+0

あなたのエラーには、Angularのために同期できることが明確に述べられています。また、 '$ http'と' $ timeout'の2つの理由があります。 - 分度器はこれらのサービスが終了するのを待ちます。 '$ timeout'によって引き起こされた場合は' $ interval'で置き換えるだけで、 '$ http'ではXHRサービスを書いて' $ http'の代わりに使用しない限り回避策はありません – maurycy

答えて

6

[OK]を、その質問は私を待っているもの分度器の判定方法についてのプログラムで解決策を考え出した私に興味をそそられて:ここでは、タイムアウトを試すことができhttp://plnkr.co/edit/O0CkpnsnUuwEAV8I2Jil?p=preview plunkerで

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) 

$ httpコール、私の遅延されたエンドポイントは、コールを解決する前に10秒待つでしょう、これはあなたに役立つことを願っています

1

私は@ maurycyに問題が$ http/$タイムアウトに関連していることに同意します。簡単な修正は、ここに記載されているように$間隔で$タイムアウトを置き換えるために、通常です:https://github.com/angular/protractor/blob/master/docs/timeouts.md

推奨事項: merge these sane defaults: allScriptsTimeout: 60000, // 1 minute jasmineNodeOpts: { defaultTimeoutInterval: 300000 // 5 minutes. Allows for 5 commands spanning the full synchronization 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; 
     }]); 
    }); 
});