ranakrunal9
ranakrunal9

Reputation: 13558

Angular2 e2e test case with protractor throwing error

I have created my app with angular2-webpack-starter and i have used socket.io with it. I have created one common service to create socket connection and listen its method. this service is used and initialized after user is logged in. When app is running and i execute test case for login, i am checking url with below code :

browser.getCurrentUrl().then((url) => {
    expect(url).toEqual('/dashboard');    
});

The issue is when socket is connected its throwing error 'Timed out waiting for Protractor to synchronize with the page after 15 seconds' and if socket is not connected same test case is running without any error.

Upvotes: 1

Views: 603

Answers (2)

demonintherough
demonintherough

Reputation: 304

So the solution I have found is:

(This is copied from here for your convenience. All credit goes to https://github.com/cpa-level-it

https://github.com/angular/angular/issues/11853#issuecomment-277185526)

What I did to fix the problem was using ngZone everywhere I have an observable that relies on socket.io.

So let's say you have this method in your service that gives you an observable on a socket.io.

private socket: SocketIOClient.Socket;

 public getSocketIOEvents(): Observable<SocketIOEvent> {

        if (this.socket == null) {
            this.socket = io.connect(this._socketPath);
        }

        return Observable.create((observer: any) => {
            this.socket.on('eventA', (item: any) => observer.next(new SocketIOEvent(item)));
            this.socket.on('eventB', (item: any) => observer.next(new SocketIOEvent(item)));
            return () => this.socket.close();
        });
    }

Then you need to use the ngZone service to tell Angular to create the socket outside the Angular 2 zone and then execute the callback of the Observable inside the Angular 2 zone.

import {  NgZone } from '@angular/core';
constructor(
    private socketService: SocketIOService,    ,
    private ngZone: NgZone) { }


ngOnInit() {

    // Subscribe to the Observable outside Angular zone...    
    this.ngZone.runOutsideAngular(() => {
      this.socketService
        .getSocketIOEvents()
        .subscribe(event => {

         // Come back into Angular zone when there is a callback from the Observable
           this.ngZone.run(() => {
            this.handleEvent(event);
          });
        });
    });

  }

This way protractor doesn't hang waiting on the socket.

Upvotes: 0

BarretV
BarretV

Reputation: 1197

I'm not sure if connecting to the socket is actually make things take longer or not but if the 15 seconds isn't enough time, you can change the allScriptsTimeout:timeout_in_millis in your protractor configuration file

protractor timeouts

Upvotes: 1

Related Questions