AngularFire / Protractor : une solution au fameux message d'erreur ScriptTimeoutError


Dans le cadre du développement d'une application ionic 4 / Angular 6AngularFire2, et plus précisément les tests e2e, j'ai tourné en ronds pendant plus de 24 h, suite à un comportement mystérieux de l'environnement de test qui se bloquait sur des messages d’erreur: ScriptTimeoutError: script timeout: result was not received in 11 seconds. 

Je me suis acharné sur le fichier de configuration protractor.conf.js et sur les fichiers .steps.ts en essayant plusieurs combinaisons possibles:
When(/^User click on the button "([^"]*)"$/, async (id) => {
   await element(by.id(id)).click();
});


When(/^User click on the button "([^"]*)"$/, function(id:string, callback){
   element(by.id(id)).click().then(callback);
});

mais pas de lumière à la fin du tunnel.

Jusqu'à ce que je tombe sur une discussion sur github  (https://github.com/angular/angularfire2/issues/225) où je découvre que le problème vient du client AngularFirestore qui opère dans le même contexte d’exécution "zone" que Angular; AngularFirestore déclenche une série d'intervals et de timeouts, qui, à leur tour, empêchent protractor de synchroniser avec Angular.

La solution: 
 Bon, il suffit tout simplement de faire exécuter AngularFirestore dans un autre contexte d'exécution que le "main context" à savoir celui du framework angular. en utilisant NgZone

import { Injectable, NgZone } from '@angular/core';
import { AngularFirestore } from 'angularfire2/firestore';

@Injectable()
export class FirestoreService {


   constructor(
      private firestore: AngularFirestore,
      private zone: NgZone) {
   }


   save(item: any, collection: string){
      this.zone.runOutsideAngular(() => {
         let shirtsCollection = firestore.collection<Item>('tshirts');
         shirtsCollection.add({ name: 'item', price: 10 });
      });
   }


}

Comments

Popular posts from this blog

AngularFire / Protractor: a solution to the famous ScriptTimeoutError error message