2017-08-27 2 views
1

J'utilise Protractor avec Chai-comme promis pour ma nouvelle application Angular 4. Je n'ai que 2 tests e2e pour le moment. L'un se connecte à un utilisateur existant, l'autre en enregistre un nouveau. Ma logique d'inscription connectera également l'utilisateur nouvellement créé si l'inscription réussit.Chai comme promis finalement n'attend pas assez longtemps dans les tests de Protractor e2e contre une application Angular

est ici le code html:

<ul class="navbar-nav my-2 my-lg-0"> 
    <li *ngIf="!isAuthenticated()" class="nav-item"> 
    <button id="loginLink" class="btn btn-link nav-link" style="line-height: inherit" type="button" role="button" (click)="openLoginModal()">Login</button> 
    </li> 
    <li *ngIf="!isAuthenticated() && signupAllowed()" class="nav-item"> 
    <button id="signupLink" class="btn btn-link nav-link" style="line-height: inherit" type="button" role="button" (click)="openSignupModal()">Sign up</button> 
    </li> 
    <li *ngIf="isAuthenticated()" class="nav-item"> 
    <a id="logoutLink" class="nav-link" role="button" (click)="logout()">Logout</a> 
    </li> 
</ul> 

Et voici les tests E2E code:

import { browser, by, element } from "protractor"; 

const expect = global[ 'chai' ].expect; 

describe('Auth',() => { 
    describe('login/logout',() => { 
    it('should login successfully with valid username and password tuple',() => { 
     // arrange 
     browser.get('/'); 
     expect(element(by.id('loginLink')).isPresent()).to.eventually.be.true; 
     element(by.id('loginLink')).click(); 

     // act 
     element(by.id('usernameInput')).sendKeys('jeep87c'); 
     element(by.id('passwordInput')).sendKeys('1111'); 
     element(by.id('loginBtn')).click(); 

     // assert 
     expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true; 
     element(by.id('logoutLink')).click(); 
     expect(element(by.id('loginLink')).isPresent().to.eventually.be.true; 
    }); 
    }); 

    describe('signup/logout',() => { 
    it('should succeeds with unused username and matching passwords and login',() => { 
     // arrange 
     browser.get('/'); 
     expect(element(by.id('signupLink')).isPresent()).to.eventually.be.true; 
     element(by.id('signupLink')).click(); 

     // act 
     element(by.id('usernameInput')).sendKeys('test'); 
     element(by.id('passwordInput')).sendKeys('1111'); 
     element(by.id('confirmPasswordInput')).sendKeys('1111'); 
     element(by.id('signupBtn')).click(); 

     // assert 
     expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true; 
     element(by.id('logoutLink')).click(); 
    }); 
    }); 
}); 

Comme vous pouvez le voir, les deux tests sont assez similaires. Mais, le signup/logout échoue sur expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true;, qui est également présent dans le test login/logout, qui réussit.

Qu'est-ce qui me manque? On dirait que ça n'attend pas du tout. Mais cela fonctionne pour le login/logout (ce qui signifie que le test réussit).

Les deux demandes de connexion à l'API & prennent environ 200ms pour chacune d'elles. Il est important de noter que lorsqu'un utilisateur soumet le formulaire d'inscription, il déclenche d'abord une demande d'inscription à l'API et si elle réussit, une demande de connexion. Il faudra donc environ 400ms pour terminer. Ce qui, je suppose, est au-dessus de ce que eventually va interroger/attendre.

EDIT: Certains expect(...).to.eventually manquaient dans le code ci-dessus, que j'ai corrigé. En tant que votre information, voici l'échec d'assertion:

Auth signup/logout should succeeds with unused username and matching passwords and login: 

    AssertionError: expected false to be true 

On se sent vraiment comme la détermination de la promesse avant que l'élément est effectivement présent dans le Royaume et ne parviennent pas l'affirmation. Au lieu d'interroger à nouveau jusqu'à ce que ce soit vrai ou timeout.

EDIT # 2: Juste essayé exactement le même code mais, en attendant 5 secondes avant d'exécuter les deux dernières lignes et il a passé avec succès ...

setTimeout(function() { 
    expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true; 
    element(by.id('logoutLink')).click(); 
}, 5000); 

Il est certainement expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true; promesse la résolution de jeûner à faux et échouer le test. Comment puis-je réparer ça?

Toute aide sera appréciée.

Répondre

0

Je ne suis pas sûr que c'était un problème qui entraînait cela, mais, une fois que je change mon code d'inscription de:

signup() { 
    this.auth.signup(signupData) 
     .subscribe({ 
        error: (err: any) => {}, 
        complete:() => { 
        this.auth.login(new LoginData(signupData.username, signupData.password)) 
         .subscribe({ 
             error: (err: any) => {}, 
             complete:() => { 
             this.activeModal.close(); 
             this.router.navigateByUrl('/'); 
             } 
            }); 
        } 
       }); 
} 

Pour:

signup() { 
    this.auth.signup(signupData) 
     .subscribe({ 
        next: (response) => this.auth.setToken(response.json().token), 
        error: (err: any) => {}, // TODO-jeep87c: Handle 403, 401 with proper UI alert and 500/404 in common handler (use username.setErrors) 
        complete:() => { 
        this.activeModal.close(); 
        this.router.navigateByUrl('/'); 
        } 
       }); 
} 

Le test a réussi. J'utilise ng2-ui-auth étant un port Angular 2+ d'origine Satellizer pour AngularJs.

Cela peut être lié à la façon dont j'ai utilisé les objets Obsersables renvoyés par les méthodes de ce service d'authentification.

Si quelqu'un pouvait expliquer, je serais heureux de vraiment comprendre ce qui s'est passé ici.