webdriverio-boneyard / wdio-cucumber-framework

A WebdriverIO v4 plugin. Adapter for Cucumber testing framework.
MIT License
77 stars 61 forks source link

Step retries lose world context #37

Open si-mikey opened 8 years ago

si-mikey commented 8 years ago

The Problem

When a retry is kicked off the functions that were added to the World are no longer available on. They are available in the first run ( as retry has not been kicked off) when the retry happens it looks like it removes the World context from the step definitions.

// worldjs
const expect = require('chai').expect;
const fixedUsers = require('../../../lib/fixtures/fixture.users');
const routes = require('../../../config/dist/routes');
const Brain = require('../../../lib/tools/dist/brain');
const users = require('../../../lib/api/dist/users');

function World () {
  this.fixedUsers = fixedUsers;
  this.expect = expect;
  this.routes = routes;
  this.brain = new Brain();
  this.users = users;
};

module.exports = function () {
  this.World = World;
};
//step defs
this.Given(/^some step definition$/, { retry: 2 }, () => {
        // Access to this.expect and others on runs run, 
        // when retry happens because something failed 
        // then the methods from world are undefined
    })

wdio-cuucmber-framework version: 0.2.5 wdio version: 4.2.11 cucumber version: 1.2.2

shkaper commented 8 years ago

Happened for me, too. Any workaround for this one?

si-mikey commented 8 years ago

The line below seems to be related https://github.com/webdriverio/wdio-cucumber-framework/blob/004a1a25a2eae80788dd8ee50fc03abe171a42d3/lib/adapter.js#L83

si-mikey commented 7 years ago

Any updates?

si-mikey commented 7 years ago

@shkaper the work around I found for this was to store any function / class instances in some custom object inside of the browser object. You would do this in a beforeScenario hook so it gets refreshed on every scenario. So something like this,

    beforeScenario: function (scenario) {
      browser['tools'] = {};
      browser['tools']['stuffInstance'] = new Stuff();
    }

This will ensure you never use the below in your step defs.

this.stuffInstance...

Instead

browser['tools']['stuffInstance'].someMethod
christian-bromann commented 7 years ago

Can someone provide a reproducible example?

si-mikey commented 7 years ago

@christian-bromann below is code to reproduce the error.
world.js

function fooBar() {
   this.getValue = function() {
     return  'FooBar';
   }
}

function World () {
   this.fooBar = new fooBar();
};

module.exports = function () {
  this.World = World;
};

step_defs.js

this.Given(/^I call a world function with a retry$/, { retry: 1 }, function() {
   var foobar = this.fooBar.getValue();
   console.log(foobar);
   // Triggger a failure so retry is ran
  throw new Error('BOOM!');
})

test.feature

Feature: Retry test suite

 Scenario: retrying step def should retain world context
   Given I call a world function with a retry

The above code will run fine the first time, the second time because of retry 1

 this.fooBar.getValue();

Will return undefined. More specifically this.fooBar is undefined.