2014-05-16 7 views
5

Tworzę SPA, używając AngularJs i routera UI z Angular-UI. Teraz próbuję utworzyć logikę uwierzytelniania.Ui-router AngulaJs. Błąd testu kątomierza

$rootScope.$on("$stateChangeStart", function (event, toState) { 
    if(toState.authenticate && !MainService.isAuthenticated()) { 
     if($cookieStore.get('authToken')) { 
      MainService.loginWithToken($cookieStore.get('authToken')) 
      .then(function() { 
       $state.go(toState.name); 
       event.preventDefault(); 
      }); 
     } 

     $rootScope.requestPath = toState.name; 
     $state.go('public.login'); 
     event.preventDefault(); 
    } 

    if(toState.url == '/login' && MainService.isAuthenticated()) { 
     $state.go('private.main'); 
     event.preventDefault(); 
    } 
}); 

Po zmianie stanu sprawdza, czy w razie potrzeby stan wymaga uwierzytelnienia i transferu do stanu logowania. Również, jeśli użytkownik jest zalogowany, uniemożliwia osiągnięcie stanu logowania. Uwierzytelnianie odbywa się za pomocą tokena zapisanego w pliku cookie.

To jest mój scenariusz testowy kątomierz:

describe('Routes', function() { 
it('Should go to the selected path if user logged in', function() { 
    browser.get('/'); 
    expect(browser.getLocationAbsUrl()).toMatch("/login"); 

    browser.manage().addCookie("authToken", "aaa"); 

    browser.manage().getCookie("authToken").then(function(cookie) { 
     expect(cookie.name).toBe('authToken'); 
     expect(cookie.value).toBe('aaa'); 
    }); 

    browser.get('/'); 
    expect(browser.getLocationAbsUrl()).toMatch("/main"); 

    browser.get('/#/main'); 
    expect(browser.getLocationAbsUrl()).toMatch("/main"); 

    /* This part fails, because, when the user is logged in, 
    he should be transfered to main state, if he is trying to reach the 
    login page. In this failing case, the user is able to reach the 
    /login even if he is logged in. */ 

    browser.get('/#/login'); 
    expect(browser.getLocationAbsUrl()).toMatch("/main"); 

    browser.manage().deleteCookie("authToken"); 

    browser.get('/#/login'); 
    expect(browser.getLocationAbsUrl()).toMatch("/login"); 

    browser.get('/#/main'); 
    expect(browser.getLocationAbsUrl()).toMatch("/login"); 
}); 

});

Kiedy próbuję symulować zachowanie sprawdzić się, wszystko jest ok, ale gdy uruchamiam kątomierz:

Message: 
Expected 'http://localhost/#/login' to match '/main'. 

StackTrace: Błąd: Nie udało oczekiwanie

Odpowiedz

0

Być może trzeba czekać na stronie Aby załadować:

browser.get('/#/main'); 
var ptor = protractor.getInstance(); 
ptor.waitForAngular(); 
expect(browser.getLocationAbsUrl()).toMatch("/main"); 
+0

bez powodzenia, test nadal nie – nn4n4s

+0

Czy widzisz prawą stronę coraz ładowane podczas uruchamiania testów? Jeśli tak, spróbuj użyć 'ptor.sleep (1000);' tego używam, gdy jestem zdesperowany. Jeśli znajdziesz lepszy sposób, daj mi znać ... Jeśli nie widzisz załadowania odpowiedniej strony, może masz problem z usunięciem pliku cookie? – Cal

1

Wpadłem na kolejne pytanie, które rozwiązało ten problem.

Zasadniczo oczekuje się pojawienia elementu na nowej stronie, zamiast polegać na kątomierzu, aby czekać na zakończenie stanu/strony. W chwili pisania tej odpowiedzi kątomierz nadal nie jest wiarygodny na stronie oczekiwania w pełni załadowanej do interfejsu użytkownika. Kątomierz czeka na $ timeout i $ http do zrobienia.

official doc

więc jeśli używasz websocket, to nie może być pokryte (przynajmniej według moich obserwacji).

API trzeba użyć jest browser.wait

browser.wait(function() { 
     return $('#test321').isPresent(); // keeps waiting until this statement resolves to true 
     }, 
     timeToWaitInMilliseconds, 
     'message to log to console if element is not present after that time' 
    ); 

    expect($('#test321').isPresent()).toBe(true); 

można znaleźć szczegóły w następującym linkiem Protractor, AngularJS, Parse -- Protractor does not wait for Angular to resolve

0

pamiętać, że w wersji 1.3 browser.getLocationAbsUrl() kątowe powraca tylko względne ścieżki. Patrz problem https://github.com/angular/protractor/issues/1436:

Using angular 1.3 in the app under test and protractor 1.3.1 browser.getLocationAbsUrl() returns a relative url instead of the absUrl due to using angular.getTestability().getLocation() instead of $location.absUrl(). It's probably as easy as adding a getLocationAbs() to $$testability, but that goes into architectural questions I don't have context for.