-
Task
-
Resolution: Obsolete
-
Neutral
-
None
-
None
TLDR
In Cucumber step-definition classes, we need the possibility to share the root pageObject among several methods. This requires dependency injection.
Cucumber context
In cucumber within one step definition class, there are typically a bunch of step definition methods for multiple scenarios of the same feature or even for several features of the same domain.
Each scenario consists of a set of methods. Sometimes one method can even be reused for more than one of the scenarios. The step def methods are executed in the order of how the scenario is defined in the feature file.
step def methods can not have parameters to share objects between methods (with the exception of cucumber.api.Scenario). Cucumber recommends using dependency injection (DI) to share objects among different methods.
Luckily, if a feature has multiple scenarios , the cucumber test runner creates a new instance of the step definition class for each scenario; and for each row of a scenario outline the cucumber test runner creates a new instance of the step definition class.
(See https://cucumber.io/blog/polymorphic-step-definitions/ , https://stackoverflow.com/questions/48726448/cucumber-step-definition-class-initialization)
Sharing the root pageObject "ui" among the methods of the same scenario ...
Within one scenario the class must share the same instance of the root page object info.magnolia.testframework.PageObjects (="ui") among the methods of this same scenario.
... but resetting the ui when starting a new scenario
When executing the 1st method of a scenario, the class must get a new, "fresh" instance of the ui.
Hooks
The cucumber API provide "hooks" which are executed before the 1st step and after the last step.
- cucumber.api.java.Before hooks run before the first step of each scenario.
- cucumber.api.java.After hooks run after the last step of each scenario, even when steps are failed, undefined, pending, or skipped.
See https://cucumber.io/docs/cucumber/api/#hooks
Acceptance criteria
- Provide a DI system to inject the root pageObjects, e.g. by injecting it into the constructor of the step def. class.
- Provide method(s) which allow to "destroy" the shared root pageObject by using the After hook and to get a new one by using the Before hook, if required.
More resources
- https://cucumber.io/docs/cucumber/state/
- http://picocontainer.com/
- https://softwareengineering.stackexchange.com/questions/287823/how-to-pass-object-generated-by-certain-test-class-to-another-test-class-using-w
- http://www.thinkcode.se/blog/2017/04/01/sharing-state-between-steps-in-cucumberjvm-using-picocontainer
- https://stackoverflow.com/questions/51125346/dependency-injection-cucumber-pico-container
Mocked example
I have added another example covering all my "cases" (having multiple scenarios plus a scenario outline).
For the new example-test I have created the class info.magnolia.functionaltests.cucumberbasictests.DummyUI to mock PageObjects, to make sure I can run the test. DummyUI gets injected by picocontainer.
The examples are on my (latest) branch (currently named feature/MGNLCE_164-page-objects-api_chm-version_vi).
- src/test/resources/info/magnolia/functionaltests/cucumberbasictests/configuration_app_availability_for_different_users.feature
- info.magnolia.functionaltests.cucumberbasictests.ConfigAppAvailabilityTest_stepDef
- info.magnolia.functionaltests.cucumberbasictests.ConfigAppAvailabilityTest
To trigger the test, run ConfigAppAvailabilityTest via Maven