2015-10-26 45 views
6

我使用量角器測試我的角度應用程序。 一旦用戶登錄到我的應用程序,我設置$超時在一個小時內完成一些工作(所以如果用戶在13:00登錄,$超時將在14:00運行)。 我不斷收到這些故障:

"Timed out waiting for Protractor to synchronize with the page after 20 seconds. Please see https://github.com/angular/protractor/blob/master/docs/faq.md. The following tasks were pending: - $timeout: function onTimeoutDone(){....." 

我讀過這個超時頁:https://github.com/angular/protractor/blob/master/docs/timeouts.md 讓我明白量角器等待,直到頁面完全加載,這意味着他在等待$超時完成...

如何讓Protractor不等待$ timeout? 我不想使用:

browser.ignoreSynchronization = true; 

因爲那樣的話我的測試也適用於其他的原因而失敗(其它角分量仍然需要加載的時間......)

+1

您是否嘗試設置後立即通過測試沖洗是超時? – MBielski

回答

3

該解決方案將刷新活躍超時(as @MBielski mentioned it in comments),但原始刷新方法本身僅在anuglar-mocks中可用。要直接使用角度模擬,您必須將其作爲<script>標籤包含在頁面中,並且您還必須處理其創建的所有覆蓋,這會產生很多副作用。我可以通過監聽創建的任何超時重新創建flush,而不使用angular-mock,然後根據需要重置它們。

例如,如果你在你的角度應用程序超時:

$timeout(function() { 
    alert('Hello World'); 
}, 10000); // say hello in 10 sec 

測試將是這樣的:

it('should reset timeouts', function() { 

    browser.addMockModule('e2eFlushTimeouts', function() { 

     angular 
     .module('e2eFlushTimeouts', []) 
     .run(function ($browser) { 

      // store all created timeouts 
      var timeouts = []; 

      // listen to all timeouts created by overriding 
      // a method responsible for that 
      var originalDefer = $browser.defer; 

      $browser.defer = function (fn, delay) { 
       // originally it returns timeout id 
       var timeoutId = originalDefer.apply($browser, arguments); 
       // store it to be able to remove it later 
       timeouts.push({ id: timeoutId, delay: delay }); 
       // preserve original behavior 
       return timeoutId; 
      }; 

      // compatibility with original method 
      $browser.defer.cancel = originalDefer.cancel; 

      // create a global method to flush timeouts greater than @delay 
      // call it using browser.executeScript() 
      window.e2eFlushTimeouts = function (delay) { 
       timeouts.forEach(function (timeout) { 
        if (timeout.delay >= delay) { 
         $browser.defer.cancel(timeout.id); 
        } 
       }); 
      }; 

     }); 

    }); 


    browser.get('example.com'); 

    // do test stuff 

    browser.executeScript(function() { 
     // flush everything that has a delay more that 6 sec 
     window.e2eFlushTimeouts(6000); 
    }); 

    expect(something).toBe(true); 
}); 

它有點實驗性的,我不知道它是否會爲工作你的情況。通過將browser.addMockModule移動到單獨的node.js模塊,也可以簡化此代碼。如果你想刪除短暫的超時(比如100ms),可能會有問題,它可以取消當前正在運行的Angular進程,因此測試會中斷。

+0

不錯的解決方案。但是,如果我理解正確,該解決方案將取消所有超時,因此在超時過程中我無法測試斷言。 – BiAiB

+0

@BiAiB,超時只得到,當你調用'browser.executeScript(...)'部分取消了,我相信你可以先作出斷言,然後,如果需要殺死超時。也許把'browser.executeScript(...)'部分放在'afterEach'中也可以。 –

0

的解決方案是使用攔截和修改這是越來越超時和設置自定義超時幾毫秒(你想要的)到HTTP請求的HTTP請求,這樣經過一段長時間運行的HTTP請求會得到關閉(因爲新的超時),然後你可以測試即時響應。

這很好,很有前途。

相關問題