From 3ff12e879757de6b343c90fc61764672641fa841 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Sun, 19 Jan 2025 16:48:55 +0100 Subject: [PATCH] fix: enhance IDE autocompletion This commit introduces explicit delegation to improve convenience and support for IDE autocompletion. The following delegates have been added: - `browser` object delegate - `page` object delegate - `report(String)` method delegate - `getPageSource()` method delegate - Refactor `ContainerAwareDownloadSupport` to a more generic support trait and move `createFileInputSource` method to it. - Move support classes to `support` package. --- build.gradle | 7 ++ .../geb/ContainerAwareDownloadSupport.groovy | 48 -------------- .../grails/plugin/geb/ContainerGebSpec.groovy | 47 +++++++------- .../geb/GrailsContainerGebExtension.groovy | 3 +- .../geb/support/ContainerSupport.groovy | 64 +++++++++++++++++++ .../LocalhostDownloadSupport.groovy | 6 +- 6 files changed, 100 insertions(+), 75 deletions(-) delete mode 100644 src/testFixtures/groovy/grails/plugin/geb/ContainerAwareDownloadSupport.groovy create mode 100644 src/testFixtures/groovy/grails/plugin/geb/support/ContainerSupport.groovy rename src/testFixtures/groovy/grails/plugin/geb/{ => support}/LocalhostDownloadSupport.groovy (92%) diff --git a/build.gradle b/build.gradle index 02d276c..4ed45cc 100644 --- a/build.gradle +++ b/build.gradle @@ -92,5 +92,12 @@ java { sourceCompatibility = JavaVersion.VERSION_11 } +tasks.withType(GroovyCompile).configureEach { + // Preserve method parameter names in compiled Groovy classes + // IDE support for parameter hints + options.debug = true + options.compilerArgs << '--parameters' +} + tasks.named('bootRun') { enabled = false } tasks.named('findMainClass') { enabled = false } \ No newline at end of file diff --git a/src/testFixtures/groovy/grails/plugin/geb/ContainerAwareDownloadSupport.groovy b/src/testFixtures/groovy/grails/plugin/geb/ContainerAwareDownloadSupport.groovy deleted file mode 100644 index d612578..0000000 --- a/src/testFixtures/groovy/grails/plugin/geb/ContainerAwareDownloadSupport.groovy +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ -package grails.plugin.geb - -import geb.download.DownloadSupport -import groovy.transform.CompileStatic -import groovy.transform.SelfType -import spock.lang.Shared - -/** - * A custom implementation of {@link geb.download.DownloadSupport} for enabling the use of its {@code download*()} methods - * within {@code ContainerGebSpec} environments. - * - *

This implementation is based on {@code DefaultDownloadSupport} from Geb, with modifications to support - * containerized environments. Specifically, it enables file downloads by resolving URLs relative to the host - * rather than the internal hostname used by the browser within the container.

- * - *

These adaptations allow the download functionality to operate correctly when tests are executed in containerized - * setups, ensuring the host network context is used for download requests.

- * - * @author Mattias Reichel - * @since 4.1 - */ -@CompileStatic -@SelfType(ContainerGebSpec) -trait ContainerAwareDownloadSupport implements DownloadSupport { - - @Delegate - @Shared - static DownloadSupport downloadSupport - - static void setDownloadSupport(DownloadSupport downloadSupport) { - this.downloadSupport = downloadSupport - } -} \ 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 index 59c7569..8374e42 100644 --- a/src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy +++ b/src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy @@ -15,14 +15,15 @@ */ package grails.plugin.geb +import geb.Browser +import geb.Page import geb.report.CompositeReporter import geb.report.PageSourceReporter import geb.report.Reporter import geb.test.GebTestManager import geb.transform.DynamicallyDispatchesToBrowser -import grails.plugin.geb.support.ContainerGebFileInputSource +import grails.plugin.geb.support.ContainerSupport import org.testcontainers.containers.BrowserWebDriverContainer -import org.testcontainers.images.builder.Transferable import spock.lang.Shared import spock.lang.Specification @@ -48,12 +49,7 @@ import spock.lang.Specification * @since 4.1 */ @DynamicallyDispatchesToBrowser -abstract class ContainerGebSpec extends Specification implements ContainerAwareDownloadSupport { - - @Shared - @Delegate(includes = ['getBrowser', 'report']) - @SuppressWarnings('unused') - static GebTestManager testManager +abstract class ContainerGebSpec extends Specification implements ContainerSupport { /** * Get access to container running the web-driver, for convenience to execInContainer, copyFileToContainer etc. @@ -66,6 +62,27 @@ abstract class ContainerGebSpec extends Specification implements ContainerAwareD @Shared static BrowserWebDriverContainer container + @Shared + static GebTestManager testManager + + @Delegate(interfaces = false) + Page getPage() { + testManager.browser.page + } + + @Delegate + Browser getBrowser() { + testManager.browser + } + + void report(String message) { + testManager.report(message) + } + + String getPageSource() { + testManager.browser.driver.pageSource + } + static void setTestManager(GebTestManager testManager) { this.testManager = testManager } @@ -80,18 +97,4 @@ abstract class ContainerGebSpec extends Specification implements ContainerAwareD Reporter createReporter() { new CompositeReporter(new PageSourceReporter()) } - - /** - * Copies a file from the host to the container for assignment to a Geb FileInput module. - * This method is useful when you need to upload a file to a form in a Geb test and will work cross-platform. - * - * @param hostPath relative path to the file on the host - * @param containerPath absolute path to where to put the file in the container - * @return the file object to assign to the FileInput module - * @since 4.2 - */ - File createFileInputSource(String hostPath, String containerPath) { - container.copyFileToContainer(Transferable.of(new File(hostPath).bytes), containerPath) - return new ContainerGebFileInputSource(containerPath) - } } \ No newline at end of file diff --git a/src/testFixtures/groovy/grails/plugin/geb/GrailsContainerGebExtension.groovy b/src/testFixtures/groovy/grails/plugin/geb/GrailsContainerGebExtension.groovy index 8538d23..62d8a82 100644 --- a/src/testFixtures/groovy/grails/plugin/geb/GrailsContainerGebExtension.groovy +++ b/src/testFixtures/groovy/grails/plugin/geb/GrailsContainerGebExtension.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2024 original author or authors + * Copyright 2024-2025 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. @@ -15,6 +15,7 @@ */ package grails.plugin.geb +import grails.plugin.geb.support.LocalhostDownloadSupport import grails.testing.mixin.integration.Integration import groovy.transform.CompileStatic import groovy.transform.TailRecursive diff --git a/src/testFixtures/groovy/grails/plugin/geb/support/ContainerSupport.groovy b/src/testFixtures/groovy/grails/plugin/geb/support/ContainerSupport.groovy new file mode 100644 index 0000000..fca709d --- /dev/null +++ b/src/testFixtures/groovy/grails/plugin/geb/support/ContainerSupport.groovy @@ -0,0 +1,64 @@ +/* + * Copyright 2024-2025 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. + */ +package grails.plugin.geb.support + +import geb.download.DownloadSupport +import grails.plugin.geb.ContainerGebSpec +import groovy.transform.CompileStatic +import groovy.transform.SelfType +import org.testcontainers.images.builder.Transferable +import spock.lang.Shared + +/** + * Features for supporting Geb tests running in a container. + * + * @author Mattias Reichel + * @since 4.1 + */ +@CompileStatic +@SelfType(ContainerGebSpec) +trait ContainerSupport implements DownloadSupport { + + @Shared + @Delegate + static DownloadSupport downloadSupport + + /** + * Sets the {@link DownloadSupport} instance to use for file downloads. + * This allows for setting a custom implementation of {@code DownloadSupport} + * when downloading from a container. + * + * @param downloadSupport the {@code DownloadSupport} instance to use + * @since 4.1 + */ + static void setDownloadSupport(DownloadSupport downloadSupport) { + this.downloadSupport = downloadSupport + } + + /** + * Copies a file from the host to the container for assignment to a Geb FileInput module. + * This method is useful when you need to upload a file to a form in a Geb test and will work cross-platform. + * + * @param hostPath relative path to the file on the host + * @param containerPath absolute path to where to put the file in the container + * @return the file object to assign to the FileInput module + * @since 4.2 + */ + File createFileInputSource(String hostPath, String containerPath) { + container.copyFileToContainer(Transferable.of(new File(hostPath).bytes), containerPath) + return new ContainerGebFileInputSource(containerPath) + } +} \ No newline at end of file diff --git a/src/testFixtures/groovy/grails/plugin/geb/LocalhostDownloadSupport.groovy b/src/testFixtures/groovy/grails/plugin/geb/support/LocalhostDownloadSupport.groovy similarity index 92% rename from src/testFixtures/groovy/grails/plugin/geb/LocalhostDownloadSupport.groovy rename to src/testFixtures/groovy/grails/plugin/geb/support/LocalhostDownloadSupport.groovy index a1a9ade..f647f27 100644 --- a/src/testFixtures/groovy/grails/plugin/geb/LocalhostDownloadSupport.groovy +++ b/src/testFixtures/groovy/grails/plugin/geb/support/LocalhostDownloadSupport.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2024 original author or authors + * Copyright 2024-2025 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. @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package grails.plugin.geb +package grails.plugin.geb.support import geb.Browser import geb.download.DefaultDownloadSupport import groovy.transform.CompileStatic -import groovy.transform.PackageScope import java.util.regex.Pattern @@ -26,7 +25,6 @@ import java.util.regex.Pattern * @author Mattias Reichel * @since 4.1 */ -@PackageScope @CompileStatic class LocalhostDownloadSupport extends DefaultDownloadSupport {