我正在使用AngularJs和Angular-UI的ui-router创建SPA。现在我正在尝试创建身份验证逻辑。
$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();
}
});
在状态更改时,将检查状态是否需要身份验证并在必要时转移到登录状态。此外,如果用户登录,则会阻止其进入登录状态。身份验证由存储在cookie中的令牌完成。
这是我的量角器测试场景:
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");
});
});
当我尝试自己模拟测试行为时,一切正常,但是当我运行量角器时:
Message:
Expected 'http://localhost/#/login' to match '/main'.
堆栈跟踪: 错误:期望失败
答案 0 :(得分:2)
我碰到了另一个解决这个问题的问题。
基本上,您等待新页面中的元素出现而不是依赖量角器等待状态/页面完成加载。在撰写此答案时,量角器在ui-router满载的等待页面上仍然不可靠。量角器等待$ timeout和$ http完成。
所以如果你使用websocket,它可能不会被覆盖(至少根据我的观察)。
您需要使用的api是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);
您可以在以下链接中找到详细信息 Protractor, AngularJS, Parse -- Protractor does not wait for Angular to resolve
答案 1 :(得分:0)
您可能需要等待页面加载:
browser.get('/#/main');
var ptor = protractor.getInstance();
ptor.waitForAngular();
expect(browser.getLocationAbsUrl()).toMatch("/main");
答案 2 :(得分:0)
请注意,在Angular版本1.3 browser.getLocationAbsUrl()
中仅返回相对路径。请参阅https://github.com/angular/protractor/issues/1436中的问题:
在测试中使用角度1.3和量角器1.3.1 browser.getLocationAbsUrl()返回一个相对url而不是absUrl,因为使用了angular.getTestability()。getLocation()而不是$ location.absUrl()。它可能就像将getLocationAbs()添加到$$可测试性一样简单,但这可归结为我没有上下文的架构问题。