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 ad722dd6 Separate the dynamic page content of PageOrientedSpec to only 
the page that expects it
ad722dd6 is described below

commit ad722dd6eeaa366862baa2757670f50448b82ded
Author: Björn Kautler <[email protected]>
AuthorDate: Wed May 14 10:52:57 2025 +0200

    Separate the dynamic page content of PageOrientedSpec to only the page that 
expects it
    
    With JavaScript enabled, the JavaScript thread modifies the page and with 
unlucky timing
    the link element needed is either not present when checked for in 
at-checking, or is stale
    when trying to click it. This makes the tests not actually needing the 
dynamic element
    flaky, failing occasionally for content not found or stale elements.
---
 .../test/groovy/geb/PageOrientedDynamicSpec.groovy | 116 +++++++++++++++++++++
 .../src/test/groovy/geb/PageOrientedSpec.groovy    |  64 ------------
 2 files changed, 116 insertions(+), 64 deletions(-)

diff --git a/module/geb-core/src/test/groovy/geb/PageOrientedDynamicSpec.groovy 
b/module/geb-core/src/test/groovy/geb/PageOrientedDynamicSpec.groovy
new file mode 100644
index 00000000..0c741708
--- /dev/null
+++ b/module/geb-core/src/test/groovy/geb/PageOrientedDynamicSpec.groovy
@@ -0,0 +1,116 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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
+ *
+ *    http://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 geb
+
+import geb.test.GebSpecWithCallbackServer
+import spock.lang.Unroll
+
+class PageOrientedDynamicSpec extends GebSpecWithCallbackServer {
+
+    def setupSpec() {
+        callbackServer.get = { req, res ->
+            def path = req.requestURI == "/b" ? "b" : "a"
+            def other = path == "b" ? "a" : "b"
+            res.outputStream << "<html>"
+            if (path == "b") {
+                res.outputStream << """
+                <head>
+                    <script type="text/javascript" charset="utf-8">
+                    setTimeout(function() {
+                        document.body.innerHTML += '<div 
id="dynamic">dynamic</div>';
+                    }, 100);
+                    </script>
+                </head>"""
+            }
+            res.outputStream << """
+            <body>
+                <a href="/$other" id="$path">$other</a>
+                <div id="uri">$req.requestURI</div>
+                <input type="text" name="input"></input>
+            </body>"""
+        }
+    }
+
+    @Unroll
+    def "implicitly waits when at checking if toWait content option is 
specified for '#contentName' content"() {
+        when:
+        to PageOrientedDynamicSpecPageA
+
+        and:
+        page[contentName].click()
+
+        then:
+        page in PageOrientedDynamicSpecPageC
+
+        where:
+        contentName << ["linkWithToWait", "linkWithToWaitUsingPageInstance"]
+    }
+
+    def "implicitly waits when at checking after clicking on content that has 
to option specified if global atCheckWaiting is specified"() {
+        given:
+        config.atCheckWaiting = true
+
+        when:
+        to PageOrientedDynamicSpecPageA
+
+        and:
+        linkToPageWithDynamicContent.click()
+
+        then:
+        page in PageOrientedDynamicSpecPageC
+    }
+
+    @Unroll
+    def "implicitly waits when at checking if toWait content option is 
specified and to option contains a list of candidates for '#contentName' 
content"() {
+        when:
+        to PageOrientedDynamicSpecPageA
+
+        and:
+        page[contentName].click()
+
+        then:
+        page in PageOrientedDynamicSpecPageC
+
+        where:
+        contentName << ["linkWithToWaitAndVariantTo", 
"linkWithToWaitAndVariantToUsingPageInstances"]
+    }
+}
+
+class PageOrientedDynamicSpecPageA extends Page {
+    static at = { link }
+    static content = {
+        link { $("#a") }
+        linkToPageWithDynamicContent(to: PageOrientedDynamicSpecPageC) { link }
+        linkWithToWait(to: PageOrientedDynamicSpecPageC, toWait: true) { link }
+        linkWithToWaitUsingPageInstance(to: new 
PageOrientedDynamicSpecPageC(), toWait: true) { link }
+        linkWithToWaitAndVariantTo(to: [PageOrientedDynamicSpecPageB, 
PageOrientedDynamicSpecPageC], toWait: true) { link }
+        linkWithToWaitAndVariantToUsingPageInstances(to: [new 
PageOrientedDynamicSpecPageB(), new PageOrientedDynamicSpecPageC()], toWait: 
true) { link }
+    }
+}
+
+class PageOrientedDynamicSpecPageB extends Page {
+    static at = { false }
+}
+
+class PageOrientedDynamicSpecPageC extends Page {
+    static at = { dynamic }
+    static content = {
+        dynamic { $("#dynamic") }
+    }
+}
diff --git a/module/geb-core/src/test/groovy/geb/PageOrientedSpec.groovy 
b/module/geb-core/src/test/groovy/geb/PageOrientedSpec.groovy
index e4a83d2c..7276c894 100644
--- a/module/geb-core/src/test/groovy/geb/PageOrientedSpec.groovy
+++ b/module/geb-core/src/test/groovy/geb/PageOrientedSpec.groovy
@@ -32,13 +32,6 @@ class PageOrientedSpec extends GebSpecWithCallbackServer {
             def other = path == "b" ? "a" : "b"
             res.outputStream << """
             <html>
-                <head>
-                    <script type="text/javascript" charset="utf-8">
-                    setTimeout(function() {
-                        document.body.innerHTML += '<div 
id="dynamic">dynamic</div>';
-                    }, 100);
-                    </script>
-                </head>
                 <body>
                     <a href="/$other" id="$path">$other</a>
                     <div id="uri">$req.requestURI</div>
@@ -342,50 +335,6 @@ class PageOrientedSpec extends GebSpecWithCallbackServer {
         PageContentPageInstancePageParam | 'instance'   | new 
PageContentPageInstancePageParam()
     }
 
-    @Unroll
-    def "implicitly waits when at checking if toWait content option is 
specified for '#contentName' content"() {
-        when:
-        to PageOrientedSpecPageA
-
-        and:
-        page[contentName].click()
-
-        then:
-        page in PageOrientedSpecPageE
-
-        where:
-        contentName << ["linkWithToWait", "linkWithToWaitUsingPageInstance"]
-    }
-
-    def "implicitly waits when at checking after clicking on content that has 
to option specified if global atCheckWaiting is specified"() {
-        given:
-        config.atCheckWaiting = true
-
-        when:
-        to PageOrientedSpecPageA
-
-        and:
-        linkToPageWithDynamicContent.click()
-
-        then:
-        page in PageOrientedSpecPageE
-    }
-
-    @Unroll
-    def "implicitly waits when at checking if toWait content option is 
specified and to option contains a list of candidates for '#contentName' 
content"() {
-        when:
-        to PageOrientedSpecPageA
-
-        and:
-        page[contentName].click()
-
-        then:
-        page in PageOrientedSpecPageE
-
-        where:
-        contentName << ["linkWithToWaitAndVariantTo", 
"linkWithToWaitAndVariantToUsingPageInstances"]
-    }
-
     def "unrecognized content template parameters are reported"() {
         when:
         to PageWithContentUsingUnrecognizedParams
@@ -511,11 +460,6 @@ class PageOrientedSpecPageA extends Page {
         linkWithVariantToUsingPageInstances(to: [new PageOrientedSpecPageD(), 
new PageOrientedSpecPageC(), new PageOrientedSpecPageB()]) { link }
         linkWithVariantToNoMatches(to: [PageOrientedSpecPageD, 
PageOrientedSpecPageC]) { link }
         linkWithVariantToNoMatchesUsingPageInstances(to: [new 
PageOrientedSpecPageD(), new PageOrientedSpecPageC()]) { link }
-        linkToPageWithDynamicContent(to: PageOrientedSpecPageE) { link }
-        linkWithToWait(to: PageOrientedSpecPageE, toWait: true) { link }
-        linkWithToWaitUsingPageInstance(to: new PageOrientedSpecPageE(), 
toWait: true) { link }
-        linkWithToWaitAndVariantTo(to: [PageOrientedSpecPageC, 
PageOrientedSpecPageE], toWait: true) { link }
-        linkWithToWaitAndVariantToUsingPageInstances(to: [new 
PageOrientedSpecPageC(), new PageOrientedSpecPageE()], toWait: true) { link }
         linkText { link.text().trim() }
         linkTextAlias(aliases: 'linkText')
         notPresentValueRequired { $("div#asdfasdf").text() }
@@ -544,14 +488,6 @@ class PageOrientedSpecPageD extends Page {
     static at = { assert 1 == 2 }
 }
 
-class PageOrientedSpecPageE extends Page {
-    static at = { dynamic }
-    static content = {
-        dynamic { $("#dynamic") }
-    }
-
-}
-
 class ConvertPage extends Page {
     static url = '/theview'
 

Reply via email to