Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
285 views
in Technique[技术] by (71.8m points)

javascript - Protractor Cucumber BDD Tests Show Pass before Execution

I have a sample BDD test using Protractor with Cucumber. On executing the code, the console immediately shows the result as passed and the code actually begins executing only after that.

I wish execution status display to be in sync with actual execution.(e.g Console displays - 'Given I launch the protractor demo page' and the code underneath is executed, then console displays next step and so on) I know it has got something to do with Async coding and callbacks, not able to figure out the exact problem though.

Feature file:

Feature: Test
Scenario:  Test Scenario
    Given I launch the protractor demo page
    When I enter two in the first field
    And I enter three in the second field
    And I click Go button
    Then Result should be displayed as Five

Step File:

 var chai = require('chai');
    var chaiAsPromised = require('chai-as-promised');
    chai.use(chaiAsPromised);
    var expect = chai.expect;

    module.exports = function () {


        this.Given(/^I launch the protractor demo page$/, function (callback) {
            browser.driver.manage().window().maximize();
            browser.get('http://juliemr.github.io/protractor-demo/');

            browser.getTitle().then(function(text){
               console.log('title is - ' + text);
                expect(text).to.equal('Super Calculator');
            });
         callback();
        });

        this.When(/^I enter two in the first field$/, function (callback) {
            element(by.model('first')).sendKeys('2');
            callback();
        });

        this.When(/^I enter three in the second field$/, function (callback) {
            element(by.model('second')).sendKeys('3');
            callback();
        });

        this.When(/^I click Go button$/, function (callback) {
            element(by.id('gobutton')).click();
            callback();
        });

        this.Then(/^Result should be displayed as Five$/, function (callback) {
             element(by.repeater('result in memory')).all(by.tagName('td')).get(2).getText().then(function(text){
            expect(text).to.equal('5');
            });
            callback();
        });

    };
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to either return a promise or use the done callback in your step definitions. Otherwise cucumber doesn't know when your asynchronous actions are complete.

I had the same question and above statement was the response from one of the core members of the protractor-cucumber github forum.

I prefer to return promises when I am performing some actions on the results with .then function and use .done callback function when I am not, Also you don't need callbacks now CucumberJS supports promises. So your step file should look like -

var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;

module.exports = function () {


    this.Given(/^I launch the protractor demo page$/, function () {
        browser.driver.manage().window().maximize();
        browser.get('http://juliemr.github.io/protractor-demo/');

      return browser.getTitle().then(function(text){
           console.log('title is - ' + text);
            expect(text).to.equal('Super Calculator');
        });
    });

    this.When(/^I enter two in the first field$/, function () {
       return element(by.model('first')).sendKeys('2'); 
    });

    this.When(/^I enter three in the second field$/, function () {
       return element(by.model('second')).sendKeys('3'); // you can use return also
    });

    this.When(/^I click Go button$/, function () {
        return element(by.id('gobutton')).click();
    });

    this.Then(/^Result should be displayed as Five$/, function () {
        return element(by.repeater('result in memory')).all(by.tagName('td')).get(2).getText().then(function(text){
        expect(text).to.equal('5');
        });

    });

};

I would recommend you to read about Promises http://www.html5rocks.com/en/tutorials/es6/promises/ as it requires some understanding how they behave.They can be sometimes tricky, it took me a while to get an idea still I have lot to learn :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...