Testing 如何使用XHR请求为angular应用程序创建e2e karma测试?

Testing 如何使用XHR请求为angular应用程序创建e2e karma测试?,testing,angularjs,karma-runner,Testing,Angularjs,Karma Runner,我用登录创建了angular应用程序。我想用e2e业力来测试它,但是出现了一些问题。我需要在每次测试前登录 describe('Tests for logged user', function () { // login before each test beforeEach(function () { browser().navigateTo('/web/'); input('user.email').enter('user@test.com'

我用登录创建了angular应用程序。我想用e2e业力来测试它,但是出现了一些问题。我需要在每次测试前登录

describe('Tests for logged user', function () {

    // login before each test
    beforeEach(function () {
        browser().navigateTo('/web/');
        input('user.email').enter('user@test.com');
        input('user.password').enter('aaa');
        element('button#login').click();
    });

    // logout after each test
    afterEach(function () {
        element('#menu-logout').click();
    });

    it('dashboard page', function () {
        expect(element('h1').text()).toBe('Dashboard');
    });


    it('profile page', function () {
        browser().navigateTo('/web/#/profile');
        expect(element('h1').text()).toBe('Profile');
    });

    ...
});
问题是在beforeach
元素('button#login')中,单击()在后台和第二个测试中调用XHR请求
browser()。导航到('/web/#/profile')不要等待登录过程结束

可以在
单击()之后添加一些睡眠,但这不是一个好的解决方案。我发现解决方案是修改DSL并创建
Future
对象,但我有点困惑如何进行最佳实践

请重新编写此文件以使用DSL和
addFuture
addFutureAction
?谢谢

更新:添加了
MainCtrl
SignCtrl
Sign
服务

MainCtrl
是ng控制器的顶层:

"use strict";

app.controller('MainCtrl', ['$scope', '$http', '$location', 'Sign',
    function ($scope, $http, $location, Sign) {
        var token;
        $scope.user = {};
        $scope.signed = false;

        init();

        function init() {
            token  = localStorage.getItem('token');
            if (token) {
                $scope.signed = true;
                $scope.user = JSON.parse(localStorage.getItem('user'));
            } else {
                $location.path('/sign/in');
            }
        }

        $scope.afterSignIn = function (user) {
            $scope.signed = true;
            $scope.user = user;
        }

        $scope.signOut = function () {
            token  = localStorage.getItem('token');
            var promise = Sign.out(token);
            promise.then(function () {
                $location.path('/sign/in');
            }, function () {
                alert('Unable to sign out');
            });

        }
}]);
这是信号控制器

app.controller('SignCtrl', ['$scope', '$location', 'Sign', function ($scope, $location, Sign) {

    $scope.$parent.signed = false;
    $scope.errorMessage = '';

    $scope.in = function () {
        var promise = Sign.in($scope.user);
        promise.then(function () {
            $scope.$parent.afterSignIn($scope.user);
            $location.path('/');
        }, function (message) {
            $scope.signError = true;
            $scope.errorClass = "has-error";
            $scope.errorMessage = message;
        });
    }

    $scope.removeError = function () {
        $scope.errorMessage = '';
        $scope.errorClass = '';
    }

}]);
这是签名服务

app.factory('Sign', ['$resource', '$http', '$q', function ($resource, $http, $q) {

    var factory = {};

    factory.in = function (user) {
        var defer = $q.defer();

        $http.post('/api/sign/in', user)
            .success(function (data) {
                localStorage.setItem('token', data.token);
                localStorage.setItem('user', JSON.stringify(data.user));
                $http.defaults.headers.common['X-Token'] = data.token;
                defer.resolve();
            }).error(function (data, status) {
                defer.reject(data);
            });

        return defer.promise;
    };

    factory.out = function (token) {
        var defer = $q.defer();

        $http.post('/api/sign/out')
            .success(function () {
                localStorage.removeItem('token');
                localStorage.removeItem('user');
                delete $http.defaults.headers.common['X-Token'];
                defer.resolve();
            }).error(function () {
                defer.reject();
            });
        return defer.promise;
    }

    return factory;
}]);

在您的实际应用程序中,如何通知控制器或服务登录成功或失败?我添加了MainCtrl、SignCtrl和Sign service