2017-01-12 73 views
3

我使用ng2-idle在一段時間後自動註銷用戶。我初始化它在我appComponent構造:爲量角器測試停止ng2-idle

import {Idle, DEFAULT_INTERRUPTSOURCES} from '@ng-idle/core'; 

export class AppComponent { 

    constructor(
     private idle:Idle) { 

     idle.setIdle(21600); 
     idle.setTimeout(1); 
     idle.setInterrupts(DEFAULT_INTERRUPTSOURCES); 

     idle.onTimeout.subscribe(() => { this.logout(); }); 
    }; 

成功登錄我使用this.idle.watch()啓動它在我LoginComponent(空閒注入的構造函數)。

這一切工作正常,但是當我去跑量角器測試他們超時,我認爲是因爲量角器等待超時結束這將需要一段時間,因爲我將ng2-idle設置爲6小時!

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. 

如果我沒有初始化使用Idle.watch()那麼測試運行。

我想要做的是設置Idle.stop();在我量角器配置文件中onPrepare塊並將其重置爲Idle.watch();測試是在我onComplete塊完成後。

我試圖在量角器的conf文件var idle = require('@ng-idle/core');但將我帶回了以下內容:

ReferenceError: document is not defined

那麼,怎樣才能我需要量角器配置文件中的NG2空閒模塊?

+0

我打了同樣的問題,試圖找出。如果idle +超時值小於DEFAULT_TIMEOUT_INTERVAL,則測試似乎正在運行。 – santon

回答

2

我不能爲您提出的問題提供解決方案。但我會爲您提供一種解決此問題的不同方法。在爲我的團隊設置Protractor時,在使用ng-idle實現會話超時策略後,我遇到了同樣的問題。在對如何解決這個問題感到一些胃口後,我意識到Angular zone API可以用來解決這個問題。這是我的解決方案的appcomponent。 請參閱runOutsideAngular運行區域中的方法。

請注意,所有狀態更改都封裝在run方法中。如果不是,則更改檢測將不起作用,並且包括倒數計時器在內的任何狀態字段都不會更新UI。

此解決方案涉及修改使用ng-idle的應用程序,因爲在我目前的理解中,無法在Protractor內完成此操作。

this.ngZone.runOutsideAngular

@Component({ 
selector : 'app-root', 
templateUrl: './app.component.html', 
styleUrls : [ './app.component.scss' ] 
}) 

export class AppComponent implements OnInit, OnDestroy{ 

idleState = 'Not started.'; 
idleStateTitle = ''; 
idleStateBtnText = ''; 
timedOut = false; 

@ViewChild(DialogComponent) dialog: DialogComponent; 

constructor(private idle: Idle, 
      private locationStrategy: LocationStrategy, 
      private authUtils: AuthUtils, 
      private ngZone: NgZone){ 

    this.ngZone.runOutsideAngular(() => { 
     //Idle timer is set to 28 minutes and timeout count down timer will run for 2 minutes. 
     idle.setIdle(28 * 60); 
     idle.setTimeout(120); 
    }); 


    //When idling starts display the dialog with count down timer 
    idle.onIdleStart.subscribe(() =>{ 
     this.idleState = ''; 
     this.idleStateTitle = 'Your session is about to expire.'; 
     this.idleStateBtnText = 'Stay Logged In'; 
     this.ngZone.run(() => this.dialog.show()); 
    }); 

    //User stopped idling 
    idle.onIdleEnd.subscribe(() =>{ 
     this.idleState = 'No longer idle.'; 
    }); 

    //Show timeout warning two minutes before expiry 
    idle.onTimeoutWarning.subscribe((countdown) =>{ 
     this.ngZone.run(() => { this.idleState = 'Your session will time out in ' + countdown + ' seconds! '}); 
    }); 

    //Session Timed out 
    idle.onTimeout.subscribe(() =>{ 
     this.ngZone.run(() =>{ 
      this.idleStateTitle = "Your session has expired."; 
      this.idleState = 'To Continue, log back in'; 
      this.timedOut = true; 
      this.idleStateBtnText = 'Log in Again'; 
     }); 
    }); 
} 

reset(){ 
    this.ngZone.runOutsideAngular(() => { 
     this.idle.watch(); 
    }); 
    this.ngZone.run(() =>{ 
     this.idleState = 'Started.'; 
     this.idleStateTitle = ""; 
     this.idleStateBtnText = ''; 
     this.timedOut = false; 
    }); 
} 

title = 'Projects'; 

/** 
* <p>Refresh Token by getting user token from the user service. Also reset the idle state timer here.</p> 
*/ 
refreshToken(){ 
    this.authUtils.refreshToken(); 
    this.reset(); 
} 

/** 
* Handle timeout 
*/ 
processTimeout(){ 
    this.dialog.hide(null); 
    if(this.timedOut){ 
     AuthUtils.invalidateSession(); 
     let origin = window.location.origin; 
     window.location.href = origin + this.locationStrategy.getBaseHref() + "?_="+ (Math.floor(Math.random() * 10000)); 
    } 
    else{ 
     this.refreshToken(); 
    } 
} 

ngOnInit(): void{ 
    this.reset(); 
} 

ngOnDestroy(): void{ 
    this.ngZone.runOutsideAngular(() =>{ 
     this.idle.stop(); 
    }); 
} 
} 

我不得不使用browser.waitForAngularEnabled(false)和禁止並在beforeEachafterEach茉莉程序使他們的一些部分成功。但它們很脆,並且不適用於所有測試。

編輯:我檢查NG2空閒問題跟蹤,發現有一個開放的缺陷爲此here