Disclaimer
This project isn't affiliated in any manner with the official cucumber / cucumberJS projects, nor does it have their explicit or implicit support. In fact, this project's philosophy directly opposes that of the official cucumber implementations.
PLEASE NOTE: Until version 0.1, this project is in an alpha stage, with possible api and behaviour changes.
About this project
Cucumber, and specifically its cucumberJS implementation are wonderful tools for test automation and collaborative work. While these projects are right to focus on mainstream requirements and popular use-cases, they leave much of these tools potential untapped.
With cucumberJS version 3, me and other tinkerers found ourselves "locked out" of hacks and workarounds we came to rely on. This helper is meant to bring back some of that functionality, as well as provide additional manipulation options and enhancements.
Stability and robustness
TL;DR - May break at any time. Use at your own risk.
Many of the capabilities this helper provides require overriding and manipulating the internal code-structures of cucumber. Currently, I attempt to implement these without changing the actual source code of cucumber's package. This means that every new version of cucumberJS (even minor versions) might break some / most of the helper's features.
I will attempt to produce an upgraded version of the helper that fixes the issues, but there may come a time when that will no longer be possible (without changing the source code).
If you use this helper in your project's, be aware - it may break at any time. Use at your own risk.
Supported cucumber versions
The helper was tested with the following versions (may work with others):
- 3.0.6
Helper features
The helper has these main features:
- Reinstate the hooks from v2, with similar parameters, where possible.
- Manipulate the scenario-stack before the run starts (remove, reorder, change).
- Manipulate each scenario's step stack before it runs (remove, reorder, change).
- Manipulate step functions in-arguments and results.
- Get information on the current state of the run.
Usage
Using each feature is described under the API Details section. However, in order for the helper to function properly, cucumber must be run from the helper itself.
Programmatically
If you're already launching cucumber programmatically (i.e. you have something like cli.run()
in your code), then the adjustment is extremely easy.
Instead of working with let cucumber = require('cucumber')
, use let cucumber = require('cucumber-helper').cucumber;
.
That's it, you're done. Everything else in your code should work while remaining exactly the same.
Externally
If you're using cucumber externally (i.e. from the command line, an editor that launches it internally, etc.), you'll have to redirect that external process to work with the helper.
Check the command you're currently executing. Most likely it's node_modules/.bin/cucumberjs
(or maybe cucumber-js
).
Simply change that to node_modules/.bin/cucumber-helper
and you'll be set to go.
API details
Using the helper is relatively straightforward - add a helper.js
file to your features/support
folder (the file name is just for clarity - it can have any name you'd like).
In the file, require the helper package, and use it according to the API Details section below.
*Data structures and type definitions specified throughout the samples are specified at under type definitions
Scenario stack manipulations
The helper supports the possibility to change the scenario run stack before the run actually starts. You can filter, change the order, remove, duplicate or even manually add new testCases as needed.
Usage: helper.setTestCaseManipulator(function(tCases){return manipulatedTCases;});
Where manipulatedTCases
is a new array of test cases.
Example
let helper = ; helper;
Run information
In any time, you can invoke helper.currentRun
and receive the current test case, feature and step.
Please note, that the returned information is disconnected from cucumber (i.e. changing it will not affect the actual run).
Hooks and other functions may receive actionable objects that changing them can and will affect the run.
Hooks
The helper attempts to track the hooks from V2, with similar parameters (where possible). If your hook function is a-synchronous, it must return a native/bluebird Promise. Some hooks receive run-related information, and some even support manipulating that information as a way to dynamically affect the test run.
Usage: helper.setHook('hookName', myFunction(){/*Do Something*/});
The Available hooks are:
BeforeFeatures
- Executed right before the cucumber Runtime starts the actual run.
- Receives the array of to-be-executed features (Please note that a single feature might be split into several helper-features due to test case manipulations)
- Please note - changing the test case order within a feature object changes nothing in the actual run.
Example
let helper = ; helper;
BeforeAll
- Performs the regular V3 BeforeAll hook action.
- Can be set either from the helper, or regularly from the cucumber defineSupportCode interface (or both, if you really want to)
For more details see cucumberJS BeforeAll.
BeforeFeature
- Executes before a test case with a different URI than the current one.
- Note, this means you man get multiple hook activations for the same feature file, if you manipulate the scenario order.
- The hook will receive the upcoming feature object
- Please note - changing the test case order within a feature object changes nothing in the actual run.
Example
let helper = ; helper;
BeforeScenario
- Executes right before the cucumber Runtime starts processing the next scenario.
- Allows you to manipulate the coming scenario (add/remove steps, change its attributes, etc.)
Example
let helper = ; helper;
Before
- Performs the regular V3 Before hook action
- Support returning 'skipped' to skip the next scenario
- Can be set either from the helper, or regularly from the cucumber defineSupportCode interface (or both, if you really want to)
For more details see cucumberJS Before.
BeforeStep
- Runs right before the step is executed
- Allows you to manipulate the step parameters before they are passed to the step function
- Allows you to plant information that can be used by the AfterStep hook.
- Please note - changing the step object fields will not affect the cucumber runtime (i.e. change it's text)
Example
let helper = ; helper;
StepResult
- Replaced by AfterStep
AfterStep
- Runs right after a step in executed
- Receives the step (and ant field set on it by BeforeStep), and its result / a {result:Boolean, error_message : string, originalResult: object} object
- The hook can return a similarly structured result object to override the step result. Returning undefined doesn't change the result.
let helper = ; helper;
After
- Performs the regular V3 Before hook action
- Can be set either from the helper, or regularly from the cucumber defineSupportCode interface (or both, if you really want to)
For more details see cucumberJS After.
ScenarioResult
- Replaced by AfterScenario
AfterScenario
- Executes after the regular V3 after hook
- Gets the tCase object that BeforeScenario manipulated
Example
let helper = ; helper;
FeatureResult
- Replaced by AfterFeature
AfterFeature
- Executes after the a last scenario of a given URI sequence has finished its AfterScenario hook
- Note that as in BeforeFeature, other scenarios from the original file may still occur in a different feature-sequence.
- Gets the Feature object that BeforeFeature manipulated
Example
let helper = ; helper;
AfterAll
- Performs the regular V3 BeforeAll hook action.
- Can be set either from the helper, or regularly from the cucumber defineSupportCode interface (or both, if you really want to)
For more details see cucumberJS BeforeAll.
AfterFeatures
- Executes after the entire run has finished and the results have been outputted
- Allows you to manipulate the JSON result (for example).
- Receives the run boolean status, and allows you to return an alternate status
Example
let helper = ; helper;
TODO: add stepResult, scenarioResult, featureResult