量角器测试没有明显的原因:“等待异步Angular任务完成超时”

时间:2018-04-04 20:35:08

标签: angular protractor end-to-end

自上周一(2018-03-26)以来,我的量角器测试被打破了,我不知道为什么。他们上次工作(并成功通过)是在此之前的星期五 -  2018-03-23

如何调试此问题?我尝试了很多东西,没有想法......

错误输出

$ npm run e2e

> myproj-spa@0.0.0 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

> myproj-spa@0.0.0 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)

我尝试了什么

❗将webdriver-manager降级为先前版本(2.36和2.35):

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

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

❗将Google Chrome浏览器降级为之前的版本Version 64.0.3282.140 (Official Build) (64-bit)

❗将应用程序中的所有NPM软件包升级到最新版本(请参阅下面的package.json)。

问题仍然存在。

有趣的是,身份验证代码可以运行(来自protractor.conf.js的身份验证代码)。它的Protractor代码稍后会失败......

源代码

E2E-工作台-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-工作台-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'));
    }

}

输入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

<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"
  }
}

1 个答案:

答案 0 :(得分:1)

  

在执行任何操作之前,Protractor会等待您的Angular应用程序中没有待处理的异步任务。这意味着所有超时和http请求都已完成。资料来源:angular/protractor documentation

队友最近添加了一些新代码(我不知道)。该代码正在做一些setInterval()的事情,这使得Protractor无法检测到Angular&#34;准备就绪&#34;工作。