Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Comment thread
kubaflo marked this conversation as resolved.

Assert.That(afterSwitchRect.X, Is.EqualTo(initialRect.X).Within(5));
Assert.That(afterSwitchRect.Width, Is.EqualTo(initialRect.Width).Within(5));
Expand Down
33 changes: 33 additions & 0 deletions src/TestUtils/src/UITest.Appium/HelperExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,39 @@ public static Rectangle GetRect(this IUIElement element)
})!;
}

/// <summary>
/// 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
/// <see cref="StaleElementReferenceException"/> from <see cref="GetRect(IUIElement)"/>. 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).
/// </summary>
/// <param name="app">Represents the main gateway to interact with an app.</param>
/// <param name="elementId">The id of the element to locate and measure.</param>
/// <param name="timeout">Optional timeout for each wait operation. Default is null, which uses the default timeout.</param>
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!;
}

/// <summary>
/// Determine if a form or form-like element (checkbox, select, etc...) is selected.
/// </summary>
Expand Down
Loading