Run ngrx / effect outside the Angular zone to prevent Protractor timeout

I just started writing e2e tests for my application and am in timeouts with Protractor and ngrx / effects.

I have the following effect dispatching an action every couple of minutes:

@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())
        ));

Attempting to run the Protractor test causes a timeout check with the following error, since Angular is unstable.

Failure: Angular asynchronous task wait timeout after 11 seconds. This may be due to the fact that the current page is not Angular. Please see our FAQ for more information: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular Waiting for an element with a locator - Locator: By (css selector, .toolbar-name)

(https://github.com/angular/protractor/issues/3349) NgZone Angular. 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?

+6
1

, 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;
}

, (, asap async), :

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))

, (, bufferTime, debounceTime, Observable.timer ..) . observeOn , - .

+13

Source: https://habr.com/ru/post/1016177/


All Articles