This is an automated email from the ASF dual-hosted git repository.

jonnybot pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy-geb.git


The following commit(s) were added to refs/heads/master by this push:
     new 61704326 Support Closure<CharSequence> JS execution script argument
61704326 is described below

commit 617043264ad81d7e38b2bd735461885a1c957973
Author: Björn Kautler <[email protected]>
AuthorDate: Mon May 26 19:25:15 2025 +0200

    Support Closure<CharSequence> JS execution script argument
---
 .../javascript/ExecutingArbitraryCodeSpec.groovy   | 23 +++++++++++++++++++++-
 doc/manual/src/docs/asciidoc/080-javascript.adoc   |  7 +++++++
 .../main/groovy/geb/js/JavascriptInterface.groovy  |  5 ++++-
 .../test/groovy/geb/JavascriptInterfaceSpec.groovy | 14 +++++++++++++
 4 files changed, 47 insertions(+), 2 deletions(-)

diff --git 
a/doc/manual-snippets/src/test/groovy/javascript/ExecutingArbitraryCodeSpec.groovy
 
b/doc/manual-snippets/src/test/groovy/javascript/ExecutingArbitraryCodeSpec.groovy
index eba3517b..c3d6be99 100644
--- 
a/doc/manual-snippets/src/test/groovy/javascript/ExecutingArbitraryCodeSpec.groovy
+++ 
b/doc/manual-snippets/src/test/groovy/javascript/ExecutingArbitraryCodeSpec.groovy
@@ -44,10 +44,31 @@ class ExecutingArbitraryCodeSpec extends 
GebSpecWithCallbackServer {
         expect:
         // tag::multiline[]
         js.exec 1, 2, """
-            someJsMethod(1, 2);
+            someJsMethod(arguments[0], arguments[1]);
             // lots of javascript
             return true;
         """
         // end::multiline[]
     }
+
+    def "closure"() {
+        given:
+        html {
+            script(type: "text/javascript", """
+                function someJsMethod(a,b) {
+                }
+            """)
+        }
+
+        expect:
+        // tag::closure[]
+        js.exec(1, 2) {
+            """
+                someJsMethod(arguments[0], arguments[1]);
+                // lots of javascript
+                return true;
+            """
+        }
+        // end::closure[]
+    }
 }
diff --git a/doc/manual/src/docs/asciidoc/080-javascript.adoc 
b/doc/manual/src/docs/asciidoc/080-javascript.adoc
index d8c850dd..2f74d5bd 100644
--- a/doc/manual/src/docs/asciidoc/080-javascript.adoc
+++ b/doc/manual/src/docs/asciidoc/080-javascript.adoc
@@ -121,6 +121,13 @@ You might be wondering why the order has been changed 
(i.e. the arguments go _be
 
include::{snippets-dir}/javascript/ExecutingArbitraryCodeSpec.groovy[tag=multiline,indent=0]
 ----
 
+Alternatively, you can give a `Closure` as last argument that returns the 
script to enable the following syntax...
+
+[source,groovy]
+----
+include::{snippets-dir}/javascript/ExecutingArbitraryCodeSpec.groovy[tag=closure,indent=0]
+----
+
 [[waiting]]
 == Waiting
 
diff --git a/module/geb-core/src/main/groovy/geb/js/JavascriptInterface.groovy 
b/module/geb-core/src/main/groovy/geb/js/JavascriptInterface.groovy
index 66636d0b..51bb9640 100644
--- a/module/geb-core/src/main/groovy/geb/js/JavascriptInterface.groovy
+++ b/module/geb-core/src/main/groovy/geb/js/JavascriptInterface.groovy
@@ -54,8 +54,11 @@ class JavascriptInterface {
             jsArgs = args[0..(args.size() - 2)]
         }
 
+        if (script instanceof Closure) {
+            script = script()
+        }
         if (!(script instanceof CharSequence)) {
-            throw new IllegalArgumentException("The last argument to the js 
function must be string-like")
+            throw new IllegalArgumentException("The last argument to the js 
function must be string-like or a Closure returning a string-like")
         }
 
         execjs(script.toString(), *jsArgs)
diff --git a/module/geb-core/src/test/groovy/geb/JavascriptInterfaceSpec.groovy 
b/module/geb-core/src/test/groovy/geb/JavascriptInterfaceSpec.groovy
index a26438b1..108a8840 100644
--- a/module/geb-core/src/test/groovy/geb/JavascriptInterfaceSpec.groovy
+++ b/module/geb-core/src/test/groovy/geb/JavascriptInterfaceSpec.groovy
@@ -125,6 +125,20 @@ class JavascriptInterfaceSpec extends 
GebSpecWithCallbackServer {
         mod.v2 == 8
     }
 
+    def "closure as script generator"() {
+        expect: "we can read the vars"
+        js.v1 == 1
+        js.v2 == 2
+        when: "we use the javascript call syntax with Closure"
+        def r = js.exec(5, 6) {
+            "return changeVars(arguments[0], arguments[1]);"
+        }
+        then: "the call result is returned and it changed the vars"
+        r == "coming back"
+        js.v1 == 5
+        js.v2 == 6
+    }
+
     /**
      * The JavascriptExecutor interface says NOTHING about script errors
      * so there is not much we can do here unfortunately.

Reply via email to