量角器测试无缘无故中断

量角器测试无缘无故中断

本文介绍了量角器测试无缘无故中断:“等待异步 Angular 任务完成超时"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的量角器测试从上周一 (2018-03-26) 开始就坏了,我不知道为什么.他们上次工作(并成功通过)是在那之前的星期五——2018-03-23.

我该如何调试这个问题?我尝试了很多东西,但没有任何想法......

错误输出

$ npm run e2e>[email protected] pree2e C:\W\cp\myproj\myproj.SPA>webdriver-manager update --standalone false --gecko false[12:54:20] I/update - chromedriver: 文件存在 C:\W\cp\myproj\myproj.SPA\node_modules\protractor\node_modules\webdriver-manager\selenium\chromedriver_2.37.zip[12:54:20] I/更新 - chromedriver:解压 chromedriver_2.37.zip[12:54:21] I/update - chromedriver: chromedriver_2.37.exe 是最新的>[email protected] e2e C:\W\cp\myproj\myproj.SPA>量角器(节点:13492)[DEP0022] 弃用警告:不推荐使用 os.tmpDir().使用 os.tmpdir() 代替.[12:54:27] I/launcher - 运行 1 个 WebDriver 实例[12:54:27] I/direct - 直接使用 ChromeDriver...DevTools 监听 ws://127.0.0.1:12867/devtools/browser/b73e368c-ac7f-407a-890d-24fbb6f0c4c9[11912:8644:0404/125435.389:ERROR:shader_disk_cache.cc(238)] 未能创建着色器缓存条目:-2[11912:8644:0404/125435.390:ERROR:shader_disk_cache.cc(238)] 未能创建着色器缓存条目:-2[11912:8644:0404/125435.390:ERROR:shader_disk_cache.cc(238)] 未能创建着色器缓存条目:-2茉莉花开始2018-04-04T12:54:40.566 [警告] http://localhost:13403/#/- WebSocket 连接到ws://localhost:13403/sockjs-node/534/0y0ajoq5/websocket"失败:WebSocket 已关闭在建立连接之前.可重用组件工作台× 用零值覆盖非零值不应擦除输入数字字段- 失败:等待异步 Angular 任务在 11 秒后完成超时.这可能是因为当前页面不是 Angular 应用程序.有关更多详细信息,请参阅常见问题解答:https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular在等待带有定位器的元素时 - Locator: By(css selector, *[id="inputNumber1"])(会话信息:chrome=64.0.3282.140)(驱动程序信息:chromedriver=2.37.540470(e522d04694c7ebea4ba8821272dbef4f9b818c91),平台=Windows NT 6.1.7601 SP1 x86_64)在 Object.checkLegacyResponse (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\error.js:546:15)在 parseHttpResponse (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\http.js:509:13)在 doSend.then.response (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\http.js:441:30)在<匿名>在 process._tickCallback (internal/process/next_tick.js:188:7)来自:任务:Protractor.waitForAngular() - 定位器:By(css selector, *[id="inputNumber1"])在 Driver.schedule (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\webdriver.js:807:17)在 ProtractorBrowser.executeAsyncScript_ (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\browser.js:425:28)在 angularAppRoot.then (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\browser.js:456:33)在 ManagedPromise.invokeCallback_ (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:1376:14)在 TaskQueue.execute_ (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:3084:14)在 TaskQueue.executeNext_ (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:3067:27)在 asyncRun (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:2927:27)在 C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:668:7在<匿名>在 process._tickCallback (internal/process/next_tick.js:188:7) 错误在 ElementArrayFinder.applyAction_ (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\element.js:459:27)在 ElementArrayFinder.(anonymous function).args [as getAttribute] (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\element.js:91:29)在 ElementFinder.(anonymous function).args [as getAttribute] (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\element.js:831:22)在 Function.Page.getInputText (C:\W\cp\myproj\myproj.SPA\e2e\dom-wrappers\page.ts:75:22)在 InputNumberWrapper.get [as text] (C:\W\cp\myproj\myproj.SPA\e2e\dom-wrappers\input-number.wrapper.ts:11:21)在 UserContext.(C:\W\cp\myproj\myproj.SPA\e2e\e2e-workbench-page.e2e-spec.ts:16:43)在新的 ManagedPromise (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:1077:7)在 ControlFlow.promise (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:2505:12)来自:任务:在控制流中运行拟合(用零值覆盖非零值不应擦除输入数字字段")从异步测试:错误(C:\W\cp\myproj\myproj.SPA\e2e\e2e-workbench-page.e2e-spec.ts:15:5)在对象(C:\W\cp\myproj\myproj.SPA\e2e\e2e-workbench-page.e2e-spec.ts:4:1)在 Module._compile (module.js:635:30)在 Module.m._compile (C:\W\cp\myproj\myproj.SPA\node_modules\ts-node\src\index.ts:392:23)在 Module._extensions..js (module.js:646:10)在 Object.require.extensions.(anonymous function) [as .ts] (C:\W\cp\myproj\myproj.SPA\node_modules\ts-node\src\index.ts:395:12)

我尝试了什么

❗ 将 webdriver-manager 降级到之前的版本(2.36 和 2.35):

webdriver-manager update --standalone false --gecko false --versions.chrome 2.36

❗检出之前通过测试的代码(由 CI 服务器证明)到另一台机器上的新 repo 克隆.

❗将谷歌Chrome浏览器降级到之前的版本Version 64.0.3282.140 (Official Build) (64-bit).

❗ 将应用中的所有 NPM 包升级到最新最好的版本(见下面的package.json).

问题仍然存在.

有趣的是,身份验证代码有效(来自 protractor.conf.js 的代码).这是后来失败的量角器代码......

源代码

e2e-workbench-page.e2e-spec.ts

import { E2EWorkbenchPageWrapper } from './dom-wrappers/e2e-workbench-page.wrapper';从'./dom-wrappers/page'导入{页面};描述('可重用组件工作台',函数(){让工作台页面:E2EWorkbenchPageWrapper;beforeAll(() => {workbenchPage = new E2EWorkbenchPageWrapper();workbenchPage.navigateTo();});afterEach(() => Page.standardAfterEach());fit(`用零值覆盖非零值不应擦除输入数字字段`, () => {expect(workbenchPage.inputNumber1.text).toBe('', '输入数字默认为空');workbenchPage.inputNumber1.setText('8');workbenchPage.inputNumber1.setText('0');expect(workbenchPage.inputNumber1.text).toBe('0.0000', '输入数字应该有一个正确格式的值.');});});

e2e-workbench-page.wrapper.ts

import { promise as wdpromise } from 'selenium-webdriver';import { InputNumberWrapper } from './input-number.wrapper';从'./page'导入{页面};导出类 E2EWorkbenchPageWrapper {导航到():wdpromise.Promise{return Page.navigateToRelativeAngularRoute('e2e-workbench');}获取 inputNumber1(): InputNumberWrapper {return new InputNumberWrapper(Page.getInputById('inputNumber1'));}}

input-number.wrapper.ts

import { by, ElementFinder } from 'protractor';导入 { promise as wdpromise } from 'selenium-webdriver';从'./page'导入{页面};导出类 InputNumberWrapper {构造函数(私有_elementFinder:ElementFinder){}获取文本():wdpromise.Promise{返回 Page.getInputText(this.inputElementFinder);}setText(text: string): wdpromise.Promise{返回 Page.setInputText(this.inputElementFinder, text);}焦点():wdpromise.Promise{返回 Page.focusOnNonButtonElement(this.inputElementFinder);}私人获取 inputElementFinder(): ElementFinder {返回 this._elementFinder.all(by.css('.form-control')).get(0);}}

执行测试的页面的 HTML

<身体><myproj-root _nghost-c0=""ng-version="4.4.6"><!-- 一些 html...--><div _ngcontent-c0=""><router-outlet _ngcontent-c0=""></router-outlet><myproj-e2e-workbench class=""><div class="row"><div class="col-md-3"><input-number class="col-md-6" id="inputNumber1"><div class="input-group has-error"><input type="text" class="form-control ng-invalid"></div></input-number>

<div class="col-md-3"><input-number class="col-md-6" id="inputNumber2"><div class="input-group"><input type="text" class="form-control"></div></input-number>

<!-- 其余的 html --></body></html>

package.json

{"name": "myproj-spa",版本":0.0.0","许可证": "麻省理工学院",角度cli":{},脚本":{"ng": "ng","start": "ng serve --port 13403 --proxy-config proxy.config.json","start-prodish": "ng serve -e prod --port 13403 --proxy-config proxy.config.json","start-prodish-for-e2e": "ng serve -e e2e --port 13403 --proxy-config proxy.config.json","lint": "tslint \"src/**/*.ts\"","test": "ng 测试","pree2e": "webdriver-manager update --standalone false --gecko false","e2e": "量角器"},私人":真的,依赖关系":{"@angular/animations": "^5.2.9","@angular/cdk": "^5.2.4","@angular/common": "^5.2.9","@angular/compiler": "^5.2.9","@angular/core": "^5.2.9","@angular/forms": "^5.2.9","@angular/http": "^5.2.9","@angular/material": "^5.2.4","@angular/platform-b​​rowser": "^5.2.9","@angular/platform-b​​rowser-dynamic": "^5.2.9","@angular/router": "^5.2.9","alertifyjs": "^1.11.1","bootstrap": "3.3.7","core-js": "^2.5.4","date-fns": "^1.28.5","fancybox": "^3.0.1","font-awesome": "^4.7.0","jquery": "^3.3.1","ngx-ssrs-reportviewer": "^1.0.2","rxjs": "5.5.2","ts-helpers": "^1.1.2",zone.js":^0.8.24"},开发依赖":{"@angular/cli": "^1.7.3","@angular/compiler-cli": "^5.2.9","@types/date-fns": "^2.6.0","@types/jasmine": "2.8.6","@types/node": "^9.6.1","jasmine-core": "^3.1.0","jasmine-spec-reporter": "^4.2.1","karma": "^2.0.0","karma-chrome-launcher": "^2.2.0","karma-cli": "^1.0.1","karma-coverage-istanbul-reporter": "^1.4.2","karma-jasmine": "^1.1.0","karma-jasmine-html-reporter": "^1.0.0","量角器": "^5.3.0","protractor-jasmine2-html-reporter": "0.0.7","ts-node": "^5.0.1","tslint": "^5.7.0",打字稿":^2.8.1"}}
解决方案

队友最近添加了一些新代码(我不知道).这段代码做了一些 setInterval() 的事情,阻止了 Protractor 检测到 Angular 的准备工作".

My Protractor tests are broken since last Monday (2018-03-26) and I don't know why. Last time they worked (and successfully passed) was Friday before that -- 2018-03-23.

How do I debug this issue? I tried so many things and ran out of ideas...

Error output

$ npm run e2e

> [email protected] pree2e C:\W\cp\myproj\myproj.SPA
> webdriver-manager update --standalone false --gecko false

[12:54:20] I/update - chromedriver: file exists C:\W\cp\myproj\myproj.SPA\node_modules\protractor\node_modules\webdriver-manager\selenium\chromedriver_2.37.zip
[12:54:20] I/update - chromedriver: unzipping chromedriver_2.37.zip
[12:54:21] I/update - chromedriver: chromedriver_2.37.exe up to date

> [email protected] e2e C:\W\cp\myproj\myproj.SPA
> protractor

(node:13492) [DEP0022] DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead.
[12:54:27] I/launcher - Running 1 instances of WebDriver
[12:54:27] I/direct - Using ChromeDriver directly...

DevTools listening on ws://127.0.0.1:12867/devtools/browser/b73e368c-ac7f-407a-890d-24fbb6f0c4c9
[11912:8644:0404/125435.389:ERROR:shader_disk_cache.cc(238)] Failed to create shader cache entry: -2
[11912:8644:0404/125435.390:ERROR:shader_disk_cache.cc(238)] Failed to create shader cache entry: -2
[11912:8644:0404/125435.390:ERROR:shader_disk_cache.cc(238)] Failed to create shader cache entry: -2
Jasmine started
2018-04-04T12:54:40.566 [WARNING] http://localhost:13403/#/ - WebSocket connection to 'ws://localhost:13403/sockjs-node/534/0y0ajoq5/websocket' failed: WebSocket is closed before the connection is established.


Reusable Component Workbench
    × overriding non-zero value with zero value should not erase input-number field
    - Failed: Timed out waiting for asynchronous Angular tasks to finish after 11 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
    While waiting for element with locator - Locator: By(css selector, *[id="inputNumber1"])
        (Session info: chrome=64.0.3282.140)
        (Driver info: chromedriver=2.37.540470 (e522d04694c7ebea4ba8821272dbef4f9b818c91),platform=Windows NT 6.1.7601 SP1 x86_64)
        at Object.checkLegacyResponse (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\error.js:546:15)
        at parseHttpResponse (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\http.js:509:13)
        at doSend.then.response (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\http.js:441:30)
        at <anonymous>
        at process._tickCallback (internal/process/next_tick.js:188:7)
    From: Task: Protractor.waitForAngular() - Locator: By(css selector, *[id="inputNumber1"])
        at Driver.schedule (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\webdriver.js:807:17)
        at ProtractorBrowser.executeAsyncScript_ (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\browser.js:425:28)
        at angularAppRoot.then (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\browser.js:456:33)
        at ManagedPromise.invokeCallback_ (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:1376:14)
        at TaskQueue.execute_ (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:3084:14)
        at TaskQueue.executeNext_ (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:3067:27)
        at asyncRun (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:2927:27)
        at C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:668:7
        at <anonymous>
        at process._tickCallback (internal/process/next_tick.js:188:7)Error
        at ElementArrayFinder.applyAction_ (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\element.js:459:27)
        at ElementArrayFinder.(anonymous function).args [as getAttribute] (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\element.js:91:29)
        at ElementFinder.(anonymous function).args [as getAttribute] (C:\W\cp\myproj\myproj.SPA\node_modules\protractor\built\element.js:831:22)
        at Function.Page.getInputText (C:\W\cp\myproj\myproj.SPA\e2e\dom-wrappers\page.ts:75:22)
        at InputNumberWrapper.get [as text] (C:\W\cp\myproj\myproj.SPA\e2e\dom-wrappers\input-number.wrapper.ts:11:21)
        at UserContext.<anonymous> (C:\W\cp\myproj\myproj.SPA\e2e\e2e-workbench-page.e2e-spec.ts:16:43)
        at new ManagedPromise (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:1077:7)
        at ControlFlow.promise (C:\W\cp\myproj\myproj.SPA\node_modules\selenium-webdriver\lib\promise.js:2505:12)
    From: Task: Run fit("overriding non-zero value with zero value should not erase input-number field") in control flow
    From asynchronous test:
    Error
        at Suite.<anonymous> (C:\W\cp\myproj\myproj.SPA\e2e\e2e-workbench-page.e2e-spec.ts:15:5)
        at Object.<anonymous> (C:\W\cp\myproj\myproj.SPA\e2e\e2e-workbench-page.e2e-spec.ts:4:1)
        at Module._compile (module.js:635:30)
        at Module.m._compile (C:\W\cp\myproj\myproj.SPA\node_modules\ts-node\src\index.ts:392:23)
        at Module._extensions..js (module.js:646:10)
        at Object.require.extensions.(anonymous function) [as .ts] (C:\W\cp\myproj\myproj.SPA\node_modules\ts-node\src\index.ts:395:12)

What I tried

❗ Downgraded the webdriver-manager to the previous version (2.36, and 2.35):

webdriver-manager update --standalone false --gecko false --versions.chrome 2.36


❗ Checked out the code passed the tests before (proven by CI server) to a fresh repo clone on another machine.


❗ Downgraded Google Chrome browser to the previous version Version 64.0.3282.140 (Official Build) (64-bit).


❗ Upgraded all NPM packages in the application to latest and greatest version (see package.json below).


The issue still persists.

Interestingly, the authentication code works (the one from protractor.conf.js). It's Protractor code that fails later on...

Source Code

e2e-workbench-page.e2e-spec.ts

import { E2EWorkbenchPageWrapper } from './dom-wrappers/e2e-workbench-page.wrapper';
import { Page } from './dom-wrappers/page';

describe('Reusable Component Workbench', function () {

    let workbenchPage: E2EWorkbenchPageWrapper;

    beforeAll(() => {
        workbenchPage = new E2EWorkbenchPageWrapper();
        workbenchPage.navigateTo();
    });

    afterEach(() => Page.standardAfterEach());

    fit(`overriding non-zero value with zero value should not erase input-number field`, () => {
        expect(workbenchPage.inputNumber1.text).toBe('', 'Input number should be blank by default');

        workbenchPage.inputNumber1.setText('8');

        workbenchPage.inputNumber1.setText('0');

        expect(workbenchPage.inputNumber1.text).toBe('0.0000', 'Input number should have a properly formatted value.');
    });

});

e2e-workbench-page.wrapper.ts

import { promise as wdpromise } from 'selenium-webdriver';

import { InputNumberWrapper } from './input-number.wrapper';
import { Page } from './page';

export class E2EWorkbenchPageWrapper {

    navigateTo(): wdpromise.Promise<any> {
        return Page.navigateToRelativeAngularRoute('e2e-workbench');
    }

    get inputNumber1(): InputNumberWrapper {
        return new InputNumberWrapper(Page.getInputById('inputNumber1'));
    }

}

input-number.wrapper.ts

import { by, ElementFinder } from 'protractor';
import { promise as wdpromise } from 'selenium-webdriver';

import { Page } from './page';

export class InputNumberWrapper {

    constructor(private _elementFinder: ElementFinder) { }

    get text(): wdpromise.Promise<string> {
        return Page.getInputText(this.inputElementFinder);
    }

    setText(text: string): wdpromise.Promise<void> {
        return Page.setInputText(this.inputElementFinder, text);
    }

    focus(): wdpromise.Promise<void> {
        return Page.focusOnNonButtonElement(this.inputElementFinder);
    }

    private get inputElementFinder(): ElementFinder {
        return this._elementFinder.all(by.css('.form-control')).get(0);
    }
}


HTML of the page against which the tests are executed

<html class=""><head>
<body>
<myproj-root _nghost-c0="" ng-version="4.4.6">

<!-- Some html... -->

<div _ngcontent-c0="">
    <router-outlet _ngcontent-c0=""></router-outlet><myproj-e2e-workbench class=""><div class="row">
    <div class="col-md-3">
        <input-number class="col-md-6" id="inputNumber1"><div class="input-group has-error">

        <input type="text" class="form-control ng-invalid">
    </div></input-number>
    </div>
    <div class="col-md-3">
        <input-number class="col-md-6" id="inputNumber2"><div class="input-group">

        <input type="text" class="form-control">
        </div></input-number>
    </div>
</div>

<!-- Rest of html -->

</body></html>

package.json

{
  "name": "myproj-spa",
  "version": "0.0.0",
  "license": "MIT",
  "angular-cli": {},
  "scripts": {
    "ng": "ng",
    "start": "ng serve --port 13403 --proxy-config proxy.config.json",
    "start-prodish": "ng serve -e prod --port 13403 --proxy-config proxy.config.json",
    "start-prodish-for-e2e": "ng serve -e e2e --port 13403 --proxy-config proxy.config.json",
    "lint": "tslint \"src/**/*.ts\"",
    "test": "ng test",
    "pree2e": "webdriver-manager update --standalone false --gecko false",
    "e2e": "protractor"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^5.2.9",
    "@angular/cdk": "^5.2.4",
    "@angular/common": "^5.2.9",
    "@angular/compiler": "^5.2.9",
    "@angular/core": "^5.2.9",
    "@angular/forms": "^5.2.9",
    "@angular/http": "^5.2.9",
    "@angular/material": "^5.2.4",
    "@angular/platform-browser": "^5.2.9",
    "@angular/platform-browser-dynamic": "^5.2.9",
    "@angular/router": "^5.2.9",
    "alertifyjs": "^1.11.1",
    "bootstrap": "3.3.7",
    "core-js": "^2.5.4",
    "date-fns": "^1.28.5",
    "fancybox": "^3.0.1",
    "font-awesome": "^4.7.0",
    "jquery": "^3.3.1",
    "ngx-ssrs-reportviewer": "^1.0.2",
    "rxjs": "5.5.2",
    "ts-helpers": "^1.1.2",
    "zone.js": "^0.8.24"
  },
  "devDependencies": {
    "@angular/cli": "^1.7.3",
    "@angular/compiler-cli": "^5.2.9",
    "@types/date-fns": "^2.6.0",
    "@types/jasmine": "2.8.6",
    "@types/node": "^9.6.1",
    "jasmine-core": "^3.1.0",
    "jasmine-spec-reporter": "^4.2.1",
    "karma": "^2.0.0",
    "karma-chrome-launcher": "^2.2.0",
    "karma-cli": "^1.0.1",
    "karma-coverage-istanbul-reporter": "^1.4.2",
    "karma-jasmine": "^1.1.0",
    "karma-jasmine-html-reporter": "^1.0.0",
    "protractor": "^5.3.0",
    "protractor-jasmine2-html-reporter": "0.0.7",
    "ts-node": "^5.0.1",
    "tslint": "^5.7.0",
    "typescript": "^2.8.1"
  }
}
解决方案

There was some new code a teammate has added recently (which I was not aware of). That code was doing some setInterval() stuff which prevented Protractor from detecting Angular's "readyness" to work.

这篇关于量角器测试无缘无故中断:“等待异步 Angular 任务完成超时"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 16:02