Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

World object in cucumber.js or where to put state in cucumber tests

I'm trying to save the current navigation state in one step (the page on a platform with multiple websites) in cucumber.js so the following steps of a scenario can deal with it. I thought using the World object for it, but mysterious things are happening.

I have a navigation state object like this:

module.exports = {
    pageName:null,
    siteName: null,
    isLoggedIn: false
}

Then I have a NavigationStateManager like this

function NavigationStateManager() {
    var state
    this.setState = function(stateP) {
       state = stateP
    }
    this.setPage = function(pageNameP, siteNameP, isLoggedInP) {
        // among other things do something link this:
        state.pageName = pageNameP
        state.siteName = siteNameP
        state.isLoggedIn = isLoggedInP
    }
}

And I have a World object

var navState = require('./navigation-state')
var NavigationStateManager = require('./navigation-state-manager')

var navigationStateManager = new NavigationStateManager()

function World() {
    this.navState = simpleCopy(navState)
    navigationStateManager.setState(this.navState)
}

function simpleCopy(objectToCopy) {
    var copy = {}
    for(var key in objectToCopy) {
       copy[key] = objectToCopy[key]
    }
    return copy
}

In my steps file I do this

var World = require('../support/world')

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

   this.Given(...)
   this.Then(...)
}

For some reason the state becomes undefined in the NavigationStateManager when the Given steps have been executed and the Then steps are being executed. When I log I can't see setState being called with an 'undefined' argument. I've had a different setup, putting the NavigationStateManager on the World object, but it gave me similar issues. Apparently the World object doesn't remain the same through all steps of a scenario, but how does it behave. The error seems to go against all JavaScript knowledge I have. Where do I put state in my tests?

like image 362
raichu Avatar asked Dec 13 '16 21:12

raichu


People also ask

What is World in cucumber JS?

In Cucumber. js, “world” is an isolated scope for each scenario. That means all the step definitions, hooks, etc., for a scenario, is a part of a world and this data can be accessed within the world.

How do you ignore scenarios in cucumbers?

You can ignore Cucumber Tests using tags. not word is used along with tags to ignore the test. This works both for the Scenario as well as the Feature. You can skip a scenario, set of scenarios, or all scenarios in a feature file.


1 Answers

All support files that export a function will be called with a context that exposes the following methods:

source: https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/api_reference.md

I hadn't read this (and probably wouldn't have understood). I also confused the this reference to the context object and the this reference to a world object.

With context they mean the object that is exposed as this in the functions you export. It is the interface to interact with the Cucumber API.

This so called context object shouldn't be confused, with the world object. The world object is the this reference inside your steps, and is created by Cucumber from the World constructor you set on the context object (or the default if you don't set one) for every scenario.

Lastly you should not require and create new instances of any constructor exported in the support folder as I did. Since Cucumber automatically calls these constructors, you'll end up with two instances of the same object. Put your own helper objects, like a PageObject, in an separate folder.

like image 101
raichu Avatar answered Sep 29 '22 20:09

raichu