Mixing instances in a Cucumber World
I recently had the problem of calling a step from another step definition in cucumber using groovy (cuke4duke). Example:
Given (~/I look for "(.*)" in "(.*)"/) { what, where ->
// groovy code
}
to be called from another step:
When (~/I perform more than (.*) searches per minute/) { int number ->
(1..number).each {
Given('I look for "John Smith " in "London"')
}
}
It’s possible to do this using Ruby (the cucumber native language), Java or Scala; but apparently it is not currently possible on groovy.
After posting my question on Cukes Groups I came up with this solution:
HomeSteps.groovy
Given (~/I look for "(.*)" in "(.*)"/) { what, where ->
lookFor(what, where)
}
ErrorsSteps.groovy
When (~/I perform more than (.*) searches per minute/) { int number ->
(1..number).each {
lookFor("John Smith","London")
}
}
env.groovy
import geb.Browser
import org.openqa.selenium.firefox.FirefoxDriver
this.metaClass.mixin(cuke4duke.GroovyDsl)
class Searcher {
def lookFor(what, where) {
go('/')
$('form')[0].looking_for = what
$('form')[0].location = where
$('input', value: "Search")[0].click()
}
}
World() {
def world = new Browser("http://localhost:8080/myApp") // mixing an instance of Browser
world.metaClass.mixin Searcher
return world
}
After() {
clearCookies()
}
Notice that I am not mixing an Object as Richard Paul suggested. In my case, I need to get an specific instance of Browser to be used across steps.
Anyway, I am posting this solution for people who might need something like this. In my case, I found out that my problem is in the way the step definitions are organized. Most of the times this kind of problem is caused by wrong organization of concepts so I recommend you think twice or even three times if you are placing your step in the right place before using a solution like the one I suggested here.
Hope this helps!