问题
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.
回答1:
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
回答2:
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.
来源:https://stackoverflow.com/questions/38930272/angular2-e2e-test-case-with-protractor-throwing-error