Испытания транспортира были прерваны без видимой причины: "Истекло время ожидания выполнения асинхронных угловых задач"
Мои тесты транспортира не работают с прошлого понедельника (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)
Что я пробовал
❗ Понизил версию менеджера веб-драйверов до предыдущей версии (2.36 и 2.35):
webdriver-manager update --standalone false --gecko false --versions.chrome 2.36
❗ Проверен код, прошедший тестирование ранее (проверено сервером CI) для нового клона репо на другой машине.
❗ Понизился браузер 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 ответ
Перед выполнением какого-либо действия Protractor ждет, пока в приложении Angular не будет отложенных асинхронных задач. Это означает, что все таймауты и http-запросы завершены. Источник: угловая / транспортирная документация
Недавно был добавлен новый код, добавленный товарищем по команде (о котором я не знал). Этот код делал некоторые setInterval()
вещи, которые не позволили Транспортиру определить "готовность" Angular к работе.