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?
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.