【问题标题】:AngularJs ui-router. Protractor test failingAngularJs ui 路由器。量角器测试失败
【发布时间】:2018-12-06 20:09:56
【问题描述】:

我正在使用 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'.

堆栈跟踪: 错误:预期失败

【问题讨论】:

    标签: angularjs angular-ui protractor


    【解决方案1】:

    我遇到了另一个解决此问题的问题。

    基本上,您等待新页面中的元素出现,而不是依靠量角器等待状态/页面完成加载。在撰写此答案时,量角器在等待 ui-router 完全加载的页面上仍然不可靠。 Protractor 等待 $timeout 和 $http 完成。

    official doc

    所以如果您使用的是 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

    【讨论】:

      【解决方案2】:

      您可能需要等待页面加载:

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

      【讨论】:

      • 不走运,测试仍然失败
      • 在运行测试时,您是否看到加载了正确的页面?如果是这样,请尝试使用ptor.sleep(1000);,这就是我绝望时使用的方法。如果您找到更好的方法,请告诉我...
      【解决方案3】:

      请注意,在 Angular 1.3 版中,browser.getLocationAbsUrl() 仅返回相对路径。请参阅https://github.com/angular/protractor/issues/1436 中的问题:

      在被测应用程序中使用 angular 1.3 和量角器 1.3.1 browser.getLocationAbsUrl() 由于使用 angular.getTestability().getLocation() 而不是 $location.absUrl() 而返回相对 url 而不是 absUrl。这可能就像将 getLocationAbs() 添加到 $$testability 一样简单,但这涉及到我没有上下文的架构问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-28
        • 1970-01-01
        相关资源
        最近更新 更多