重新加载Angular app

时间:2015-06-11 14:20:46

标签: angularjs selenium testing protractor

我有一个Protractor测试,启动重新加载相同的Angular应用程序。有时它在Travis构建中失败,但在构建一次或两次重新启动后会通过。很少在我的本地机器上失败。 Travis构建使用Firefox,但它在我的机器上失败的时间一直在使用Firefox和Selenium的chromedriver。

我已设置rootElement: 'html'(按this GitHub issue on Protractor中的建议),因为这是ng-app的位置,但我仍然收到此错误:

  

等待Protractor与页面同步时出错:“root元素(html)没有注入器。这可能意味着它不在ng-app中。”

错误是angular.element('html').injector()返回falsey的结果,即使Angular has loaded。量角器代码中的previous test证实了这一点。

测试涉及被重定向到恰好是同一个角应用的不同index.html。重定向的原因是提供语言选择,然后以该语言重新加载应用程序。

有多个区域设置(为简单起见,此处显示了两个区域设置)。 app是文档根目录,因此app/index.html是入口点,可检测系统语言或默认为en-gb,然后重定向到app/<locale>/index.html。前者不是Angular应用程序(app/);后者是(app/<locale>/)并链接到../common/的库和Angular模块文件。区域设置文件夹中的index.html个文件是相同的。

访问文档根目录时会发生什么?

/ - &gt;重定向/en-gb/#/language

当你选择德语时?

/en-gb/#/language重定向../de/#/menu - &gt; /de/#/menu

目录结构:

└── app
    ├── common
    │   ├── fonts
    │   ├── images
    │   ├── lib
    │   ├── modules
    │   └── styles
    ├── de
    │   ├── i18n.js
    │   └── index.html
    ├── en-gb
    │   ├── i18n.js
    │   └── index.html
    └── index.html

测试:

(function () {

    'use strict';

    describe('Module: app, language screen:', function () {

        beforeEach(function () {
            browser.get('http://localhost:9000/en-gb/#/language/');
            this.$germanChoice = // get the clickable element to select German
            this.$buttonContinue = // get the clickable element to continue
        });

        describe('continue button', function () {
            it('should go forward to the menu', function () {
                this.$germanChoice.click();
                this.$buttonContinue.click();
                expect(browser.getCurrentUrl()).toBe('http://localhost:9000/de/#/menu/');
            });
        });

    });

}());

使用缩小文件的区域设置index.html

<!doctype html>
<!--[if IE 8]>         <html id="ng-app" ng-app="app" lang="{{ app.locale.html }}" class="no-js lt-ie10 lt-ie9"> <![endif]-->
<!--[if IE 9]>         <html id="ng-app" ng-app="app" lang="{{ app.locale.html }}" class="no-js lt-ie10">        <![endif]-->
<!--[if gt IE 9]><!--> <html id="ng-app" ng-app="app" lang="{{ app.locale.html }}" class="no-js">                <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title ng-bind="app.page.title ? app.page.title + ' - ' + app.page.titleBase : app.page.titleBase"></title>
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="stylesheet" href="../common/lib/nouislider/jquery.nouislider.css" />

        <!--[if gt IE 8]><!-->
            <link rel="stylesheet" href="../common/styles/b8a085fb.main.css">
        <!--<![endif]-->

        <!--[if lt IE 9]>
            <link rel="stylesheet" href="../common/styles/f71e8123.ie.css">
        <![endif]-->

        <!--[if lt IE 9]>
            <script src="../common/scripts/a5663f12.lt-ie9.js"></script>
        <![endif]-->
    </head>

    <body ng-class="{ 'ios6': app.environment.ios6, 'gt-ios6': app.environment.gtIos6, 'cordova': app.environment.cordova }">

        <div ng-view="" autoscroll="true"></div>

        <script src="../common/scripts/cbd2241e.app.js"></script>
        <script src="i18n.js"></script>

    </body>
</html>

1 个答案:

答案 0 :(得分:2)

我偶尔会遇到非Angular登录页面的问题(其中一些有几个步骤)。我认为您的语言选择页面可能类似。该解决方案在您的测试中有点逻辑,并与browser.driver中公开的Webdriver API相结合。

if ('some condition that determines you are on a non-Angular page') {
  browser.driver.findElement(by.id('language-choice')).click();
}

测试的最佳条件是:

  1. 测试是否显示某些唯一元素。
  2. 获取当前页面的网址,并将其与预期值进行比较。
  3. 每当你不在Angular页面上时使用browser.driver,因为它绕过了Protractor。否则,Protractor将寻找Angular,找不到它,并抛出错误。你可以在菜单的下方区域找到browser.driver所能做的一切:http://angular.github.io/protractor/#/api

    然后,为了在使用Protractor之前等待Angular页面显示,请尝试以下代码段:

    browser.driver.wait(function() {
        return browser.driver.getCurrentUrl().then(function(url) {
            return url.toString().indexOf('my angular page url') !== -1;
        }, function(err) {
            throw err;
        });
    }, 5000, 'Timed out waiting for your Angular page to load.');
    

    这在您的onPrepare语句中特别有用(只需在return之前添加browser.driver.wait即可。测试将等待您的Angular页面加载,之后您可以将Protractor放在心里。

    稍微讨论一下,这个相同的片段可用于对多步非Angular入门页面做出反应。并且,封装到它自己的整洁的小函数中,这可以在Protractor易于被转储到非Angular页面的任何地方重复使用。