Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I am automating an angular 4 application with protractor & cucumber framework.
Getting error for a simple button click. (Not all the times)
1) Scenario: Scenario 2 - features\Home.feature:9
Step: Then Click on edit button - features\Home.feature:11
Step Definition: stepDefinitions\FirstStep.ts:31
Message:
Error: function timed out after 5000 milliseconds
at Timeout.<anonymous> (C:\MyWorkspace\protractor-cucumber-final\protractor-cucumber-final\node_modules\cucumber\lib\user_code_runner.js:91:22)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)
Checked here I believe no need to set wait times as protractor is intelligent enough to resolve promises
my project details as follows:
Node: v6.10.3
protractor: v5.1.2
StepDefinition.ts:
let homePage = new HomePage();
Then(/^Click on edit button$/, async () => {
await homePage.clickEditButton();
HomePage.ts:
async clickEditButton() {
console.log('clicking on Edit Button');
await this.editButton.click();
package.json (part of it)
"main": "index.js",
"scripts": {
"test": "protractor config/config.js",
"webdriver-start": "webdriver-manager start",
"webdriver-update": "webdriver-manager update"
"dependencies": {
"chai": "^4.0.2",
"cucumber": "^2.3.0",
"mkdirp": "^0.5.1",
"protractor": "^5.1.1",
"protractor-cucumber-framework": "^3.1.0"
"devDependencies": {
"chai-as-promised": "^6.0.0",
"cucumber-html-report": "^0.6.0",
"cucumber-html-reporter": "^0.5.2",
"cucumberjs-allure-reporter": "^1.0.3",
"pg": "^6.0.3"
config.js
var chai = require("chai");
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
exports.config = {
seleniumAddress: "http://localhost:4444/wd/hub",
baseUrl: "http://localhost:4200/",
framework: "custom",
frameworkPath: require.resolve("protractor-cucumber-framework"),
specs: ["../features/*.feature"],
exclude: "../features/database.feature",
resultJsonOutputFile: "./reports/json/protractor_report.json",
onPrepare: function() {
// browser.ignoreSynchronization = true;
browser.manage().window().maximize();
global.expect = chai.expect;
cucumberOpts: {
strict: true,
format: ["pretty"],
require: ["../stepDefinitions/*.js", "../support/*.js"],
tags: "@micro"
Thanks in advance
UPDATED 28-Aug'17:
ManageRecipeStep.ts
import {defineSupportCode} from 'cucumber';
import {ManageRecipePage} from "../pages/ManageRecipePage";
var chai = require("chai");
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
let expect = chai.expect;
Then(/^Cancel button should be displayed$/, async () => {
await expect(manageRecipePage.getCancelButton()).to.eventually.equal('Cancel');
ManageRecipePage.ts
import {ActionUtil} from "../utils/ActionUtil";
import {BasePage, IdentificationType} from "../utils/BasePage";
const Locators = {
cancelByText: {
type:IdentificationType[IdentificationType.PartialButtonText],
value: "Cancel"
let actionUtil = new ActionUtil();
export class ManageRecipePage extends BasePage {
async getCancelButton() {
await actionUtil.getElementText(Locators.cancelByText);
ActionUtil.ts
import {BasePage} from "./BasePage";
export class ActionUtil {
private basePage: BasePage = new BasePage();
async getElementText(obj) {
let attempts = 0;
while(attempts < 2) {
try {
return await this.basePage.ElementLocator(obj).getText();
} catch(StaleElementException) {
console.log("EXCEPTION while getting Text" + StaleElementException);
attempts++;
return null; // todo: this case
BasePage.ts
import { browser, element, by, protractor, $$, $ } from 'protractor';
export enum IdentificationType {
Xpath,
Name,
PartialLinkText,
ClassName,
PartialButtonText
export class BasePage {
ElementLocator(obj) {
switch (obj.type) {
case IdentificationType[IdentificationType.Xpath]:
return element(by.xpath(obj.value));
case IdentificationType[IdentificationType.ClassName]:
return element(by.className(obj.value));
case IdentificationType[IdentificationType.Id]:
return element(by.id(obj.value));
case IdentificationType[IdentificationType.Js]:
return element(by.js(obj.value));
case IdentificationType[IdentificationType.Css]:
return element(by.css(obj.value));
case IdentificationType[IdentificationType.PartialButtonText]:
return element(by.partialButtonText(obj.value));
default:
break;
Default timeout for cucumber is 5 sec. Setting default time (to 10 sec) worked for me. Example is here. This issue might be because application is down.
@quirimmo Thanks for your support.
BeforeAll({ timeout: 60 * 1000 }, () => {
setDefaultTimeout(60 * 1000);
return browser.get(config.baseUrl);
BeforeAll({ timeout: 60 * 1000 }, () => {
defineSupportCode( ({ setDefaultTimeout }) => {
setDefaultTimeout(60 * 1000);
return browser.get(config.baseUrl);
Here is my import:
import { Before, After, BeforeAll, defineSupportCode, Status, setDefaultTimeout } from 'cucumber';
–
Two things:
1) Be sure to disable the WebDriver Control Flow
when using protractor with async/await
through the following command in the config:
SELENIUM_PROMISE_MANAGER: false
Here the spec of the property from the official doc:
Enable/disable the WebDriver Control Flow.
WebDriverJS (and by extention, Protractor) uses a Control Flow to
manage the order in which commands are executed and promises are
resolved (see docs/control-flow.md for details).
However, as syntax like async
/await
are being introduced, WebDriverJS has
decided to deprecate the control flow, and have users manage the
asynchronous activity themselves (details here:
https://github.com/SeleniumHQ/selenium/issues/2969).
At the moment, the WebDriver Control Flow is still enabled by default. You
can disable it by setting the environment variable
SELENIUM_PROMISE_MANAGER
to 0
. In a webdriver release in Q4
2017, the Control Flow will be disabled by default, but you will be
able to re-enable it by setting SELENIUM_PROMISE_MANAGER
to
1
. At a later point, the control flow will be removed for
good. If you don't like managing environment variables, you
can set this option in your config file, and Protractor will
handle enabling/disabling the control flow for you. Setting this
option is higher priority than the SELENIUM_PROMISE_MANAGER
environment variable.
@type {boolean=}
2) Are you sure that Node 6.10.3 supports async/await
? I remember that the official default support for async/await
is since Node 7.6
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.