diff --git a/README.md b/README.md index cf6dcbd..583b699 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,18 @@ Just run `./gradlew integrationTest` and a container will be started and configu #### Custom Host Configuration -The annotation `ContainerGebConfiguration` exists to customize the connection the container will use to access the application under test. The annotation is not required and `ContainerGebSpec` will use the default values in this annotation if it's not present. +The annotation `ContainerGebConfiguration` exists to customize the connection the container will use to access the application under test. +The annotation is not required and `ContainerGebSpec` will use the default values in this annotation if it's not present. + +The interface `IContainerGebConfiguration` exists as an inheritable version of the annotation. + +#### Reporting + +To configure reporting, enable it using the `recording` property on the annotation `ContainerGebConfiguration`. The following system properties exist for reporting configuration: + +* `grails.geb.reporting.directory` + * purpose: if the test enables reporting, the directory to save the reports relative to the project directory + * defaults to `build/gebContainer/reports` #### Recording By default, no test recording will be performed. Here are the system properties available to change the recording behavior: diff --git a/spock-container-test-app/src/integration-test/groovy/org/demo/spock/InheritedConfigSpec.groovy b/spock-container-test-app/src/integration-test/groovy/org/demo/spock/InheritedConfigSpec.groovy new file mode 100644 index 0000000..a7c10c4 --- /dev/null +++ b/spock-container-test-app/src/integration-test/groovy/org/demo/spock/InheritedConfigSpec.groovy @@ -0,0 +1,88 @@ +package org.demo.spock + +import grails.plugin.geb.ContainerGebConfiguration +import grails.plugin.geb.IContainerGebConfiguration +import grails.plugin.geb.ContainerGebSpec +import grails.testing.mixin.integration.Integration + +/** + * Adaptation of {@link ServerNameControllerSpec} + */ +@Integration +class SuperSpec extends ContainerGebSpec implements IContainerGebConfiguration { + @Override + String hostName() { + return 'super.example.com' + } +} + +@Integration +@ContainerGebConfiguration(hostName = 'not.example.com') +class NotSuperSpec extends ContainerGebSpec {} + +@Integration +class InheritedConfigSpec extends SuperSpec { + void 'should show the right server name when visiting /serverName'() { + when: 'visiting the server name controller' + go '/serverName' + + then: 'the emitted hostname is correct' + $('p').text() == 'Server name: super.example.com' + } +} + +@Integration +class NotInheritedConfigSpec extends NotSuperSpec { + void 'should show the right server name when visiting /serverName'() { + when: 'visiting the server name controller' + go '/serverName' + + then: 'the emitted hostname is correct' + $('p').text() != 'Server name: not.example.com' + } +} + +@Integration +class ChildPreferenceInheritedConfigSpec extends SuperSpec { + @Override + String hostName() { + return 'child.example.com' + } + + void 'should show the right server name when visiting /serverName'() { + when: 'visiting the server name controller' + go '/serverName' + + then: 'the emitted hostname is correct' + $('p').text() == 'Server name: child.example.com' + + when: + report('whatever') + + then: + // geb.test.GebTestManager: "Reporting has not been enabled on this GebTestManager yet report() was called" + Throwable t = thrown(Exception) + t.message.contains("not been enabled") + } +} + +// No sane person would do this, but lets test anyway +@Integration +class SuperSuperInheritedConfigSpec extends SuperSpec { + @Override + boolean reporting() { + return true + } +} + +@Integration +class MultipleInheritanceSpec extends SuperSuperInheritedConfigSpec { + void 'should show the right server name when visiting /serverName'() { + when: 'visiting the server name controller' + go '/serverName' + + then: 'the emitted hostname is correct' + $('p').text() == 'Server name: super.example.com' + report('multi inheritance report') + } +} diff --git a/src/testFixtures/groovy/grails/plugin/geb/ContainerGebConfiguration.groovy b/src/testFixtures/groovy/grails/plugin/geb/ContainerGebConfiguration.groovy index 3855a09..487f2f9 100644 --- a/src/testFixtures/groovy/grails/plugin/geb/ContainerGebConfiguration.groovy +++ b/src/testFixtures/groovy/grails/plugin/geb/ContainerGebConfiguration.groovy @@ -65,3 +65,23 @@ import java.lang.annotation.Target */ Class fileDetector() default DefaultContainerFileDetector } + +/** + * Inheritable version of {@link ContainerGebConfiguration} + * + * @since 4.2 + */ +interface IContainerGebConfiguration { + + default String protocol() { + ContainerGebConfiguration.DEFAULT_PROTOCOL + } + + default String hostName() { + ContainerGebConfiguration.DEFAULT_HOSTNAME_FROM_CONTAINER + } + + default boolean reporting() { + false + } +} diff --git a/src/testFixtures/groovy/grails/plugin/geb/WebDriverContainerHolder.groovy b/src/testFixtures/groovy/grails/plugin/geb/WebDriverContainerHolder.groovy index 036efdc..a6e3639 100644 --- a/src/testFixtures/groovy/grails/plugin/geb/WebDriverContainerHolder.groovy +++ b/src/testFixtures/groovy/grails/plugin/geb/WebDriverContainerHolder.groovy @@ -212,9 +212,17 @@ class WebDriverContainerHolder { Class fileDetector WebDriverContainerConfiguration(SpecInfo spec) { - ContainerGebConfiguration configuration = spec.annotations.find { - it.annotationType() == ContainerGebConfiguration - } as ContainerGebConfiguration + ContainerGebConfiguration configuration + + // Check if the class implements the interface + if (IContainerGebConfiguration.isAssignableFrom(spec.reflection)) { + configuration = spec.reflection.getConstructor().newInstance() as ContainerGebConfiguration + } else { + // Check for the annotation + configuration = spec.annotations.find { + it.annotationType() == ContainerGebConfiguration + } as ContainerGebConfiguration + } protocol = configuration?.protocol() ?: ContainerGebConfiguration.DEFAULT_PROTOCOL hostName = configuration?.hostName() ?: ContainerGebConfiguration.DEFAULT_HOSTNAME_FROM_CONTAINER