Hi folks, One of the major benefits of the Apache Isis framework (and more generally the naked objects pattern) is that as a developer you get a user interface "for free". So given that the responsibility for rendering your domain objects moves into the framwork, it's a little embarrassing that the framework itself doesn't have any end-2-end browser (ie Selenium) tests to check that the rendering is correct. I'd really like to address that.
But it would also be useful, I think, for the framework to make it easy for projects to write their own end-to-end tests. Even though using integration tests and unit tests should be the standard way of verifying that the business functionality of the application works as expected, having as a minimum some browser based tests for smoke tests could be worthwhile in many cases, especially as more and more of us are moving to continuous deployment and tighter release schedules. Another use case is BDD, where the output of the BDD tests acting as "living documentation" to describe the behaviour of the system. Being able to hook up a BDD framework to an end-to-end testing framework that can take screenshots of the "journey" through the application would make that living documentation that much more compelling. On the other hand, end-to-end tests are notoriously labour intensive to develop, and can be expensive to maintain. Any support that the framework provides should substantially address these issues. With that in mind, I've started to do some exploration, using the kitchensink app [1]. What's emerging is the following architecture: - a set of page objects that could in principle be code-generated from Isis' own metamodel - tests that then use these page objects If the Wicket viewer is changed, then the code generation would also be updated; the tests would not change. And, because the page objects are code generated, they would be quite standardised and so hopefully easy to use. These page objects I see as being code-generated by the isis-maven-plugin, probably using freemarker templates. These would then be compiled into bytecode using a subsequent maven compiler plugin later on in the build pipeline. Finally, the tests would compile against these page objects. In this way, the end-to-end tests would therefore belong in the same repo as the application under test. In terms of how this might look, in the kitchensink I've been using the (groovy) geb and spock libraries. For example, given BusRulesObject [2] domain service: public class BusRulesObjects { ... public List<BusRulesObject> listAllBusRulesObject() { ... } public BusRulesObject findBusRulesObject(final String name) { ... } ... } then the listAll could be tested using [3]: @Stepwise class S_040_BusRulesObject_ListAllBusRulesObject extends GebReportingSpecWithApprovals { void "Business Rules Object > List All Bus Rules Object"() { given: def page = at LoggedInPage when: page.busRulesObjects.menu.jquery.mouseover() page.busRulesObjects.listAllBusRulesObject.menuItem.click() then: at BusRulesObject_StandaloneCollectionPage } void "Check 1st Row"() { when: def page = at BusRulesObject_StandaloneCollectionPage then: page.tablePanel.columns.name(0) =~ /Foo/ page.tablePanel.columns.enableActions(0) == false } void "Navigate to 1st Entity"() { given: def page = at BusRulesObject_StandaloneCollectionPage when: page.tablePanel.columns.objectTitle(0).click() then: def nextPage = at BusRulesObject_EntityPage nextPage.objectTitle =~ /Foo/ } } and the finder could be tested using [4]: @Stepwise class S_050_BusRulesObjects_FindBusRulesObject extends GebReportingSpecWithApprovals { void "Business Rules Object > Find Bus Rules Object"() { given: def page = at LoggedInPage when: page.busRulesObjects.menu.jquery.mouseover() page.busRulesObjects.findBusRulesObject.menuItem.click() then: page.busRulesObjects.findBusRulesObject.prompt.displayed when: "Missing name" page.busRulesObjects.findBusRulesObject.prompt.parameters.name.input = "" page.busRulesObjects.findBusRulesObject.prompt.ok.click() then: page.busRulesObjects.findBusRulesObject.prompt.parameters.name.feedback.text() =~ /'Name' is required./ report "name is required" when: "Enter all details" page.busRulesObjects.findBusRulesObject.prompt.parameters.name.input = "Foo" page.busRulesObjects.findBusRulesObject.prompt.ok.click() then: at EntityPage } } Each of these would result in a number of geb "module"s [5], these are the classes that would be code generated. All in all it's going to be quite a bit of effort to develop out these page object generation, though my hunch is that this will be worthwhile in the end. Not only will the current community benefit, it would also be a rather unique selling point for the framework. So, *if anyone is interested in helping out, please reply on this thread*. You'll need to have some familiarity (or willing to learn) with Selenium/geb and CSS, but you don't need to understand the internals of the framework to assist. Many thanks Dan [1] https://github.com/isisaddons/isis-app-kitchensink (maint-1.16.1 branch) [2] https://github.com/isisaddons/isis-app-kitchensink/blob/maint-1.16.1/dom/src/main/java/org/isisaddons/app/kitchensink/dom/busrules/BusRulesObjects.java [3] https://github.com/isisaddons/isis-app-kitchensink/blob/maint-1.16.1/tests-e2e/src/test/groovy/org/isisaddons/app/kitchensink/e2etests/specs/S_040_BusRulesObject_ListAllBusRulesObject.groovy [4] https://github.com/isisaddons/isis-app-kitchensink/blob/maint-1.16.1/tests-e2e/src/test/groovy/org/isisaddons/app/kitchensink/e2etests/specs/S_050_BusRulesObjects_FindBusRulesObject.groovy [5] https://github.com/isisaddons/isis-app-kitchensink/blob/maint-1.16.1/tests-e2e/src/test/groovy/org/isisaddons/app/kitchensink/e2etests/modules/busrules/BusRulesObjects/BusRulesObjects.groovy