diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs
index e2b9d4836436..d6b8ba4e9099 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs
@@ -20,12 +20,12 @@ public void SafeAreaShouldWorkOnAllShellTabs()
App.SetOrientationLandscape();
//Adding delay to allow for orientation change to complete
Thread.Sleep(2000);
- var initialRect = App.WaitForElement("EdgeLabel").GetRect();
+ var initialRect = App.WaitForElementAndGetRect("EdgeLabel");
App.TapTab("Second Tab");
App.WaitForElement("EdgeLabel");
App.TapTab("First Tab");
- var afterSwitchRect = App.WaitForElement("EdgeLabel").GetRect();
+ var afterSwitchRect = App.WaitForElementAndGetRect("EdgeLabel");
Assert.That(afterSwitchRect.X, Is.EqualTo(initialRect.X).Within(5));
Assert.That(afterSwitchRect.Width, Is.EqualTo(initialRect.Width).Within(5));
diff --git a/src/TestUtils/src/UITest.Appium/HelperExtensions.cs b/src/TestUtils/src/UITest.Appium/HelperExtensions.cs
index 9bd0aefa2bc6..1343d574af89 100644
--- a/src/TestUtils/src/UITest.Appium/HelperExtensions.cs
+++ b/src/TestUtils/src/UITest.Appium/HelperExtensions.cs
@@ -179,6 +179,39 @@ public static Rectangle GetRect(this IUIElement element)
})!;
}
+ ///
+ /// Waits for an element and reads its on-screen rectangle, re-querying and retrying if the
+ /// element reference becomes stale. A navigation or tab-switch animation can recycle the
+ /// underlying view between the element query and the geometry read, which surfaces as a
+ /// from . Re-finding
+ /// the element and reading again once it has settled keeps the geometry read deterministic
+ /// without changing what the caller asserts on. This mirrors the existing stale-element handling
+ /// used elsewhere in the framework (see AppiumMouseActions).
+ ///
+ /// Represents the main gateway to interact with an app.
+ /// The id of the element to locate and measure.
+ /// Optional timeout for each wait operation. Default is null, which uses the default timeout.
+ public static Rectangle WaitForElementAndGetRect(this IApp app, string elementId, TimeSpan? timeout = null)
+ {
+ StaleElementReferenceException? lastStale = null;
+
+ for (int attempt = 0; attempt < 3; attempt++)
+ {
+ try
+ {
+ return app.WaitForElement(elementId, timeout: timeout).GetRect();
+ }
+ catch (StaleElementReferenceException ex)
+ {
+ // The view was recycled between the query and the geometry read (typically
+ // mid-animation); re-find the element and read again now that it should have settled.
+ lastStale = ex;
+ }
+ }
+
+ throw lastStale!;
+ }
+
///
/// Determine if a form or form-like element (checkbox, select, etc...) is selected.
///