You are viewing a plain text version of this content. The canonical link for it is here.
Posted to geb-notifications@groovy.apache.org by cm...@apache.org on 2026/02/15 22:13:14 UTC
(groovy-geb) branch task/geb-testcontainers updated (0babb6c7 -> 120e2c5b)
This is an automated email from the ASF dual-hosted git repository.
cmarcum pushed a change to branch task/geb-testcontainers
in repository https://gitbox.apache.org/repos/asf/groovy-geb.git
from 0babb6c7 change chrome testcontainer to firefox for macOS testers.
new 0036f2ca fix codenarc violations.
new 43c6f2fc fix codenarc violations.
new 120e2c5b remove codenarc issue from the temporary section of README.md.
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
integration/geb-testcontainers/README.md | 8 +-
.../demo/spock/BaseUrlConfigFromClassSpec.groovy | 3 -
.../ContainerFileDetectorAnnotationSpec.groovy | 3 +-
.../spock/ContainerFileDetectorDefaultSpec.groovy | 1 -
.../spock/ContainerFileDetectorSpockSpec.groovy | 5 +-
.../demo/spock/ContainerGebSpecWithServer.groovy | 4 -
.../org/demo/spock/DownloadSupportSpec.groovy | 2 -
.../groovy/org/demo/spock/GebConfigSpec.groovy | 4 -
.../demo/spock/HostNameConfigurationSpec.groovy | 1 -
.../org/demo/spock/InheritedConfigSpec.groovy | 1 -
.../groovy/org/demo/spock/PageDelegateSpec.groovy | 6 +-
.../org/demo/spock/PerTestRecordingSpec.groovy | 12 +-
.../org/demo/spock/PortConfigFromClassSpec.groovy | 2 -
.../groovy/org/demo/spock/RootPageSpec.groovy | 1 -
.../groovy/org/demo/spock/TestFileServer.groovy | 5 -
.../org/demo/spock/TestFileServerSpec.groovy | 5 -
.../groovy/org/demo/spock/UploadSpec.groovy | 4 -
.../groovy/org/demo/spock/pages/HomePage.groovy | 1 -
.../groovy/org/demo/spock/pages/UploadPage.groovy | 4 -
.../org/demo/spock/pages/UploadSuccessPage.groovy | 1 -
.../grails/plugin/geb/ContainerFileDetector.groovy | 2 +-
.../plugin/geb/ContainerGebTestDescription.groovy | 4 +-
.../plugin/geb/DefaultContainerFileDetector.groovy | 4 +-
.../plugin/geb/GrailsContainerGebExtension.groovy | 18 +-
.../grails/plugin/geb/GrailsGebSettings.groovy | 45 ++-
.../plugin/geb/WebDriverContainerHolder.groovy | 387 +++++++++++----------
.../geb/serviceloader/ServiceRegistry.groovy | 4 +-
.../grails/plugin/geb/support/BrowserType.groovy | 14 +-
.../geb/support/ContainerGebFileInputSource.groovy | 1 -
.../geb/support/LocalhostDownloadSupport.groovy | 4 +-
.../geb/support/delegate/BrowserDelegate.groovy | 2 +-
.../geb/support/delegate/PageDelegate.groovy | 2 +-
32 files changed, 260 insertions(+), 300 deletions(-)
(groovy-geb) 02/03: fix codenarc violations.
Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
cmarcum pushed a commit to branch task/geb-testcontainers
in repository https://gitbox.apache.org/repos/asf/groovy-geb.git
commit 43c6f2fc62473719c3a9000106b49f1d7c626944
Author: Carl Marcum <ca...@codebuilders.net>
AuthorDate: Sun Feb 15 10:36:11 2026 -0500
fix codenarc violations.
---
.../groovy/org/demo/spock/BaseUrlConfigFromClassSpec.groovy | 3 ---
.../demo/spock/ContainerFileDetectorAnnotationSpec.groovy | 3 +--
.../org/demo/spock/ContainerFileDetectorDefaultSpec.groovy | 1 -
.../org/demo/spock/ContainerFileDetectorSpockSpec.groovy | 5 ++---
.../groovy/org/demo/spock/ContainerGebSpecWithServer.groovy | 4 ----
.../groovy/org/demo/spock/DownloadSupportSpec.groovy | 2 --
.../groovy/org/demo/spock/GebConfigSpec.groovy | 4 ----
.../groovy/org/demo/spock/HostNameConfigurationSpec.groovy | 1 -
.../groovy/org/demo/spock/InheritedConfigSpec.groovy | 1 -
.../groovy/org/demo/spock/PageDelegateSpec.groovy | 6 +-----
.../groovy/org/demo/spock/PerTestRecordingSpec.groovy | 12 ++++--------
.../groovy/org/demo/spock/PortConfigFromClassSpec.groovy | 2 --
.../groovy/org/demo/spock/RootPageSpec.groovy | 1 -
.../groovy/org/demo/spock/TestFileServer.groovy | 5 -----
.../groovy/org/demo/spock/TestFileServerSpec.groovy | 5 -----
.../integration-test/groovy/org/demo/spock/UploadSpec.groovy | 4 ----
.../groovy/org/demo/spock/pages/HomePage.groovy | 1 -
.../groovy/org/demo/spock/pages/UploadPage.groovy | 4 ----
.../groovy/org/demo/spock/pages/UploadSuccessPage.groovy | 1 -
19 files changed, 8 insertions(+), 57 deletions(-)
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/BaseUrlConfigFromClassSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/BaseUrlConfigFromClassSpec.groovy
index fbaf4483..0c11e4e9 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/BaseUrlConfigFromClassSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/BaseUrlConfigFromClassSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import grails.plugin.geb.ContainerGebSpec
@@ -28,11 +27,9 @@ import spock.lang.Narrative
@Narrative("To verify that class field overrides config file.")
class BaseUrlConfigFromClassSpec extends ContainerGebSpec {
-
String baseUrl = "http://groovy.apache.org"
def "should use the class field value"() {
-
when: "go to geb sub-page of groovy"
go "/geb"
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorAnnotationSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorAnnotationSpec.groovy
index 50f713b8..195f66db 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorAnnotationSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorAnnotationSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import grails.plugin.geb.ContainerGebConfiguration
@@ -25,7 +24,7 @@ import org.demo.spock.pages.UploadPage
import org.openqa.selenium.WebDriverException
/**
- * Altered copy of {@link ContainerFileDetectorDefaultSpec}
+ * Altered copy of {@link ContainerFileDetectorDefaultSpec}
* that throws {@link org.openqa.selenium.InvalidArgumentException}
*/
@ContainerGebConfiguration(fileDetector = UselessContainerFileDetector)
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorDefaultSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorDefaultSpec.groovy
index d07001eb..e23b3942 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorDefaultSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorDefaultSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import org.demo.spock.pages.UploadSuccessPage
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorSpockSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorSpockSpec.groovy
index d9975fa9..af93dea8 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorSpockSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerFileDetectorSpockSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import grails.plugin.geb.ContainerFileDetector
@@ -31,11 +30,11 @@ import spock.lang.PendingFeature
*/
class ContainerFileDetectorSpockSpec extends ContainerGebSpecWithServer {
- def setupSpec(){
+ def setupSpec() {
ServiceRegistry.setInstance(ContainerFileDetector, new UselessContainerFileDetector())
}
- def cleanupSpec(){
+ def cleanupSpec() {
ServiceRegistry.setInstance(ContainerFileDetector, null)
}
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerGebSpecWithServer.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerGebSpecWithServer.groovy
index 5dfeefaa..4381c82b 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerGebSpecWithServer.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/ContainerGebSpecWithServer.groovy
@@ -16,10 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
-
import grails.plugin.geb.ContainerGebSpec
/**
@@ -38,6 +36,4 @@ class ContainerGebSpecWithServer extends ContainerGebSpec {
server.stop(0)
}
-
-
}
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/DownloadSupportSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/DownloadSupportSpec.groovy
index 3ede798e..cafb8762 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/DownloadSupportSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/DownloadSupportSpec.groovy
@@ -16,13 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import org.demo.spock.pages.HomePage
import spock.lang.Title
-
@Title("should be able to use download methods")
class DownloadSupportSpec extends ContainerGebSpecWithServer {
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/GebConfigSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/GebConfigSpec.groovy
index 5009c589..d57d23bf 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/GebConfigSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/GebConfigSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import org.demo.spock.pages.HomePage
@@ -29,8 +28,6 @@ import org.openqa.selenium.remote.RemoteWebDriver
class GebConfigSpec extends ContainerGebSpecWithServer {
def "should use custom RemoteWebDriver from GebConfig.groovy"() {
- // reportInfo "the config file should use environment blocks with browser names"
-
expect: 'the driver to be a RemoteWebDriver'
driver instanceof RemoteWebDriver
@@ -63,7 +60,6 @@ class GebConfigSpec extends ContainerGebSpecWithServer {
$("h1").text() == "Welcome to the Geb/Spock Test"
}
-
def cleanup() {
sleep(1000) // give the last video time to copy
}
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/HostNameConfigurationSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/HostNameConfigurationSpec.groovy
index 7530dccc..16d202ad 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/HostNameConfigurationSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/HostNameConfigurationSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import org.demo.spock.pages.HomePage
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/InheritedConfigSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/InheritedConfigSpec.groovy
index 5edbb392..a9977a01 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/InheritedConfigSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/InheritedConfigSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import org.demo.spock.pages.HomePage
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PageDelegateSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PageDelegateSpec.groovy
index 6bc2c67f..ee21ed05 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PageDelegateSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PageDelegateSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import org.demo.spock.pages.UploadPage
@@ -24,11 +23,8 @@ import org.demo.spock.pages.UploadPage
class PageDelegateSpec extends ContainerGebSpecWithServer {
def "should delegate to page object"() {
- given:
- to(UploadPage)
-
when:
- nop()
+ to(UploadPage)
then:
title == 'Upload Test'
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PerTestRecordingSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PerTestRecordingSpec.groovy
index 7995a3b1..1eb0bce2 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PerTestRecordingSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PerTestRecordingSpec.groovy
@@ -16,19 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import grails.plugin.geb.ContainerGebSpec
-import spock.lang.Shared
import spock.lang.Stepwise
@Stepwise // execute feature methods in declared order
class PerTestRecordingSpec extends ContainerGebSpec {
- // @Shared
- // serverPort = 8080 // TODO: this needs to be a configuration
-
void '(setup) running a test to create a recording'() {
when: 'visiting the grails home page'
go('https://grails.apache.org/')
@@ -83,9 +78,10 @@ class PerTestRecordingSpec extends ContainerGebSpec {
and: 'the recording files should have different content (different sizes)'
// Sort by last modified time to get the most recent files
- def sortedFiles = recordingFiles.sort { it.lastModified() }
- def secondLastFile = sortedFiles[sortedFiles.length - 2]
- def lastFile = sortedFiles[sortedFiles.length - 1]
+ recordingFiles.sort { it.lastModified() }
+ // recordedFiles in now sorted by modified date
+ def secondLastFile = recordingFiles[recordingFiles.length - 2]
+ def lastFile = recordingFiles.last()
// Files should have different sizes (allowing for small variations due to timing)
long sizeDifference = Math.abs(lastFile.length() - secondLastFile.length())
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PortConfigFromClassSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PortConfigFromClassSpec.groovy
index 25168b95..3947d077 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PortConfigFromClassSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/PortConfigFromClassSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import grails.plugin.geb.ContainerGebSpec
@@ -50,7 +49,6 @@ class PortConfigFromClassSpec extends ContainerGebSpec {
and: "the welcome header should be displayed"
$("h1").text() == "Welcome to the Geb/Spock Test"
-
}
def cleanup() {
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/RootPageSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/RootPageSpec.groovy
index aadc5a1c..2f5a053b 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/RootPageSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/RootPageSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import geb.report.CompositeReporter
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/TestFileServer.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/TestFileServer.groovy
index 211c9be7..f291320a 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/TestFileServer.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/TestFileServer.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import com.sun.net.httpserver.HttpServer
@@ -30,8 +29,6 @@ class TestFileServer {
static HttpServer server
- TestFileServer() {}
-
void start() {
start(8080)
}
@@ -55,8 +52,6 @@ class TestFileServer {
stop(0)
}
-
-
void stop(int delay) {
println "Stopping TestFileServer..."
if (server) {
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/TestFileServerSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/TestFileServerSpec.groovy
index a0df3cf4..696788f1 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/TestFileServerSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/TestFileServerSpec.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import grails.plugin.geb.ContainerGebSpec
@@ -34,7 +33,6 @@ class TestFileServerSpec extends ContainerGebSpec {
server = new TestFileServer()
}
-
// the config file should contain a 'hostPort = 8090' setting
def "should use the hostPort con GebConfig.groovy"() {
given: "a server listening on port 8090"
@@ -49,7 +47,6 @@ class TestFileServerSpec extends ContainerGebSpec {
and: "the welcome header should be displayed"
$("h1").text() == "Welcome to the Geb/Spock Test"
-
}
def cleanup() {
@@ -57,6 +54,4 @@ class TestFileServerSpec extends ContainerGebSpec {
server.stop(0)
}
-
-
}
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/UploadSpec.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/UploadSpec.groovy
index 674c9263..d4fa6fc3 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/UploadSpec.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/UploadSpec.groovy
@@ -16,13 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock
import geb.module.FileInput
import org.demo.spock.pages.UploadSuccessPage
-import grails.plugin.geb.ContainerGebSpec
import org.demo.spock.pages.UploadPage
import spock.lang.IgnoreIf
import spock.lang.Requires
@@ -103,7 +101,6 @@ class UploadSpec extends ContainerGebSpecWithServer {
then:
$("div.example").$("h3").text() == "File Uploaded!"
$("div.example").$("div", id: "uploaded-files").text() == "upload-test.txt"
-
}
def cleanup() {
@@ -111,5 +108,4 @@ class UploadSpec extends ContainerGebSpecWithServer {
container.execInContainer("rm /tmp/upload-test.txt")
}
-
}
\ No newline at end of file
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/HomePage.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/HomePage.groovy
index 7fd3d999..418ab81a 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/HomePage.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/HomePage.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock.pages
import geb.Page
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/UploadPage.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/UploadPage.groovy
index 610e9a6d..6fcea215 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/UploadPage.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/UploadPage.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock.pages
import geb.Page
@@ -32,7 +31,4 @@ class UploadPage extends Page {
submitBtn { $('button', type: 'submit') }
}
- void nop() {
- // no-op
- }
}
\ No newline at end of file
diff --git a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/UploadSuccessPage.groovy b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/UploadSuccessPage.groovy
index 3f53dd5a..cde7f5f5 100644
--- a/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/UploadSuccessPage.groovy
+++ b/integration/geb-testcontainers/src/integration-test/groovy/org/demo/spock/pages/UploadSuccessPage.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.demo.spock.pages
import geb.Page
(groovy-geb) 01/03: fix codenarc violations.
Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
cmarcum pushed a commit to branch task/geb-testcontainers
in repository https://gitbox.apache.org/repos/asf/groovy-geb.git
commit 0036f2ca9bfe1921be634341b5043a3a8f594478
Author: Carl Marcum <ca...@codebuilders.net>
AuthorDate: Sat Feb 14 16:01:02 2026 -0500
fix codenarc violations.
---
.../grails/plugin/geb/ContainerFileDetector.groovy | 2 +-
.../plugin/geb/ContainerGebTestDescription.groovy | 4 +-
.../plugin/geb/DefaultContainerFileDetector.groovy | 4 +-
.../plugin/geb/GrailsContainerGebExtension.groovy | 18 +-
.../grails/plugin/geb/GrailsGebSettings.groovy | 45 ++-
.../plugin/geb/WebDriverContainerHolder.groovy | 387 +++++++++++----------
.../geb/serviceloader/ServiceRegistry.groovy | 4 +-
.../grails/plugin/geb/support/BrowserType.groovy | 14 +-
.../geb/support/ContainerGebFileInputSource.groovy | 1 -
.../geb/support/LocalhostDownloadSupport.groovy | 4 +-
.../geb/support/delegate/BrowserDelegate.groovy | 2 +-
.../geb/support/delegate/PageDelegate.groovy | 2 +-
12 files changed, 251 insertions(+), 236 deletions(-)
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/ContainerFileDetector.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/ContainerFileDetector.groovy
index 0b824738..f271c209 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/ContainerFileDetector.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/ContainerFileDetector.groovy
@@ -23,7 +23,7 @@ import org.openqa.selenium.remote.FileDetector
/**
* An extension of {@link org.openqa.selenium.remote.FileDetector}
- * that will get passed additional parameters from the webdriver container holder.
+ * that will get passed additional parameters from the webdriver container holder.
* <p>
* Implementations must provide a zero-argument constructor to ensure compatibility
* with {@link java.util.ServiceLoader}.
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/ContainerGebTestDescription.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/ContainerGebTestDescription.groovy
index 65bb5f15..71251bcd 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/ContainerGebTestDescription.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/ContainerGebTestDescription.groovy
@@ -39,8 +39,8 @@ class ContainerGebTestDescription implements TestDescription {
testId = [
testInfo.feature.spec.displayName,
testInfo.feature.displayName,
- testInfo.displayName != testInfo.feature.displayName ? testInfo.displayName : null,
- testInfo.displayName != testInfo.feature.displayName ? testInfo.iterationIndex : null
+ testInfo.displayName == testInfo.feature.displayName ? null : testInfo.displayName,
+ testInfo.displayName == testInfo.feature.displayName ? null : testInfo.iterationIndex
].findAll(/* Remove nulls */).join(' ')
def safeName = testId.replaceAll('\\W+', '_')
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/DefaultContainerFileDetector.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/DefaultContainerFileDetector.groovy
index a15a7e4c..c4472a36 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/DefaultContainerFileDetector.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/DefaultContainerFileDetector.groovy
@@ -23,7 +23,7 @@ import org.openqa.selenium.remote.UselessFileDetector
/**
* Detects files on the local disk.
- *
+ *
* @since 4.2
*/
class DefaultContainerFileDetector extends LocalFileDetector implements ContainerFileDetector {
@@ -31,7 +31,7 @@ class DefaultContainerFileDetector extends LocalFileDetector implements Containe
/**
* A file detector that never finds anything.
- *
+ *
* @since 4.2
*/
class UselessContainerFileDetector extends UselessFileDetector implements ContainerFileDetector {
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/GrailsContainerGebExtension.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/GrailsContainerGebExtension.groovy
index b976aebd..28584375 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/GrailsContainerGebExtension.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/GrailsContainerGebExtension.groovy
@@ -70,7 +70,7 @@ class GrailsContainerGebExtension implements IGlobalExtension {
@Override
void visitSpec(SpecInfo spec) {
- if (isContainerGebSpec(spec) ) {
+ if (isContainerGebSpec(spec)) {
// Do not allow parallel execution since there's only 1 set of containers in testcontainers
spec.addExclusiveResource(exclusiveResource)
@@ -122,6 +122,13 @@ class GrailsContainerGebExtension implements IGlobalExtension {
}
}
+ private static void addGebExtensionOnFailureReporter(SpecInfo spec) {
+ List<MethodInfo> methods = spec.allFeatures*.featureMethod + spec.allFixtureMethods.toList()
+ methods.each {
+ it.addInterceptor(new GebOnFailureReporter())
+ }
+ }
+
@TailRecursive
private boolean isContainerGebSpec(SpecInfo spec) {
if (spec) {
@@ -132,14 +139,5 @@ class GrailsContainerGebExtension implements IGlobalExtension {
}
return false
}
-
-
-
- private static void addGebExtensionOnFailureReporter(SpecInfo spec) {
- List<MethodInfo> methods = spec.allFeatures*.featureMethod + spec.allFixtureMethods.toList()
- methods.each {
- it.addInterceptor(new GebOnFailureReporter())
- }
- }
}
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/GrailsGebSettings.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/GrailsGebSettings.groovy
index 55b6bd2e..5326866c 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/GrailsGebSettings.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/GrailsGebSettings.groovy
@@ -89,12 +89,32 @@ class GrailsGebSettings {
this.startTime = startTime
}
+ boolean isRecordingEnabled() {
+ recordingMode != VncRecordingMode.SKIP
+ }
+
+ @Memoized
+ File getRecordingDirectory() {
+ if (!recordingEnabled) {
+ return null
+ }
+ createDirectory(recordingDirectoryName, 'recording')
+ }
+
+ @Memoized
+ File getReportingDirectory() {
+ if (!reportingDirectoryName) {
+ return null
+ }
+ createDirectory(reportingDirectoryName, 'reporting')
+ }
+
private static boolean getBooleanProperty(String propertyName, boolean defaultValue) {
Boolean.parseBoolean(System.getProperty(propertyName, defaultValue.toString()))
}
private static int getIntProperty(String propertyName, int defaultValue) {
- Integer.getInteger(propertyName, defaultValue) ?: defaultValue
+ System.getProperty(propertyName)?.toInteger() ?: defaultValue
}
private static Number getNumberProperty(String propertyName, Number defaultValue) {
@@ -103,9 +123,8 @@ class GrailsGebSettings {
try {
if (propValue.contains('.')) {
return new BigDecimal(propValue)
- } else {
- return Integer.parseInt(propValue)
}
+ return Integer.parseInt(propValue)
} catch (NumberFormatException ignored) {
log.warn(
'Could not parse property [{}] with value [{}] as a Number. Using default value [{}] instead.',
@@ -118,26 +137,6 @@ class GrailsGebSettings {
return defaultValue
}
- boolean isRecordingEnabled() {
- recordingMode != VncRecordingMode.SKIP
- }
-
- @Memoized
- File getRecordingDirectory() {
- if (!recordingEnabled) {
- return null
- }
- createDirectory(recordingDirectoryName, 'recording')
- }
-
- @Memoized
- File getReportingDirectory() {
- if (!reportingDirectoryName) {
- return null
- }
- createDirectory(reportingDirectoryName, 'reporting')
- }
-
private File createDirectory(String directoryName, String useCase) {
def dir = new File(
"$directoryName$File.separator${DateTimeFormatter.ofPattern('yyyyMMdd_HHmmss').format(startTime)}"
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/WebDriverContainerHolder.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/WebDriverContainerHolder.groovy
index 9beaa695..bab7e1d4 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/WebDriverContainerHolder.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/WebDriverContainerHolder.groovy
@@ -18,7 +18,6 @@
*/
package grails.plugin.geb
-
import org.openqa.selenium.firefox.FirefoxOptions
import java.time.Duration
@@ -76,6 +75,8 @@ class WebDriverContainerHolder {
private static final String DEFAULT_HOSTNAME_FROM_HOST = 'localhost'
private static final String REMOTE_ADDRESS_PROPERTY = 'webdriver.remote.server'
+ private static final String HOST_PORT_PROPERTY = 'hostPort'
+ private static final String BASE_URL_PROPERTY = 'baseUrl'
private static final String DEFAULT_BROWSER = 'firefox'
GrailsGebSettings settings
@@ -102,85 +103,13 @@ class WebDriverContainerHolder {
boolean matchesCurrentContainerConfiguration(WebDriverContainerConfiguration specConf) {
specConf == containerConf &&
- settings.recordingMode == BrowserWebDriverContainer.VncRecordingMode.SKIP
- }
-
- /**
- * Returns a host port to use for the container in this order:
- * Class field 'hostPort' if found in the invocation (Spec).
- * A 'hostPort' property in the GebConfig configuration.
- * @param methodInvocation
- * @return
- */
- private static int findServerPort(IMethodInvocation methodInvocation) {
- // use the test class hostPort if specified
- try {
- return (int) methodInvocation.instance.metaClass.getProperty(
- methodInvocation.instance,
- 'hostPort'
- )
- } catch (ignored) {
- // Grails throws an IllegalStateException about their annotation here. We do not.
- log.info("no hostPort from methodInvocation")
- }
-
- try {
- // use geb config setting or default 8080
- Configuration gebConfig = new ConfigurationLoader().conf
- return (int) gebConfig.rawConfig.getProperty('hostPort')
- } catch (ignored) {
- log.info("no hostPort in config")
- }
-
- log.info("using default hostPort 8080")
- return 8080
- }
-
- /**
- * Returns a baseUrl from a setting if found in this order:
- * A class field 'baseUrl' if found in the invocation (Spec).
- * A 'baseUrl' property in the GebConfig configuration.
- * Or an empty String if not found.
- * @param methodInvocation
- * @return
- */
- private static String findBaseUrl(IMethodInvocation methodInvocation) {
- // use the test class baseUrl if specified
- try {
- String baseUrl = methodInvocation.instance.metaClass.getProperty(
- methodInvocation.instance,
- 'baseUrl'
- )
- if (baseUrl) {
- log.info("using baseUrl: ${baseUrl} from method invocation.")
- return baseUrl
- }
- } catch (ignored) {
- log.info("no baseUrl from methodInvocation")
- }
-
- try {
- // use geb config setting or default
- Configuration gebConfig = new ConfigurationLoader().conf
- String baseUrl = gebConfig.getProperty('baseUrl') ?: ""
- if (baseUrl != "") {
- log.info("using baseUrl: ${baseUrl} from configuration.")
- return baseUrl
- }
- } catch (ignored) {
- log.info("no baseUrl in config.")
- }
-
- log.info("no configured baseUrl found.")
- return ""
-
+ settings.recordingMode == BrowserWebDriverContainer.VncRecordingMode.SKIP
}
-
@PackageScope
boolean reinitialize(IMethodInvocation methodInvocation) {
def specConf = new WebDriverContainerConfiguration(
- methodInvocation.spec
+ methodInvocation.spec
)
if (matchesCurrentContainerConfiguration(specConf)) {
return false
@@ -200,25 +129,25 @@ class WebDriverContainerHolder {
validateDriverConf(gebConf)
if (customBrowser) {
log.info(
- 'A \'containerBrowser\' property was found in GebConfig. ' +
- "Using [$customBrowser] container image."
+ 'A \'containerBrowser\' property was found in GebConfig. ' +
+ "Using [$customBrowser] container image."
)
// Prepare for creating a container matching
// the GebConfig `containerBrowser` property.
dockerImageName = createDockerImageName(customBrowser)
} else {
log.info(
- 'No \'containerBrowser\' property found in GebConfig. ' +
- "Using default [$DEFAULT_BROWSER] container image."
+ 'No \'containerBrowser\' property found in GebConfig. ' +
+ "Using default [$DEFAULT_BROWSER] container image."
)
}
}
containerConf = specConf
container = new BrowserWebDriverContainer(dockerImageName).withRecordingMode(
- settings.recordingMode,
- settings.recordingDirectory,
- settings.recordingFormat
+ settings.recordingMode,
+ settings.recordingDirectory,
+ settings.recordingFormat
)
container.with {
@@ -230,11 +159,10 @@ class WebDriverContainerHolder {
startContainer(container, dockerImageName, customBrowser)
-
if (hostnameChanged) {
container.execInContainer(
- '/bin/sh', '-c',
- "echo '$hostIp\t$containerConf.hostName' | sudo tee -a /etc/hosts"
+ '/bin/sh', '-c',
+ "echo '$hostIp\t$containerConf.hostName' | sudo tee -a /etc/hosts"
)
}
@@ -256,9 +184,9 @@ class WebDriverContainerHolder {
// the `RemoteWebDriver` will be instantiated using the `webdriver.remote.server`
// system property. We set that property to inform the driver of the container address.
gebConf.driverConf = ClosureDecorators.withSystemProperty(
- gebConf.driverConf as Closure,
- REMOTE_ADDRESS_PROPERTY,
- container.seleniumAddress
+ gebConf.driverConf as Closure,
+ REMOTE_ADDRESS_PROPERTY,
+ container.seleniumAddress
)
} else {
// If no driver was set in GebConfig, create a Firefox driver
@@ -284,6 +212,144 @@ class WebDriverContainerHolder {
return true
}
+ void setupBrowserUrl(IMethodInvocation methodInvocation) {
+ if (!browser) {
+ return
+ }
+
+ // use a configured baseUrl if found, otherwise use localhost and hostPort
+ def baseUrl = findBaseUrl(methodInvocation)
+ if (baseUrl != "") {
+ browser.baseUrl = baseUrl
+ } else {
+ int hostPort = findServerPort(methodInvocation)
+ Testcontainers.exposeHostPorts(hostPort)
+ browser.baseUrl = "$containerConf.protocol://$containerConf.hostName:$hostPort"
+ }
+ }
+
+ /**
+ * Returns the hostname that the server under test is available on from the host.
+ * <p>This is useful when using any of the {@code download*()} methods as they will
+ * connect from the host, and not from within the container.
+ *
+ * <p>Defaults to {@code localhost}. If the value returned by {@code webDriverContainer.getHost()}
+ * is different from the default, this method will return the same value same as
+ * {@code webDriverContainer.getHost()}.
+ *
+ * @return the hostname for accessing the server under test from the host
+ */
+ String getHostNameFromHost() {
+ hostNameChanged ? container.host : DEFAULT_HOSTNAME_FROM_HOST
+ }
+
+ /**
+ * Workaround for https://github.com/testcontainers/testcontainers-java/issues/3998
+ * <p>
+ * Restarts the VNC recording container to enable separate recording files for each
+ * test method. This method uses reflection to access the VNC recording container
+ * field in BrowserWebDriverContainer. Should be called BEFORE each test starts.
+ */
+ void restartVncRecordingContainer() {
+ if (!settings.recordingEnabled || !settings.restartRecordingContainerPerTest || !container) {
+ return
+ }
+ try {
+ // Use reflection to access the VNC recording container field
+ def field = BrowserWebDriverContainer.getDeclaredField('vncRecordingContainer').tap {
+ accessible = true
+ }
+
+ def vncContainer = field.get(container) as VncRecordingContainer
+ if (vncContainer) {
+ // Stop the current VNC recording container
+ vncContainer.stop()
+ // Create and start a new VNC recording container for the next test
+ def newVncContainer = new VncRecordingContainer(container)
+ .withVncPassword('secret')
+ .withVncPort(5900)
+ .withVideoFormat(settings.recordingFormat)
+ field.set(container, newVncContainer)
+ newVncContainer.start()
+
+ log.debug('Successfully restarted VNC recording container')
+ }
+ } catch (Exception e) {
+ log.warn("Failed to restart VNC recording container: $e.message", e)
+ // Don't throw the exception to avoid breaking the test execution
+ }
+ }
+
+ /**
+ * Returns a host port to use for the container in this order:
+ * Class field 'hostPort' if found in the invocation (Spec).
+ * A 'hostPort' property in the GebConfig configuration.
+ * @param methodInvocation The method invocation.
+ * @return int The server port.
+ */
+ private static int findServerPort(IMethodInvocation methodInvocation) {
+ // use the test class hostPort if specified
+ try {
+ return (int) methodInvocation.instance.metaClass.getProperty(
+ methodInvocation.instance,
+ HOST_PORT_PROPERTY
+ )
+ } catch (ignored) {
+ // Grails throws an IllegalStateException about their annotation here. We do not.
+ log.info("no ${HOST_PORT_PROPERTY} from methodInvocation")
+ }
+
+ try {
+ // use geb config setting or default 8080
+ Configuration gebConfig = new ConfigurationLoader().conf
+ return (int) gebConfig.rawConfig.getProperty(HOST_PORT_PROPERTY)
+ } catch (ignored) {
+ log.info("no ${HOST_PORT_PROPERTY} in config")
+ }
+
+ log.info("using default ${HOST_PORT_PROPERTY} 8080")
+ return 8080
+ }
+
+ /**
+ * Returns a baseUrl from a setting if found in this order:
+ * A class field 'baseUrl' if found in the invocation (Spec).
+ * A 'baseUrl' property in the GebConfig configuration.
+ * Or an empty String if not found.
+ * @param methodInvocation The method invocation.
+ * @return String The base URL.
+ */
+ private static String findBaseUrl(IMethodInvocation methodInvocation) {
+ // use the test class baseUrl if specified
+ try {
+ String baseUrl = methodInvocation.instance.metaClass.getProperty(
+ methodInvocation.instance,
+ BASE_URL_PROPERTY
+ )
+ if (baseUrl) {
+ log.info("using ${BASE_URL_PROPERTY}: ${baseUrl} from method invocation.")
+ return baseUrl
+ }
+ } catch (ignored) {
+ log.info("no ${BASE_URL_PROPERTY} from methodInvocation")
+ }
+
+ try {
+ // use geb config setting or default
+ Configuration gebConfig = new ConfigurationLoader().conf
+ String baseUrl = gebConfig.getProperty(BASE_URL_PROPERTY) ?: ""
+ if (baseUrl != "") {
+ log.info("using ${BASE_URL_PROPERTY}: ${baseUrl} from configuration.")
+ return baseUrl
+ }
+ } catch (ignored) {
+ log.info("no ${BASE_URL_PROPERTY} in config.")
+ }
+
+ log.info("no configured ${BASE_URL_PROPERTY} found.")
+ return ""
+ }
+
private static Browser createBrowser(Configuration gebConf) {
def browser = new Browser(gebConf)
try {
@@ -313,18 +379,24 @@ class WebDriverContainerHolder {
private static void applyTimeouts(Browser browser, GrailsGebSettings settings) {
// Overwrite `GebConfig` timeouts with values explicitly set in
// `GrailsGebSettings` (via system properties)
- if (settings.implicitlyWait != DEFAULT_TIMEOUT_IMPLICITLY_WAIT)
+ if (settings.implicitlyWait != DEFAULT_TIMEOUT_IMPLICITLY_WAIT) {
browser.driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(settings.implicitlyWait))
- if (settings.pageLoadTimeout != DEFAULT_TIMEOUT_PAGE_LOAD)
+ }
+ if (settings.pageLoadTimeout != DEFAULT_TIMEOUT_PAGE_LOAD) {
browser.driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(settings.pageLoadTimeout))
- if (settings.scriptTimeout != DEFAULT_TIMEOUT_SCRIPT)
+ }
+ if (settings.scriptTimeout != DEFAULT_TIMEOUT_SCRIPT) {
browser.driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(settings.scriptTimeout))
- if (settings.atCheckWaiting != DEFAULT_AT_CHECK_WAITING)
+ }
+ if (settings.atCheckWaiting != DEFAULT_AT_CHECK_WAITING) {
browser.config.atCheckWaiting = settings.atCheckWaiting
- if (settings.timeout != Wait.DEFAULT_TIMEOUT)
+ }
+ if (settings.timeout != Wait.DEFAULT_TIMEOUT) {
(browser.config.rawConfig.waiting as ConfigObject).timeout = settings.timeout
- if (settings.retryInterval != Wait.DEFAULT_RETRY_INTERVAL)
+ }
+ if (settings.retryInterval != Wait.DEFAULT_RETRY_INTERVAL) {
(browser.config.rawConfig.waiting as ConfigObject).retryInterval = settings.retryInterval
+ }
}
private static void startContainer(BrowserWebDriverContainer container, DockerImageName dockerImageName, String customBrowser) {
@@ -344,39 +416,6 @@ class WebDriverContainerHolder {
}
}
- void setupBrowserUrl(IMethodInvocation methodInvocation) {
- if (!browser) return
-
- // use a configured baseUrl if found, otherwise use localhost and hostPort
- def baseUrl = findBaseUrl(methodInvocation)
- if (baseUrl != "") {
- browser.baseUrl = baseUrl
- } else {
- int hostPort = findServerPort(methodInvocation)
- Testcontainers.exposeHostPorts(hostPort)
- browser.baseUrl = "$containerConf.protocol://$containerConf.hostName:$hostPort"
- }
-
- }
-
- private GebTestManager createTestManager() {
- new SpockGebTestManagerBuilder()
- .withReportingEnabled(containerConf.reporting)
- .withBrowserCreator(
- new Supplier<Browser>() {
- @Override
- Browser get() {
- browser
- }
- }
- )
- .build()
- }
-
- private boolean isHostnameChanged() {
- containerConf.hostName != ContainerGebConfiguration.DEFAULT_HOSTNAME_FROM_CONTAINER
- }
-
private static String getHostIp() {
try {
PortForwardingContainer.getDeclaredMethod('getNetwork').with {
@@ -393,25 +432,6 @@ class WebDriverContainerHolder {
}
}
- /**
- * Returns the hostname that the server under test is available on from the host.
- * <p>This is useful when using any of the {@code download*()} methods as they will
- * connect from the host, and not from within the container.
- *
- * <p>Defaults to {@code localhost}. If the value returned by {@code webDriverContainer.getHost()}
- * is different from the default, this method will return the same value same as
- * {@code webDriverContainer.getHost()}.
- *
- * @return the hostname for accessing the server under test from the host
- */
- String getHostNameFromHost() {
- hostNameChanged ? container.host : DEFAULT_HOSTNAME_FROM_HOST
- }
-
- private boolean isHostNameChanged() {
- container.host != ContainerGebConfiguration.DEFAULT_HOSTNAME_FROM_CONTAINER
- }
-
private static DockerImageName createDockerImageName(Object browserName) {
DockerImageName.parse(
"selenium/standalone-$browserName:$seleniumVersion"
@@ -431,6 +451,28 @@ class WebDriverContainerHolder {
SeleniumUtils.determineClasspathSeleniumVersion()
}
+ private GebTestManager createTestManager() {
+ new SpockGebTestManagerBuilder()
+ .withReportingEnabled(containerConf.reporting)
+ .withBrowserCreator(
+ new Supplier<Browser>() {
+ @Override
+ Browser get() {
+ browser
+ }
+ }
+ )
+ .build()
+ }
+
+ private boolean isHostnameChanged() {
+ containerConf.hostName != ContainerGebConfiguration.DEFAULT_HOSTNAME_FROM_CONTAINER
+ }
+
+ private boolean isHostNameChanged() {
+ container.host != ContainerGebConfiguration.DEFAULT_HOSTNAME_FROM_CONTAINER
+ }
+
@CompileStatic
@EqualsAndHashCode
private static class WebDriverContainerConfiguration {
@@ -460,43 +502,6 @@ class WebDriverContainerHolder {
}
}
- /**
- * Workaround for https://github.com/testcontainers/testcontainers-java/issues/3998
- * <p>
- * Restarts the VNC recording container to enable separate recording files for each
- * test method. This method uses reflection to access the VNC recording container
- * field in BrowserWebDriverContainer. Should be called BEFORE each test starts.
- */
- void restartVncRecordingContainer() {
- if (!settings.recordingEnabled || !settings.restartRecordingContainerPerTest || !container) {
- return
- }
- try {
- // Use reflection to access the VNC recording container field
- def field = BrowserWebDriverContainer.getDeclaredField('vncRecordingContainer').tap {
- accessible = true
- }
-
- def vncContainer = field.get(container) as VncRecordingContainer
- if (vncContainer) {
- // Stop the current VNC recording container
- vncContainer.stop()
- // Create and start a new VNC recording container for the next test
- def newVncContainer = new VncRecordingContainer(container)
- .withVncPassword('secret')
- .withVncPort(5900)
- .withVideoFormat(settings.recordingFormat)
- field.set(container, newVncContainer)
- newVncContainer.start()
-
- log.debug('Successfully restarted VNC recording container')
- }
- } catch (Exception e) {
- log.warn("Failed to restart VNC recording container: $e.message", e)
- // Don't throw the exception to avoid breaking the test execution
- }
- }
-
@CompileStatic
private static class ClosureDecorators {
@@ -521,7 +526,7 @@ class WebDriverContainerHolder {
private static class SysPropScope {
private static final ThreadLocal<Map<String,String>> OVERRIDDEN_SYSTEM_PROPERTIES =
- ThreadLocal.withInitial { [:] as Map<String,String> }
+ ThreadLocal.withInitial { [:] } as ThreadLocal<Map<String, String>>
@Lazy // Thread-safe wrapping of system properties
private static Properties propertiesWrappedOnFirstAccess = {
@@ -538,8 +543,14 @@ class WebDriverContainerHolder {
try {
return body.call()
} finally {
- if (prev == null) map.remove(key) else map[key] = prev
- if (map.isEmpty()) OVERRIDDEN_SYSTEM_PROPERTIES.remove()
+ if (prev == null) {
+ map.remove(key)
+ } else {
+ map[key] = prev
+ }
+ if (map.isEmpty()) {
+ OVERRIDDEN_SYSTEM_PROPERTIES.remove()
+ }
}
}
@@ -554,8 +565,4 @@ class WebDriverContainerHolder {
}
}
-
-
-
-
}
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/serviceloader/ServiceRegistry.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/serviceloader/ServiceRegistry.groovy
index 7b18c118..0d2b15a6 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/serviceloader/ServiceRegistry.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/serviceloader/ServiceRegistry.groovy
@@ -42,8 +42,8 @@ import groovy.transform.CompileStatic
class ServiceRegistry {
private static final ThreadLocal<HashMap<Class<?>, Object>> INSTANCES = ThreadLocal.withInitial {
- new HashMap<Class<?>, Object>()
- }
+ [:]
+ } as ThreadLocal<HashMap<Class<?>, Object>>
/**
* Returns the service instance of the given service type, loading it using
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/BrowserType.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/BrowserType.groovy
index 4ebefd32..b6ec9c49 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/BrowserType.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/BrowserType.groovy
@@ -19,12 +19,24 @@
package grails.plugin.geb.support
/**
+ * Represents the supported browser types.
*
+ * <p>This enum defines the available browser options that can be used.</p>
*/
enum BrowserType {
+ /**
+ * Google Chrome browser.
+ */
+
CHROME,
+ /**
+ * Mozilla Firefox browser.
+ */
FIREFOX,
- EDGE
+ /**
+ * Microsoft Edge browser.
+ */
+ EDGE
}
\ No newline at end of file
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/ContainerGebFileInputSource.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/ContainerGebFileInputSource.groovy
index 5ec39d57..23c11650 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/ContainerGebFileInputSource.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/ContainerGebFileInputSource.groovy
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package grails.plugin.geb.support
/**
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/LocalhostDownloadSupport.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/LocalhostDownloadSupport.groovy
index 8f782c97..f2167fc9 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/LocalhostDownloadSupport.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/LocalhostDownloadSupport.groovy
@@ -31,7 +31,7 @@ import java.util.regex.Pattern
@CompileStatic
class LocalhostDownloadSupport extends DefaultDownloadSupport {
- private final static Pattern urlPattern = ~/(https?:\/\/)([^\/:]+)(:\d+\/.*)/
+ private final static Pattern URL_PATTERN = ~/(https?:\/\/)([^\/:]+)(:\d+\/.*)/
private final String hostNameFromHost
private final Browser browser
@@ -48,7 +48,7 @@ class LocalhostDownloadSupport extends DefaultDownloadSupport {
}
private String resolveBase(Map options) {
- return options.base ?: browser.driver.currentUrl.replaceAll(urlPattern) { match, proto, host, rest ->
+ return options.base ?: browser.driver.currentUrl.replaceAll(URL_PATTERN) { match, proto, host, rest ->
"${proto}${hostNameFromHost}${rest}"
}
}
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/delegate/BrowserDelegate.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/delegate/BrowserDelegate.groovy
index 0ad9763a..4809047c 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/delegate/BrowserDelegate.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/delegate/BrowserDelegate.groovy
@@ -386,7 +386,7 @@ trait BrowserDelegate {
* Delegates to {@link geb.Browser#setNetworkLatency(Duration)}.
*/
void setNetworkLatency(Duration duration) {
- browser.setNetworkLatency(duration)
+ browser.networkLatency = duration
}
/**
diff --git a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/delegate/PageDelegate.groovy b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/delegate/PageDelegate.groovy
index 1706abe5..cbd5f259 100644
--- a/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/delegate/PageDelegate.groovy
+++ b/integration/geb-testcontainers/src/main/groovy/grails/plugin/geb/support/delegate/PageDelegate.groovy
@@ -409,7 +409,7 @@ trait PageDelegate implements Navigable, AlertAndConfirmSupport, WaitingSupport,
}
@Override
- void interact(@DelegatesTo(strategy = 1, value = InteractDelegate.class) Closure interactionClosure) {
+ void interact(@DelegatesTo(strategy = 1, value = InteractDelegate) Closure interactionClosure) {
page.interact(interactionClosure)
}
}
\ No newline at end of file
(groovy-geb) 03/03: remove codenarc issue from the temporary section of README.md.
Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
cmarcum pushed a commit to branch task/geb-testcontainers
in repository https://gitbox.apache.org/repos/asf/groovy-geb.git
commit 120e2c5bc37ef0ace725bcce532f7cea34e9d0ba
Author: Carl Marcum <ca...@codebuilders.net>
AuthorDate: Sun Feb 15 10:38:58 2026 -0500
remove codenarc issue from the temporary section of README.md.
---
integration/geb-testcontainers/README.md | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/integration/geb-testcontainers/README.md b/integration/geb-testcontainers/README.md
index 88ebd2d4..aad74240 100644
--- a/integration/geb-testcontainers/README.md
+++ b/integration/geb-testcontainers/README.md
@@ -22,13 +22,7 @@ A library to support using Testcontainers in Apache Geb integration testing.
Currently, this library is a work in progress and is not yet ready for production use.
-Work is ongoing to fix a number of codenarc issues and remove some remaining Grails references.
-
-To run the build or run tests, you have to exclude the codenarc tasks.
-
-```shell
-./gradlew check --rerun-tasks -x codenarcMain -x codenarcTest -x codenarcIntegrationTest
-```
+Work is ongoing to remove some remaining Grails references.
## Geb Functional Testing using Testcontainers