From f2dc00ea64da0767bb78b9fbb14d5dafa36ea92c Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Mon, 14 Oct 2024 18:07:46 +0200 Subject: [PATCH 01/14] feat: Add `ContainerGebSpec` for running the browser in a container This feature enables easy running of geb tests in a container so you don't have to manage driver versions on the host machine. --- build.gradle | 6 ++++ gradle.properties | 3 ++ .../org/grails/geb/ContainerGebSpec.groovy | 31 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 src/main/groovy/org/grails/geb/ContainerGebSpec.groovy diff --git a/build.gradle b/build.gradle index 0838a4d..1effb36 100644 --- a/build.gradle +++ b/build.gradle @@ -31,12 +31,18 @@ configurations { dependencies { compileOnly "org.grails:grails-core:$grailsVersion" + compileOnlyApi "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" // used transitively by the generated tests api "org.gebish:geb-spock:$gebSpock" api "org.grails:grails-testing-support:$testingSupportVersion" api "org.grails:grails-datastore-gorm:$datastoreVersion" + implementation "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion" + implementation "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion" + implementation "org.testcontainers:spock:$testcontainersVersion" + implementation "org.testcontainers:selenium:$testcontainersVersion" + documentation "org.apache.groovy:groovy:$groovyVersion" documentation "org.apache.groovy:groovy-ant:$groovyVersion" documentation "org.apache.groovy:groovy-templates:$groovyVersion" diff --git a/gradle.properties b/gradle.properties index 8b2ebed..4b007af 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,9 @@ grailsVersion=7.0.0-SNAPSHOT grailsGradlePluginVersion=7.0.0-SNAPSHOT groovyVersion=4.0.23 javaParserCoreVersion=3.26.2 +seleniumVersion=4.25.0 +servletApiVersion=6.0.0 +testcontainersVersion=1.20.2 testingSupportVersion=4.0.0-SNAPSHOT org.gradle.parallel=true diff --git a/src/main/groovy/org/grails/geb/ContainerGebSpec.groovy b/src/main/groovy/org/grails/geb/ContainerGebSpec.groovy new file mode 100644 index 0000000..7adbb4c --- /dev/null +++ b/src/main/groovy/org/grails/geb/ContainerGebSpec.groovy @@ -0,0 +1,31 @@ +package org.grails.geb + +import geb.spock.GebSpec +import org.openqa.selenium.chrome.ChromeOptions +import org.openqa.selenium.remote.RemoteWebDriver +import org.testcontainers.containers.BrowserWebDriverContainer +import spock.lang.Shared + +import java.time.Duration + +class ContainerGebSpec extends GebSpec { + + @Shared + BrowserWebDriverContainer webDriverContainer + + void setupSpec() { + webDriverContainer = new BrowserWebDriverContainer() + webDriverContainer.start() + browser.driver = new RemoteWebDriver(webDriverContainer.seleniumAddress, new ChromeOptions()) + browser.driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30)) + } + + void setup() { + assert serverPort : "You must annotate your test class with @Integration for serverPort to be injected" + baseUrl = "http://host.docker.internal:$serverPort" + } + + def cleanupSpec() { + webDriverContainer.stop() + } +} \ No newline at end of file From 9c31099f66bb81cc99d3b65a6207b06f22c414af Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 15 Oct 2024 09:35:47 +0200 Subject: [PATCH 02/14] fix: Set proper package for `ContainerGebSpec` The common package name used by grails plugins is `grails.plugin.{plugin-name}`. --- .../{org/grails => grails/plugin}/geb/ContainerGebSpec.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/groovy/{org/grails => grails/plugin}/geb/ContainerGebSpec.groovy (97%) diff --git a/src/main/groovy/org/grails/geb/ContainerGebSpec.groovy b/src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy similarity index 97% rename from src/main/groovy/org/grails/geb/ContainerGebSpec.groovy rename to src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy index 7adbb4c..c7e8aa4 100644 --- a/src/main/groovy/org/grails/geb/ContainerGebSpec.groovy +++ b/src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy @@ -1,4 +1,4 @@ -package org.grails.geb +package grails.plugin.geb import geb.spock.GebSpec import org.openqa.selenium.chrome.ChromeOptions From 3cc8dd6da65dc20260e2664fe947a2395128df97 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 15 Oct 2024 09:37:26 +0200 Subject: [PATCH 03/14] refactor: Move `GebGrailsPlugin` to package `grails.plugin.geb` The common package name used by grails plugins is `grails.plugin.{plugin-name}`. --- src/main/groovy/{ => grails/plugin}/geb/GebGrailsPlugin.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/groovy/{ => grails/plugin}/geb/GebGrailsPlugin.groovy (96%) diff --git a/src/main/groovy/geb/GebGrailsPlugin.groovy b/src/main/groovy/grails/plugin/geb/GebGrailsPlugin.groovy similarity index 96% rename from src/main/groovy/geb/GebGrailsPlugin.groovy rename to src/main/groovy/grails/plugin/geb/GebGrailsPlugin.groovy index bde67dd..8884a3a 100644 --- a/src/main/groovy/geb/GebGrailsPlugin.groovy +++ b/src/main/groovy/grails/plugin/geb/GebGrailsPlugin.groovy @@ -1,4 +1,4 @@ -package geb +package grails.plugin.geb import grails.plugins.Plugin import grails.plugins.metadata.PluginSource From 2c204340dc4fc40323835465a0996e77f2491d18 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 15 Oct 2024 09:44:47 +0200 Subject: [PATCH 04/14] fix: Throw `IllegalStateException` if `serverPort` is null For `ContainerGebSpec` to work, the serverPort needs to be set. This is done by adding the `@Integration` annotation to the test class. --- src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy b/src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy index c7e8aa4..5c78dcf 100644 --- a/src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy +++ b/src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy @@ -16,12 +16,14 @@ class ContainerGebSpec extends GebSpec { void setupSpec() { webDriverContainer = new BrowserWebDriverContainer() webDriverContainer.start() - browser.driver = new RemoteWebDriver(webDriverContainer.seleniumAddress, new ChromeOptions()) + browser.driver = new RemoteWebDriver(webDriverContainer.seleniumAddress, new ChromeOptions(), false) browser.driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30)) } void setup() { - assert serverPort : "You must annotate your test class with @Integration for serverPort to be injected" + if (!serverPort) { + throw new IllegalStateException('You must annotate your test class with @Integration for serverPort to be injected') + } baseUrl = "http://host.docker.internal:$serverPort" } From a368a26c4d941cbec46876766d24f04c3610e75e Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Wed, 16 Oct 2024 16:57:17 +0200 Subject: [PATCH 05/14] fix: Exclude unnecessary slf4j exclusion in the pom --- gradle.properties | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gradle.properties b/gradle.properties index 4b007af..6789e47 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,6 +13,10 @@ servletApiVersion=6.0.0 testcontainersVersion=1.20.2 testingSupportVersion=4.0.0-SNAPSHOT +# This prevents the Grails Gradle Plugin from unnecessarily excluding slf4j-simple in the generated POMs +# https://github.com/grails/grails-gradle-plugin/issues/222 +slf4jPreventExclusion=true + org.gradle.parallel=true org.gradle.caching=true org.gradle.daemon=true From d9ce1997c3dcfd938ad021f55032e9798048cecd Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Wed, 16 Oct 2024 17:01:59 +0200 Subject: [PATCH 06/14] fix: Major updates to `ContainerGebSpec` feature - Use Gradle testFixtures feature to make test dependencies available to downstream projects without leaking them to the wrong scopes - Refactor `ContainerGebSpec` in co-operation with sbglasius to add more features and make it work without Docker Desktop. --- build.gradle | 53 +++++---- .../grails/plugin/geb/ContainerGebSpec.groovy | 33 ------ .../grails/plugin/geb/ContainerGebSpec.groovy | 109 ++++++++++++++++++ 3 files changed, 135 insertions(+), 60 deletions(-) delete mode 100644 src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy create mode 100644 src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy diff --git a/build.gradle b/build.gradle index 1effb36..37a3749 100644 --- a/build.gradle +++ b/build.gradle @@ -11,9 +11,10 @@ version projectVersion group "org.grails.plugins" apply plugin: 'java-library' -apply plugin: 'idea' +apply plugin: 'java-test-fixtures' apply plugin: 'org.grails.grails-plugin' apply plugin: 'org.grails.internal.grails-plugin-publish' +apply plugin: 'maven-publish' java { toolchain { @@ -30,18 +31,19 @@ configurations { } dependencies { - compileOnly "org.grails:grails-core:$grailsVersion" - compileOnlyApi "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" + compileOnly "org.grails:grails-core:$grailsVersion" // Provided as this is a Grails plugin + compileOnly "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" // Provided by the servlet container - // used transitively by the generated tests + // These are used transitively by the tests generated by the 'create-functional-test' script + // If they are not included as api, the generated tests will not compile without adding the dependencies manually api "org.gebish:geb-spock:$gebSpock" api "org.grails:grails-testing-support:$testingSupportVersion" api "org.grails:grails-datastore-gorm:$datastoreVersion" - implementation "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion" - implementation "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion" - implementation "org.testcontainers:spock:$testcontainersVersion" - implementation "org.testcontainers:selenium:$testcontainersVersion" + testFixturesCompileOnly "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" + testFixturesApi "org.testcontainers:selenium:$testcontainersVersion" + testFixturesApi "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion" + testFixturesApi "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion" documentation "org.apache.groovy:groovy:$groovyVersion" documentation "org.apache.groovy:groovy-ant:$groovyVersion" @@ -49,8 +51,6 @@ dependencies { documentation "com.github.javaparser:javaparser-core:$javaParserCoreVersion" } -findMainClass.enabled = false - grailsPublish { userOrg = 'grails' githubSlug = 'grails/geb' @@ -59,36 +59,35 @@ grailsPublish { } title = "Grails Geb Plugin" desc = "Provides Integration with Geb for Functional Testing" - developers = [graemerocher: "Graeme Rocher", puneetbehl: "Puneet Behl"] + developers = [ + graemerocher: 'Graeme Rocher', + puneetbehl: 'Puneet Behl', + sbglasius: 'Søren Berg Glasius', + matrei: 'Mattias Reichel' + ] } -tasks.withType(Groovydoc) { - destinationDir = new File(buildDir, 'docs/api') +tasks.withType(Groovydoc).configureEach { + destinationDir = layout.buildDirectory.dir('docs/api').get().asFile docTitle = "Grails Geb Plugin ${version}" classpath = configurations.documentation } -tasks.withType(GroovyCompile) { - configure(groovyOptions) { - forkOptions.jvmArgs = ['-Xmx1024m'] - } +tasks.withType(GroovyCompile).configureEach { + groovyOptions.forkOptions.jvmArgs = ['-Xmx1024m'] } -tasks.withType(Test) { +tasks.withType(Test).configureEach { useJUnitPlatform() -} - -test { testLogging { - events "passed", "skipped", "failed" - + events 'passed', 'skipped', 'failed' showExceptions true - exceptionFormat "full" + exceptionFormat 'full' showCauses true showStackTraces true } } -bootJar.enabled = false -bootRun.enabled = false -bootTestRun.enabled = false \ No newline at end of file +tasks.named('bootJar').configure { enabled = false } +tasks.named('bootRun').configure { enabled = false } +tasks.named('bootTestRun').configure { enabled = false } \ No newline at end of file diff --git a/src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy b/src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy deleted file mode 100644 index 5c78dcf..0000000 --- a/src/main/groovy/grails/plugin/geb/ContainerGebSpec.groovy +++ /dev/null @@ -1,33 +0,0 @@ -package grails.plugin.geb - -import geb.spock.GebSpec -import org.openqa.selenium.chrome.ChromeOptions -import org.openqa.selenium.remote.RemoteWebDriver -import org.testcontainers.containers.BrowserWebDriverContainer -import spock.lang.Shared - -import java.time.Duration - -class ContainerGebSpec extends GebSpec { - - @Shared - BrowserWebDriverContainer webDriverContainer - - void setupSpec() { - webDriverContainer = new BrowserWebDriverContainer() - webDriverContainer.start() - browser.driver = new RemoteWebDriver(webDriverContainer.seleniumAddress, new ChromeOptions(), false) - browser.driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30)) - } - - void setup() { - if (!serverPort) { - throw new IllegalStateException('You must annotate your test class with @Integration for serverPort to be injected') - } - baseUrl = "http://host.docker.internal:$serverPort" - } - - def cleanupSpec() { - webDriverContainer.stop() - } -} \ No newline at end of file diff --git a/src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy b/src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy new file mode 100644 index 0000000..8a8f83e --- /dev/null +++ b/src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy @@ -0,0 +1,109 @@ +package grails.plugin.geb +/* + * Copyright 2024 original author or authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import geb.spock.GebSpec +import groovy.transform.PackageScope +import org.openqa.selenium.chrome.ChromeOptions +import org.openqa.selenium.remote.RemoteWebDriver +import org.testcontainers.Testcontainers +import org.testcontainers.containers.BrowserWebDriverContainer +import org.testcontainers.containers.PortForwardingContainer +import spock.lang.Shared + +import java.time.Duration + +/** + * A {@link geb.spock.GebSpec GebSpec} that leverages Testcontainers to run the browser inside a container. + * + *

Prerequisites: + *

    + *
  • + * The test class must be annotated with {@link grails.testing.mixin.integration.Integration @Integration}. + *
  • + *
  • + * A compatible container runtime + * (e.g., Docker) must be available for Testcontainers to utilize. + *
  • + *
+ * + * @author Søren Berg Glasius + * @author Mattias Reichel + * @since 5.0.0 + */ +class ContainerGebSpec extends GebSpec { + + private static final String DEFAULT_PROTOCOL = 'http' + private static final String DEFAULT_HOSTNAME = 'host.testcontainers.internal' + + @Shared + BrowserWebDriverContainer webDriverContainer + + @PackageScope + void initialize() { + if (!webDriverContainer) { + if (!hasProperty('serverPort')) { + throw new IllegalStateException('Test class must be annotated with @Integration for serverPort to be injected') + } + webDriverContainer = new BrowserWebDriverContainer() + webDriverContainer.tap { + addExposedPort(serverPort) + withAccessToHost(true) + start() + } + Testcontainers.exposeHostPorts(serverPort) + if (hostName != DEFAULT_HOSTNAME) { + webDriverContainer.execInContainer('/bin/sh', '-c', "echo '$hostIp\t$hostName' | sudo tee -a /etc/hosts") + } + browser.driver = new RemoteWebDriver(webDriverContainer.seleniumAddress, new ChromeOptions()) + browser.driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30)) + } + } + + void setup() { + initialize() + baseUrl = "$protocol://$hostName:$serverPort" + } + + def cleanupSpec() { + webDriverContainer.stop() + } + + /** + * Returns the protocol that the browser will use to access the server under test. + *

Defaults to {@code http}. + * + * @return the protocol for accessing the server under test + */ + String getProtocol() { + return DEFAULT_PROTOCOL + } + + /** + * Returns the hostname that the browser will use to access the server under test. + *

Defaults to {@code host.testcontainers.internal}. + * + * @return the hostname for accessing the server under test + */ + String getHostName() { + return DEFAULT_HOSTNAME + } + + private static String getHostIp() { + PortForwardingContainer.INSTANCE.network.get().ipAddress + } +} \ No newline at end of file From 5bc7784c861daef519ad33c445d664afa8366c03 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Wed, 16 Oct 2024 19:52:41 +0200 Subject: [PATCH 07/14] fix: Change scope of dependencies in generated tests After this change this library needs to be referenced with `integrationTestImplementation testFixtures('org.grails.plugins:geb')` but now we are not leaking any test dependencies to downstream projects non-test configurations. --- build.gradle | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 37a3749..3259e69 100644 --- a/build.gradle +++ b/build.gradle @@ -34,13 +34,10 @@ dependencies { compileOnly "org.grails:grails-core:$grailsVersion" // Provided as this is a Grails plugin compileOnly "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" // Provided by the servlet container - // These are used transitively by the tests generated by the 'create-functional-test' script - // If they are not included as api, the generated tests will not compile without adding the dependencies manually - api "org.gebish:geb-spock:$gebSpock" - api "org.grails:grails-testing-support:$testingSupportVersion" - api "org.grails:grails-datastore-gorm:$datastoreVersion" - testFixturesCompileOnly "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" + testFixturesApi "org.gebish:geb-spock:$gebSpock" + testFixturesApi "org.grails:grails-testing-support:$testingSupportVersion" + testFixturesApi "org.grails:grails-datastore-gorm:$datastoreVersion" testFixturesApi "org.testcontainers:selenium:$testcontainersVersion" testFixturesApi "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion" testFixturesApi "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion" From bfae916ebdc645ea927705eb17c1a6e64df3e356 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Wed, 16 Oct 2024 20:08:01 +0200 Subject: [PATCH 08/14] fix: Remove `compileOnly` dependency on `servlet-api` --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3259e69..e75beef 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,6 @@ configurations { dependencies { compileOnly "org.grails:grails-core:$grailsVersion" // Provided as this is a Grails plugin - compileOnly "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" // Provided by the servlet container testFixturesCompileOnly "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" testFixturesApi "org.gebish:geb-spock:$gebSpock" From 0399b8f6e1bb145d22b4571ef29aee2d886e78ce Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Wed, 16 Oct 2024 20:22:12 +0200 Subject: [PATCH 09/14] chore: Move package declaration in `ContainerGebSpec` --- .../groovy/grails/plugin/geb/ContainerGebSpec.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy b/src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy index 8a8f83e..4da8ba5 100644 --- a/src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy +++ b/src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy @@ -1,4 +1,3 @@ -package grails.plugin.geb /* * Copyright 2024 original author or authors * @@ -14,7 +13,7 @@ package grails.plugin.geb * See the License for the specific language governing permissions and * limitations under the License. */ - +package grails.plugin.geb import geb.spock.GebSpec import groovy.transform.PackageScope From 426f4c71ed95b1a613ab059c15c37fdbe9c2ebc6 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Thu, 17 Oct 2024 15:35:53 +0200 Subject: [PATCH 10/14] fix(deps): Use versions from the `grails-bom` where available --- build.gradle | 38 +++++++++++++++++++------------------- gradle.properties | 3 --- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/build.gradle b/build.gradle index e75beef..9927778 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ buildscript { repositories { - maven { url "https://repo.grails.org/grails/core" } + maven { url = 'https://repo.grails.org/grails/core' } } dependencies { classpath "org.grails:grails-gradle-plugin:$grailsGradlePluginVersion" } } -version projectVersion -group "org.grails.plugins" +version = projectVersion +group = 'org.grails.plugins' apply plugin: 'java-library' apply plugin: 'java-test-fixtures' @@ -23,7 +23,7 @@ java { } repositories { - maven { url "https://repo.grails.org/grails/core" } + maven { url = 'https://repo.grails.org/grails/core' } } configurations { @@ -31,19 +31,22 @@ configurations { } dependencies { - compileOnly "org.grails:grails-core:$grailsVersion" // Provided as this is a Grails plugin + + implementation(platform("org.grails:grails-bom:$grailsVersion")) + + compileOnly 'org.grails:grails-core' // Provided as this is a Grails plugin testFixturesCompileOnly "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" testFixturesApi "org.gebish:geb-spock:$gebSpock" - testFixturesApi "org.grails:grails-testing-support:$testingSupportVersion" - testFixturesApi "org.grails:grails-datastore-gorm:$datastoreVersion" + testFixturesApi "org.grails:grails-testing-support" + testFixturesApi "org.grails:grails-datastore-gorm" testFixturesApi "org.testcontainers:selenium:$testcontainersVersion" testFixturesApi "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion" testFixturesApi "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion" - documentation "org.apache.groovy:groovy:$groovyVersion" - documentation "org.apache.groovy:groovy-ant:$groovyVersion" - documentation "org.apache.groovy:groovy-templates:$groovyVersion" + documentation "org.apache.groovy:groovy" + documentation "org.apache.groovy:groovy-ant" + documentation "org.apache.groovy:groovy-templates" documentation "com.github.javaparser:javaparser-core:$javaParserCoreVersion" } @@ -53,8 +56,8 @@ grailsPublish { license { name = 'Apache-2.0' } - title = "Grails Geb Plugin" - desc = "Provides Integration with Geb for Functional Testing" + title = 'Grails Geb Plugin' + desc = 'Provides Integration with Geb for Functional Testing' developers = [ graemerocher: 'Graeme Rocher', puneetbehl: 'Puneet Behl', @@ -69,10 +72,6 @@ tasks.withType(Groovydoc).configureEach { classpath = configurations.documentation } -tasks.withType(GroovyCompile).configureEach { - groovyOptions.forkOptions.jvmArgs = ['-Xmx1024m'] -} - tasks.withType(Test).configureEach { useJUnitPlatform() testLogging { @@ -84,6 +83,7 @@ tasks.withType(Test).configureEach { } } -tasks.named('bootJar').configure { enabled = false } -tasks.named('bootRun').configure { enabled = false } -tasks.named('bootTestRun').configure { enabled = false } \ No newline at end of file +tasks.named('bootJar') { enabled = false } +tasks.named('bootRun') { enabled = false } +tasks.named('bootTestRun') { enabled = false } +tasks.named('findMainClass') { enabled = false } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 6789e47..53894c4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,16 +2,13 @@ projectVersion=5.0.0-SNAPSHOT title=Grails Geb Plugin developers=Puneet Behl -datastoreVersion=9.0.0-SNAPSHOT gebSpock=7.0 grailsVersion=7.0.0-SNAPSHOT grailsGradlePluginVersion=7.0.0-SNAPSHOT -groovyVersion=4.0.23 javaParserCoreVersion=3.26.2 seleniumVersion=4.25.0 servletApiVersion=6.0.0 testcontainersVersion=1.20.2 -testingSupportVersion=4.0.0-SNAPSHOT # This prevents the Grails Gradle Plugin from unnecessarily excluding slf4j-simple in the generated POMs # https://github.com/grails/grails-gradle-plugin/issues/222 From d077bdbc879160af73cf2e03fa3f62a42e8f71a5 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Thu, 17 Oct 2024 16:17:32 +0200 Subject: [PATCH 11/14] build: Update to `develocity` plugin and `bellsoft` toolchain vendor --- build.gradle | 1 + settings.gradle | 33 +++++++++++++++------------------ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 9927778..d0f96c4 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ apply plugin: 'maven-publish' java { toolchain { languageVersion = JavaLanguageVersion.of(17) + vendor = JvmVendorSpec.BELLSOFT } } diff --git a/settings.gradle b/settings.gradle index e3273ca..5e7b294 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,30 +1,27 @@ plugins { - id "com.gradle.enterprise" version "3.18.1" + id 'com.gradle.develocity' version '3.18.1' id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.0.2' + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' } -rootProject.name="geb" +def isCI = System.getenv('CI') != null +def isLocal = !isCI +def isAuthenticated = System.getenv('DEVELOCITY_ACCESS_KEY') != null -gradleEnterprise { +develocity { server = 'https://ge.grails.org' buildScan { - publishAlways() - publishIfAuthenticated() - uploadInBackground = System.getenv("CI") == null - capture { - taskInputFiles = true - } + publishing.onlyIf { isAuthenticated } + uploadInBackground = isLocal } } buildCache { - local { enabled = System.getenv('CI') != 'true' } - remote(HttpBuildCache) { - push = System.getenv('CI') == 'true' + local { enabled = isLocal } + remote(develocity.buildCache) { + push = isCI && isAuthenticated enabled = true - url = 'https://ge.grails.org/cache/' - credentials { - username = System.getenv('GRADLE_ENTERPRISE_BUILD_CACHE_NODE_USER') - password = System.getenv('GRADLE_ENTERPRISE_BUILD_CACHE_NODE_KEY') - } - }} + } +} + +rootProject.name = 'geb' From dfd27aaf668088fda5cd529d8c42e5bba9b667f5 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Wed, 23 Oct 2024 13:59:28 +0200 Subject: [PATCH 12/14] chore(build): Remove unused project properties --- gradle.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 53894c4..9377fb1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,4 @@ projectVersion=5.0.0-SNAPSHOT -title=Grails Geb Plugin -developers=Puneet Behl gebSpock=7.0 grailsVersion=7.0.0-SNAPSHOT From d4e86157f5ec74e6869a5935e0f2ee48ed4a4548 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Wed, 23 Oct 2024 14:00:25 +0200 Subject: [PATCH 13/14] fix(deps): Use versions from `grails-bom` --- build.gradle | 16 ++++++++-------- gradle.properties | 4 ---- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index d0f96c4..08857db 100644 --- a/build.gradle +++ b/build.gradle @@ -37,18 +37,18 @@ dependencies { compileOnly 'org.grails:grails-core' // Provided as this is a Grails plugin - testFixturesCompileOnly "jakarta.servlet:jakarta.servlet-api:$servletApiVersion" - testFixturesApi "org.gebish:geb-spock:$gebSpock" - testFixturesApi "org.grails:grails-testing-support" - testFixturesApi "org.grails:grails-datastore-gorm" + testFixturesCompileOnly 'jakarta.servlet:jakarta.servlet-api' + testFixturesApi 'org.gebish:geb-spock' + testFixturesApi 'org.grails:grails-testing-support' + testFixturesApi 'org.grails:grails-datastore-gorm' testFixturesApi "org.testcontainers:selenium:$testcontainersVersion" testFixturesApi "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion" testFixturesApi "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion" - documentation "org.apache.groovy:groovy" - documentation "org.apache.groovy:groovy-ant" - documentation "org.apache.groovy:groovy-templates" - documentation "com.github.javaparser:javaparser-core:$javaParserCoreVersion" + documentation 'org.apache.groovy:groovy' + documentation 'org.apache.groovy:groovy-ant' + documentation 'org.apache.groovy:groovy-templates' + documentation 'com.github.javaparser:javaparser-core' } grailsPublish { diff --git a/gradle.properties b/gradle.properties index 9377fb1..b82b693 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,11 +1,7 @@ projectVersion=5.0.0-SNAPSHOT - -gebSpock=7.0 grailsVersion=7.0.0-SNAPSHOT grailsGradlePluginVersion=7.0.0-SNAPSHOT -javaParserCoreVersion=3.26.2 seleniumVersion=4.25.0 -servletApiVersion=6.0.0 testcontainersVersion=1.20.2 # This prevents the Grails Gradle Plugin from unnecessarily excluding slf4j-simple in the generated POMs From 2061ddfffdfb86251a40632c6d72409ba753b7fc Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Wed, 23 Oct 2024 14:14:30 +0200 Subject: [PATCH 14/14] docs: Update readme with info about `ContainerGebSpec` --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index c422780..bf96052 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,16 @@ Geb Functional Testing for the Grails® framework. +This plugin provides the Geb dependencies, a `create-functional-test` command for generating Geb tests in a Grails app +and also adds a ContainerGebSpec that when inherited from automatically runs the browser in a container. + This plugin provides the Geb dependencies and a `create-functional-test` command for generating Geb tests in a Grails app. +It also provides a `ContainerGebSpec` class, which can be used in place of `GebSpec`, that automatically +runs the browser in a container using [Testcontainers](https://java.testcontainers.org/). This requires a +[compatible container runtime](https://java.testcontainers.org/supported_docker_environment/) such as +[Docker](https://www.docker.com/) to be installed. + For further reference please see the [Geb documentation](https://www.gebish.org). ## Examples