Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge 4.2.x into 5.0.x #130

Merged
merged 23 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3ff12e8
fix: enhance IDE autocompletion
matrei Jan 19, 2025
59feccc
build: include parameter metadata in compiled Groovy classes
matrei Jan 23, 2025
64ab651
fix: improve DX by using manual delegation to Geb API
matrei Jan 23, 2025
b84630d
docs: correct `@since` version in Javadoc for `ContainerSupport`
matrei Jan 23, 2025
1a6e12a
build: user setter syntax for Gradle compatibility
matrei Jan 23, 2025
60e3448
build: cleanup
matrei Jan 23, 2025
9019e30
docs: set correct year in license header
matrei Jan 23, 2025
c73b351
docs: add license header and Javadoc to `ReportingSupport`
matrei Jan 23, 2025
e5ade0b
Merge pull request #126 from grails/matrei/ide-autocompletion
matrei Jan 31, 2025
29fe3e0
build(deps): bump `com.github.ben-manes.versions` from 0.51.0 to 0.52.0
matrei Jan 31, 2025
a03e206
build(deps): bump `com.github.javaparser:javaparser-core` from 3.26.2…
matrei Jan 31, 2025
d3d2f30
chore(deps): bump `selenium` from 4.27.0 to 4.28.1
matrei Jan 31, 2025
dad7967
test: fix error on windows test
matrei Jan 31, 2025
01974cb
test: use new API in integration test
matrei Jan 31, 2025
e09f73c
chore(deps): bump Grails from 6.2.2 to 6.2.3
matrei Jan 31, 2025
6a2e2d2
chore(deps): bump `grails-gradle-plugin` from 6.2.3 to 6.2.4
matrei Jan 31, 2025
f0c34a8
chore: simplify GString expression
matrei Jan 31, 2025
7fdb691
build(deps): bump `gradle-wrapper` in test project from 7.6.2 to 7.6.4
matrei Jan 31, 2025
a2c5e8c
build(deps): bump `com.gradle.develocity` from 3.18.2 to 3.19.1
matrei Jan 31, 2025
1854e10
build(deps): bump `common-custom-user-data` from 2.0.2 to 2.1
matrei Jan 31, 2025
738da03
ci: update GitHub workflows
matrei Jan 31, 2025
bb95d0c
Merge pull request #129 from grails/matrei/chores-4.2.x
matrei Jan 31, 2025
5c65d06
Merge branch '4.2.x' into merge-4.2.x-into-5.0.x
matrei Jan 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ jobs:
- name: "🐘 Setup Gradle"
uses: gradle/actions/setup-gradle@v4
with:
develocity-access-key: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- name: "🔨 Build project"
id: build
env:
GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build
run: ./gradlew build --continue
- name: "🏃‍♀️Run functional tests"
env:
GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
run: |
cd spock-container-test-app
./gradlew check
./gradlew check --continue
publish:
if: github.event_name == 'push'
runs-on: ubuntu-latest
Expand All @@ -52,7 +52,7 @@ jobs:
- name: "🐘 Setup Gradle"
uses: gradle/actions/setup-gradle@v4
with:
develocity-access-key: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- name: "📤 Publish Snapshot version to Artifactory (repo.grails.org)"
env:
MAVEN_PUBLISH_USERNAME: ${{ secrets.MAVEN_PUBLISH_USERNAME }}
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ jobs:
- name: "🐘 Setup Gradle"
uses: gradle/actions/setup-gradle@v4
with:
develocity-access-key: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- name: "📝 Store the current release version"
id: release_version
run: echo "release_version=${GITHUB_REF:11}" >> $GITHUB_OUTPUT
- name: "⚙ Run pre-release"
- name: "⚙ Run pre-release"
uses: grails/github-actions/pre-release@main
- name: "🔐 Generate key file for artifact signing"
env:
Expand All @@ -38,13 +38,13 @@ jobs:
NEXUS_PUBLISH_STAGING_PROFILE_ID: ${{ secrets.NEXUS_PUBLISH_STAGING_PROFILE_ID }}
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }}
SECRING_FILE: ${{ secrets.SECRING_FILE }}
GITHUB_MAVEN_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
run: >
./gradlew
-Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg
publishToSonatype
closeAndReleaseSonatypeStagingRepository
--no-build-cache
-Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg
- name: "📖 Generate Documentation"
id: docs
if: steps.publish.outcome == 'success'
Expand Down
20 changes: 12 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
}

plugins {
id 'com.github.ben-manes.versions' version '0.51.0'
id 'com.github.ben-manes.versions' version '0.52.0'
}

version = projectVersion
Expand Down Expand Up @@ -84,23 +84,27 @@ grailsPublish {

tasks.withType(Groovydoc).configureEach {
destinationDir = layout.buildDirectory.dir('docs/api').get().asFile
docTitle = "Grails Geb Plugin ${version}"
docTitle = "Grails Geb Plugin $version"
classpath = configurations.documentation
source = files(source, sourceSets.testFixtures.allSource)
}

tasks.withType(Test).configureEach {
useJUnitPlatform()
testLogging {
events 'passed', 'skipped', 'failed'
showExceptions true
exceptionFormat 'full'
showCauses true
showStackTraces true
events('passed', 'skipped', 'failed')
showExceptions = true
exceptionFormat = 'full'
showCauses = true
showStackTraces = true
}
}

tasks.named('bootJar') { enabled = false }
tasks.withType(GroovyCompile).configureEach {
// Preserve method parameter names in Groovy classes for IDE parameter hints.
groovyOptions.parameters = true
}

tasks.named('bootRun') { enabled = false }
tasks.named('bootTestRun') { enabled = false }
tasks.named('findMainClass') { enabled = false }
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
projectVersion=5.0.0-SNAPSHOT
grailsVersion=7.0.0-M1
grailsGradlePluginVersion=7.0.0-SNAPSHOT
seleniumVersion=4.27.0
seleniumVersion=4.28.1
testcontainersVersion=1.20.4

# This prevents the Grails Gradle Plugin from unnecessarily excluding slf4j-simple in the generated POMs
Expand Down
4 changes: 2 additions & 2 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'com.gradle.develocity' version '3.18.2'
id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.0.2'
id 'com.gradle.develocity' version '3.19.1'
id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.1'
}

def isCI = System.getenv('CI') != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,38 @@ class UploadSpec extends ContainerGebSpec {
@Requires({ os.windows })
void 'should be able to upload files on a Windows host'() {
given:
to UploadPage
def uploadPage = to UploadPage

when:
fileInput.file = createFileInputSource(
uploadPage.fileInput.file = createFileInputSource(
'src/integration-test/resources/assets/upload-test.txt',
'/tmp/upload-test.txt'
)

and:
submitBtn.click()
uploadPage.submitBtn.click()

then:
title == 'File Uploaded'
browser.pageSource.contains('File uploaded successfully')
pageSource.contains('File uploaded successfully')
}

@IgnoreIf({ os.windows })
void 'should be able to upload files on a non-Windows host'() {
given:
to UploadPage
def uploadPage = to UploadPage

when:
fileInput.file = createFileInputSource(
uploadPage.fileInput.file = createFileInputSource(
'src/integration-test/resources/assets/upload-test.txt',
'/tmp/upload-test.txt'
)

and:
submitBtn.click()
uploadPage.submitBtn.click()

then:
title == 'File Uploaded'
browser.driver.pageSource.contains('File uploaded successfully')
pageSource.contains('File uploaded successfully')
}
}

This file was deleted.

52 changes: 11 additions & 41 deletions src/testFixtures/groovy/grails/plugin/geb/ContainerGebSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
*/
package grails.plugin.geb

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 org.testcontainers.containers.BrowserWebDriverContainer
import org.testcontainers.images.builder.Transferable
import grails.plugin.geb.support.ContainerSupport
import grails.plugin.geb.support.ReportingSupport
import grails.plugin.geb.support.delegate.BrowserDelegate
import grails.plugin.geb.support.delegate.DownloadSupportDelegate
import grails.plugin.geb.support.delegate.DriverDelegate
import grails.plugin.geb.support.delegate.PageDelegate
import groovy.transform.CompileStatic
import spock.lang.Shared
import spock.lang.Specification

Expand All @@ -47,43 +47,13 @@ import spock.lang.Specification
* @author James Daugherty
* @since 4.1
*/
@DynamicallyDispatchesToBrowser
abstract class ContainerGebSpec extends Specification implements ContainerAwareDownloadSupport {
@CompileStatic
abstract class ContainerGebSpec extends Specification implements ContainerSupport, ReportingSupport, BrowserDelegate, PageDelegate, DriverDelegate, DownloadSupportDelegate {

@Shared
@Delegate(includes = ['getBrowser', 'report'])
@SuppressWarnings('unused')
static GebTestManager testManager

/**
* Get access to container running the web-driver, for convenience to execInContainer, copyFileToContainer etc.
*
* @see org.testcontainers.containers.ContainerState#execInContainer(java.lang.String ...)
* @see org.testcontainers.containers.ContainerState#copyFileToContainer(org.testcontainers.utility.MountableFile, java.lang.String)
* @see org.testcontainers.containers.ContainerState#copyFileFromContainer(java.lang.String, java.lang.String)
* @see org.testcontainers.containers.ContainerState
*/
@Shared
static BrowserWebDriverContainer container

/**
* The reporter that Geb should use when reporting is enabled.
*/
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)
static void setTestManager(GebTestManager testManager) {
this.testManager = testManager
}
}
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 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.containers.BrowserWebDriverContainer
import org.testcontainers.images.builder.Transferable
import spock.lang.Shared

/**
* Features for supporting Geb tests running in a container.
*
* @author Mattias Reichel
* @since 4.2
*/
@CompileStatic
@SelfType(ContainerGebSpec)
trait ContainerSupport implements DownloadSupport {

/**
* Get access to container running the web-driver, for convenience to execInContainer, copyFileToContainer etc.
*
* @see org.testcontainers.containers.ContainerState#execInContainer(java.lang.String ...)
* @see org.testcontainers.containers.ContainerState#copyFileToContainer(org.testcontainers.utility.MountableFile, java.lang.String)
* @see org.testcontainers.containers.ContainerState#copyFileFromContainer(java.lang.String, java.lang.String)
* @see org.testcontainers.containers.ContainerState
*/
@Shared
static BrowserWebDriverContainer container

static void setContainer(BrowserWebDriverContainer container) {
this.container = container
}

@Shared
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)
}
}
Loading
Loading