This is an automated email from the ASF dual-hosted git repository.
jdaugherty pushed a commit to branch 8.0.x
in repository https://gitbox.apache.org/repos/asf/grails-core.git
The following commit(s) were added to refs/heads/8.0.x by this push:
new 565f438322 address test flakiness
565f438322 is described below
commit 565f43832230b430af34873503049b606ab66a7d
Author: James Daugherty <[email protected]>
AuthorDate: Thu Jul 9 19:58:39 2026 -0400
address test flakiness
---
.../groovy/com/example/pages/LoginPage.groovy | 7 +--
.../groovy/com/example/pages/LogoutPage.groovy | 7 +--
.../groovy/com/example/pages/NavigationPage.groovy | 53 ++++++++++++++++++++++
3 files changed, 57 insertions(+), 10 deletions(-)
diff --git
a/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/LoginPage.groovy
b/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/LoginPage.groovy
index 94da225537..39c61e9eae 100644
---
a/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/LoginPage.groovy
+++
b/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/LoginPage.groovy
@@ -18,9 +18,7 @@
*/
package com.example.pages
-import geb.Page
-
-class LoginPage extends Page {
+class LoginPage extends NavigationPage {
static String pageTitle = 'Please sign in'
@@ -35,7 +33,6 @@ class LoginPage extends Page {
void login(String username = '[email protected]', String password =
'letmein') {
this.username = username
this.password = password
- loginButton.click()
- waitFor { title && title != pageTitle }
+ clickAndWaitForNavigation(loginButton)
}
}
diff --git
a/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/LogoutPage.groovy
b/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/LogoutPage.groovy
index dcaaae57cf..5bfdf4f56c 100644
---
a/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/LogoutPage.groovy
+++
b/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/LogoutPage.groovy
@@ -18,9 +18,7 @@
*/
package com.example.pages
-import geb.Page
-
-class LogoutPage extends Page {
+class LogoutPage extends NavigationPage {
static String pageTitle = 'Confirm Log Out?'
@@ -31,7 +29,6 @@ class LogoutPage extends Page {
}
void logout() {
- logoutButton.click()
- waitFor { title != pageTitle }
+ clickAndWaitForNavigation(logoutButton)
}
}
diff --git
a/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/NavigationPage.groovy
b/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/NavigationPage.groovy
new file mode 100644
index 0000000000..aac0f30556
--- /dev/null
+++
b/grails-test-examples/scaffolding/src/integrationTest/groovy/com/example/pages/NavigationPage.groovy
@@ -0,0 +1,53 @@
+/*
+ * 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
+ *
+ * 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 com.example.pages
+
+import org.openqa.selenium.StaleElementReferenceException
+import org.openqa.selenium.WebElement
+
+import geb.Page
+import geb.navigator.Navigator
+
+abstract class NavigationPage extends Page {
+
+ /**
+ * Clicks a button that triggers navigation and waits for the new document
to
+ * replace the current one. Required when the destination can share the
current
+ * page's at-check (e.g. a failed login re-rendering the sign-in page),
where a
+ * title-based wait would otherwise pass against the outgoing document.
+ */
+ protected void clickAndWaitForNavigation(Navigator button) {
+ WebElement oldElement = button.firstElement()
+ button.click()
+ waitForStale(oldElement)
+ waitFor { title }
+ }
+
+ private void waitForStale(WebElement oldElement) {
+ waitFor {
+ try {
+ oldElement.enabled
+ false
+ }
+ catch (StaleElementReferenceException ignored) {
+ true
+ }
+ }
+ }
+}