I'm using cucumber + capybara for some web automation testing. I'd love to be able to wire up my own tag (something like @all_browsers before the scenario) and have it run against a list of web drivers I set (celerity, selenium on firefox, ie and chrome). I don't want to have to write the scenario 4 different times with 4 different tags out front. I've looked into trying to do this with a new driver I register via:
Capybara.register_driver :all_browsers do |app|
# What would even work in here? I don't think anything will.
end
And then following it up with:
Before('@all_browsers') do
# Same problem here.
end
But I'm not quite sure what to put in that Before method that might actually work.
I've tried using cucumber hooks, specifically:
Around('@all_browsers') do |scenario, block|
Capybara.current_driver = :selenium_firefox
block.call
Capybara.current_driver = :selenium_chrome
block.call
# etc
end
But this doesn't behave as I had hoped. It uses the same driver and runs the scenario twice with it.
Following along the hook lines, there's this from the cucumber documentation:
You may also provide an AfterConfiguration hook that will be run after Cucumber has been configured. This hook will run only once; after support has been loaded but before features are loaded. You can use this hook to extend Cucumber, for example you could affect how features are loaded...
This may be a potential path to go down for this, but I've not managed to come up with anything that works here either.
I've looked into custom formatters, but they really only look like they do exactly that – format the output, not so much designate how the features are actually run.
I've looked into overriding cucumber's feature runner, but that doesn't look easy or friendly to do.
Help please? Anyone?
Best Answer
So, I wound up rolling my own solution to this. Not sure if it was the best or most elegant approach, but I actually just wound up:
env.rb
env.rb
and then set the default driver for Capybara to the appropriate driver.Working like a charm and I think might have actually wound up better in the end than anything I was trying above, as within the Thor file I was able to add things like a benchmarking option, as well as whether or not to split the feature run up into multiple threads. Still curious if anyone else came up with a solution for this though.
cucumber.yaml:
Here, the all_features file just does a glob of everything ending in .feature, because if I pulled in the entire features directory it would pull in everything beneath it, including all the profile files, etc, which isn't what I wanted since each profile file sets the default capybara driver to a different value. Once you specify
-r
as an option to cucumber, all autoloading of any file is halted.firefox.rb (the 'profile' file):
selenium_firefox.rb (where I register the driver, and set some tag capability which I've wound up not needing now, as the
@selenium_firefox
tag was part of my original attempt at this posted in the question):feature_runner.thor:
Where everything wound up, in relation to the root directory:
Output of
thor -T
Now I can run something like:
thor feature_runner:all_drivers_runner --benchmark
This would run all features on all capybara drivers in a thread for each driver, benchmnarking the results.
Or
thor feature_runner:celerity_runner
This would run all features only on celerity.
But I can now also supply some other options to the thor command which get passed onto cucumber such as:
--tags=@all_browsers
--formatter=hotpants
--other_cucumber_args="--dry-run --guess --etc"
What a feature file can now look like:
Seems like a lot of setup, but now if I tag a feature with @all_browsers, I can build out a suite to test against all capybara drivers, in a multi-threaded environment, with one thor command:
thor feature_runner:all_drivers_runner --threaded --tags=@all_browsers
Or build out a smoke test suite that runs in celerity:
thor feature_runner:celerity_runner --tags=@smoke_test