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 jo...@apache.org on 2025/05/20 21:42:45 UTC
(groovy-geb) branch master updated: Separate the dynamic page content of PageOrientedSpec to only the page that expects it
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 <Bj...@Kautler.net>
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'