2017-08-24 39 views
1

我使用量角器&黄瓜框架自动化角4应用程序。函数在5000毫秒后超时 - 角4 - 量角器和黄瓜

获取单击按钮的错误。 (不是所有的时间)

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我认为没有必要设置等待时间为量角器有足够的智能如下解决的承诺

我的项目的详细信息:

节点:v6.10.3 量角器: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(它的一部分)

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

感谢推进

修订版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, 
Css, 
Id, 
Js, 
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; 
    } 
} 
} 

回答

1

两件事情:

1)请务必在使用量角器与async/await时禁用WebDriver Control Flow通过以下指挥官d在配置:

SELENIUM_PROMISE_MANAGER: false 

这里的财产从官方文档规范:

启用/禁用webdriver的控制流。 WebDriverJS(以及扩展,量角器)使用控制流程来管理命令执行的顺序,并且承诺解决了 (详情请参阅docs/control-flow.md)。 然而,由于语法像async/await正在引入,WebDriverJS有 决定弃用控制流程,并让用户(了解详情: https://github.com/SeleniumHQ/selenium/issues/2969)管理 异步活动本身。 目前,默认情况下,WebDriver控制流仍处于启用状态。您可以通过将环境变量 SELENIUM_PROMISE_MANAGER设置为0来禁用它。在Q4 2017的webdriver发行版中,默认情况下,控制流程将被禁用,但您将通过SELENIUM_PROMISE_MANAGER设置为 1而使 可以重新启用。稍后,控制流程将被移除,对于 好。如果你不喜欢管理环境变量, 可以在你的配置文件中设置这个选项,量角器将 为你启用/禁用控制流。设置此 选项的优先级高于环境变量的SELENIUM_PROMISE_MANAGER 。 @type {布尔=}

2)你肯定节点6.10.3支持async/await?我记得async/await的官方默认支持是自从节点7.6

+0

评论AR e不适合长时间讨论;这个对话已经[在聊天中存档](http://chat.stackoverflow.com/rooms/153004/discussion-on-answer-by-quirimmo-function-timed-out-after-5000-milliseconds-an)。 –

0

对我来说,(我没有使用异步/等待),我使用

SELENIUM_PROMISE_MANAGER: true, 
在protractor.conf.js

在我hooks.ts,我需要的两者之一:

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); 
    }); 

这里是我的导入:

import { Before, After, BeforeAll, defineSupportCode, Status, setDefaultTimeout } from 'cucumber';