当重新加载角度应用程序时,量角器测试有时会失败

时间:2021-08-02 01:23:47

I have a Protractor test that initiates a reloading of the same Angular app. Occasionally it fails in a Travis build, but will pass after one or two restarts of the build. Rarely it fails on my local machine. The Travis builds use Firefox, but the times it has failed on my machine have been using both Firefox and Selenium's chromedriver.

我有一个量角器测试,它开始重新加载相同的角化应用程序。偶尔它在Travis构建中失败,但在一次或两次重新启动之后就会通过。在我的本地机器上很少出现故障。构建Travis使用Firefox,但是它在我的机器上失败的次数是同时使用Firefox和Selenium的chromedriver。

I've set rootElement: 'html' (as recommended in this GitHub issue on Protractor) because that is where the ng-app is, but I still get this error:

我已经设置了rootElement: 'html'(正如在pro拖拉机上GitHub的问题中建议的那样),因为这就是ng-app的位置,但我还是得到了这个错误:

Error while waiting for Protractor to sync with the page: "root element (html) has no injector. this may mean it is not inside ng-app."

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

The error is the result of angular.element('html').injector() returning falsey, even though Angular has loaded. A previous test in the Protractor code confirms this.

这个错误是Angular .element('html').injector()返回falsey,尽管angle已经加载。量角器代码中的先前测试证实了这一点。

The test involves being redirected to a different index.html that happens to be the same angular app. Reason for the redirect is to offer a language choice then reload the app in that language.

测试涉及重定向到不同的索引。这恰好是同一个角化的应用程序。重定向的原因是提供语言选择,然后用这种语言重新加载应用程序。

There are multiple locales (two shown here for simplicity). app is the document root, so app/index.html is the entry point, which detects the system language or defaults to en-gb and then redirects to app/<locale>/index.html. The former is not an Angular app (app/); the latter is (app/<locale>/) and links to ../common/ for library and Angular module files. The index.html files in the locale folders are identical.

有多个地区(为了简单起见,这里显示了两个)。app是文档根,所以app/index。html是入口点,它检测系统语言或默认为en-gb,然后重定向到app/ /index.html。前者不是一个角化应用(app/);后者是(app/ /)和链接到。/通用/用于库和角模块文件。索引。语言环境文件夹中的html文件是相同的。

What happens when you visit the document root?

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

/ -> redirect /en-gb/#/language

/ - >重定向/ en / # /语言

And when you choose the German language?

当你选择德语的时候?

/en-gb/#/language redirect ../de/#/menu -> /de/#/menu

/ en / # /语言重定向。/德/ # /菜单- > /德/ # /菜单

Directory structure:

目录结构:

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

Test:

测试:

(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/');
            });
        });

    });

}());

Locale index.html using minified files:

语言环境指数。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 个解决方案

#1


2  

I occasionally run into issues with non-Angular login pages (some of which have several steps). I think your language selection page might be similar. The solution is a bit of logic in your tests, combined with the exposed Webdriver API in browser.driver.

我偶尔会遇到非角登录页面的问题(有些有几个步骤)。我认为你的语言选择页面可能是相似的。解决方案是在您的测试中加入了一些逻辑,并结合了浏览器.driver中公开的Webdriver API。

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

The best conditions to test are:

测试的最佳条件是:

  1. Test if some unique element is displayed.
  2. 测试是否显示了一些惟一的元素。
  3. Get the URL of the current page and compare it to an expected value.
  4. 获取当前页面的URL并将其与预期值进行比较。

And use browser.driver any time you're not on an Angular page, because it bypasses Protractor. Otherwise, Protractor will look for Angular, fail to find it, and throw errors. Everything you can do with browser.driver can be found here, in the lower regions of the menu: http://angular.github.io/protractor/#/api

和使用浏览器。当你不在一个有棱角的页面上时,它会绕过量角器。否则,量角器会寻找角度,找不到它,并抛出错误。你可以用浏览器做的一切。在这里可以找到驱动程序,在菜单的下半部分:http://angular.github.io/protractor/#/api

Then, in order to wait for your Angular page to show up before you use Protractor, try this snippet:

然后,为了在使用量角器之前等待角化页面显示,请尝试以下代码片段:

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.');

This is particularly useful in your onPrepare statement (just add return to the very beginning, before browser.driver.wait). The test will wait for your Angular page to load, after which you can Protractor around to your heart's content.

这在onPrepare语句中特别有用(只需在开始时添加return,然后浏览.driver.wait)。测试将等待你的角页加载,然后你可以在你的心的内容上量角器。

With a bit of messing around, this same snippet can be used to react to multi-step non-Angular introductory pages. And, encapsulated into its own neat little function, this can be reused anywhere that Protractor is liable to get dumped onto a non-Angular page.

稍微有点混乱,同样的片段可以用于对多步非角入门页面做出反应。并且,封装到它自己的整洁的小函数中,它可以在任何量角器容易被丢弃到无角页面的地方被重用。

#1


2  

I occasionally run into issues with non-Angular login pages (some of which have several steps). I think your language selection page might be similar. The solution is a bit of logic in your tests, combined with the exposed Webdriver API in browser.driver.

我偶尔会遇到非角登录页面的问题(有些有几个步骤)。我认为你的语言选择页面可能是相似的。解决方案是在您的测试中加入了一些逻辑,并结合了浏览器.driver中公开的Webdriver API。

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

The best conditions to test are:

测试的最佳条件是:

  1. Test if some unique element is displayed.
  2. 测试是否显示了一些惟一的元素。
  3. Get the URL of the current page and compare it to an expected value.
  4. 获取当前页面的URL并将其与预期值进行比较。

And use browser.driver any time you're not on an Angular page, because it bypasses Protractor. Otherwise, Protractor will look for Angular, fail to find it, and throw errors. Everything you can do with browser.driver can be found here, in the lower regions of the menu: http://angular.github.io/protractor/#/api

和使用浏览器。当你不在一个有棱角的页面上时,它会绕过量角器。否则,量角器会寻找角度,找不到它,并抛出错误。你可以用浏览器做的一切。在这里可以找到驱动程序,在菜单的下半部分:http://angular.github.io/protractor/#/api

Then, in order to wait for your Angular page to show up before you use Protractor, try this snippet:

然后,为了在使用量角器之前等待角化页面显示,请尝试以下代码片段:

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.');

This is particularly useful in your onPrepare statement (just add return to the very beginning, before browser.driver.wait). The test will wait for your Angular page to load, after which you can Protractor around to your heart's content.

这在onPrepare语句中特别有用(只需在开始时添加return,然后浏览.driver.wait)。测试将等待你的角页加载,然后你可以在你的心的内容上量角器。

With a bit of messing around, this same snippet can be used to react to multi-step non-Angular introductory pages. And, encapsulated into its own neat little function, this can be reused anywhere that Protractor is liable to get dumped onto a non-Angular page.

稍微有点混乱,同样的片段可以用于对多步非角入门页面做出反应。并且,封装到它自己的整洁的小函数中,它可以在任何量角器容易被丢弃到无角页面的地方被重用。