gpt4 book ai didi

angular - 在 Angular 区域之外运行 ngrx/effect 以防止 Protractor 超时

转载 作者:太空狗 更新时间:2023-10-29 17:05:45 24 4
gpt4 key购买 nike

我刚开始为我的应用程序编写端到端测试,但遇到了 Protractor 和 ngrx/effects 的超时问题。

我每两分钟调度一个 Action 有以下效果:

@Effect() setSessionTimer$ = this.actions$
.ofType(Auth.ActionTypes.SET_SECONDS_LEFT)
.map(toPayload)
.switchMap(secondsLeft => Observable.concat(
Observable.timer((secondsLeft - 60) * 1000).map(_ => new Auth.SessionExpiringAction(60)),
Observable.timer(60 * 1000).map(_ => new Auth.SessionExpiredAction())
));

尝试运行 Protractor 测试会导致测试超时并出现以下错误,因为 Angular 不稳定。

Failed: Timed out waiting for asynchronous Angular tasks to finish after 11 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular While waiting for element with locator - Locator: By(css selector, .toolbar-title)

根据这个问题(https://github.com/angular/protractor/issues/3349),我需要使用 NgZone 在 Angular 之外运行一个间隔 Observable。我尝试了 this.ngZone.runOutsideAngular() 的不同组合,但没有任何效果,而且测试一直超时。

例如这不起作用:

@Effect() setSessionTimer$ = this.actions$
.ofType(Auth.ActionTypes.SET_SECONDS_LEFT)
.map(toPayload)
.switchMap(secondsLeft => this.ngZone.runOutsideAngular(() => Observable.concat(
Observable.timer((secondsLeft - 60) * 1000).map(_ => new Auth.SessionExpiringAction(60)),
Observable.timer(60 * 1000).map(_ => new Auth.SessionExpiredAction())
)));

我不知道如何在 Angular 之外运行效果。有人成功地进行了 e2e 测试他们的 ngrx 应用程序吗?

最佳答案

解决方案是安排计时器可观察到在 NgZone 之外运行,然后在发生有趣的事情时重新进入该区域。

首先,您需要两个实用函数来包装任何调度程序并使效果进入或离开区域:

import { Subscription } from 'rxjs/Subscription';
import { Scheduler } from 'rxjs/Scheduler';
import { NgZone } from '@angular/core';


class LeaveZoneSchduler {
constructor(private zone: NgZone, private scheduler: Scheduler) { }

schedule(...args: any[]): Subscription {
return this.zone.runOutsideAngular(() =>
this.scheduler.schedule.apply(this.scheduler, args)
);
}
}

class EnterZoneScheduler {
constructor(private zone: NgZone, private scheduler: Scheduler) { }

schedule(...args: any[]): Subscription {
return this.zone.run(() =>
this.scheduler.schedule.apply(this.scheduler, args)
);
}
}

export function leaveZone(zone: NgZone, scheduler: Scheduler): Scheduler {
return new LeaveZoneSchduler(zone, scheduler) as any;
}

export function enterZone(zone: NgZone, scheduler: Scheduler): Scheduler {
return new EnterZoneScheduler(zone, scheduler) as any;
}

然后使用调度程序(如 asapasync),您可以使流进入或离开区域:

import { async } from 'rxjs/scheduler/async';
import { enterZone, leaveZone } from './util';

actions$.ofType('[Light] Turn On')
.bufferTime(300, leaveZone(this.ngZone, async))
.filter(messages => messages.length > 0)
.observeOn(enterZone(this.ngZone, async))

请注意,大多数基于时间的运算符(如 bufferTimedebounceTimeObservable.timer 等)已经接受了替代调度程序.当发生有趣的事情时,您只需要 observeOn 重新进入该区域。

关于angular - 在 Angular 区域之外运行 ngrx/effect 以防止 Protractor 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43121400/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com