【问题标题】:function timed out after 5000 milliseconds - Angular 4 - Protractor & cucumber功能在 5000 毫秒后超时 - Angular 4 - 量角器和黄瓜
【发布时间】:2017-08-24 03:50:20
【问题描述】:

我正在使用量角器和黄瓜框架自动化 Angular 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" 
    }
 };

提前致谢

2017 年 8 月 28 日更新:

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

【问题讨论】:

    标签: angular typescript protractor cucumber


    【解决方案1】:

    黄瓜的默认超时为 5 秒。 Setting default time(至 10 秒)为我工作。 Example is here。此问题可能是因为应用程序已关闭。

    @quirimmo 感谢您的支持。

    【讨论】:

      【解决方案2】:

      对我来说,(我没有使用 async/await),我正在使用

       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';
      

      【讨论】:

      • hooks.ts 文件应该放在哪里?是否只是需要 cucumberOpts 中的文件的情况?
      • 刚刚将它添加到我的需求数组中,它找到了它
      • BeforeAll 中的 setDefaultTimeout 为我解决了这个问题
      【解决方案3】:

      两件事:

      1) 使用带有async/await 的量角器时,请务必通过配置中的以下命令禁用WebDriver Control Flow

      SELENIUM_PROMISE_MANAGER: false
      

      这里是官方文档中的属性规范:

      启用/禁用 WebDriver 控制流。 WebDriverJS(以及扩展,量角器)使用控制流来 管理执行命令和承诺的顺序 已解决(有关详细信息,请参阅 docs/control-flow.md)。 但是,由于引入了 async/await 之类的语法,WebDriverJS 具有 决定弃用控制流,并让用户管理 异步活动本身(此处的详细信息: https://github.com/SeleniumHQ/selenium/issues/2969)。 目前,WebDriver 控制流仍默认启用。你 可以通过设置环境变量来禁用它 SELENIUM_PROMISE_MANAGER0。在第四季度的 webdriver 版本中 2017,默认情况下将禁用控制流,但您将 能够通过将SELENIUM_PROMISE_MANAGER 设置为重新启用它 1。稍后,将删除控制流 好的。如果你不喜欢管理环境变量,你 可以在你的配置文件中设置这个选项,Protractor 会 为您处理启用/禁用控制流。设置这个 选项的优先级高于SELENIUM_PROMISE_MANAGER 环境变量。 @type {boolean=}

      2) 你确定 Node 6.10.3 支持async/await 吗?我记得官方默认支持async/await是从Node 7.6开始

      【讨论】:

      猜你喜欢
      • 2019-07-16
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 2017-02-02
      • 1970-01-01
      相关资源
      最近更新 更多