Skip to content

[ci-fix] De-flake SafeAreaShouldWorkOnAllShellTabs (StaleElementReferenceException on tab switch) - #36429

Merged
kubaflo merged 1 commit into
inflight/currentfrom
ci-fix/issue-36259-attempt-1-fb45f4747ef0b315
Jul 21, 2026
Merged

[ci-fix] De-flake SafeAreaShouldWorkOnAllShellTabs (StaleElementReferenceException on tab switch)#36429
kubaflo merged 1 commit into
inflight/currentfrom
ci-fix/issue-36259-attempt-1-fb45f4747ef0b315

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Summary

De-flakes the Android UI test SafeAreaShouldWorkOnAllShellTabs (Issue33034), which intermittently fails with a StaleElementReferenceException thrown from IUIElement.GetRect().

Target branch: main
Refs: #36259
Attempt: 1/5
Flake class: test-quality (genuine test defect) → de-flake

Reproduction evidence

Pipeline maui-pr-uitests (def 313), branch main. The signature is intermittent across the most recent completed builds — the hallmark of a real flake, not a fixed issue:

Build Leg outcome Signature
1484478 failed on first attempt, passed on retry StaleElementReferenceException at get_Rect
1486368 failed on first attempt, passed on retry present
3 newest (incl. latest 1495318) passed absent

Failed-then-passed-on-retry and present-in-some-but-not-all recent builds → genuinely flaky. Issue33034.cs was last modified well before the failures began, so the recent greens are luck, not a landed fix.

Root cause

App.TapTab("First Tab");                                          // starts tab-switch animation
var afterSwitchRect = App.WaitForElement("EdgeLabel").GetRect();  // find succeeds, then get_Rect races the animation

WaitForElement returns as soon as EdgeLabel exists, but the tab-switch animation recycles the underlying view between the query and the getRect round-trip, invalidating the element reference → StaleElementReferenceException on get_Rect(). This is a pre-assertion crash, not an assertion failure.

Fix

Add a stale-resilient WaitForElementAndGetRect helper to HelperExtensions that re-finds the element and retries GetRect() when the reference goes stale, then use it at the two post-UI-change rect reads in the test.

  • Condition-based, not a fixed wait — it retries on the actual stale condition (re-querying a fresh element each attempt via WaitForElement), with no new Thread.Sleep/Task.Delay.
  • Mirrors existing framework behaviorAppiumMouseActions.ProcessException already re-finds stale elements ("Appium elements will sometimes become stale ... we retrieve it here").
  • Assertions untouched — the .Within(5) tolerance checks are unchanged; nothing is weakened, muted, or skipped.

Not muting

No [ActiveIssue], [SkipOnPlatform], [Retry]/[Repeat], category exclusion, csproj incompatibility, weakened assertion, or timeout bump. The test still exercises and asserts the same SafeArea behavior on every tab; it is simply made robust against a known Appium view-recycling artifact during navigation animations.

Validation

⚠️ This is an on-device Android UI test that cannot be executed in the fixer's sandbox, so the change is not runner-validated (help-style). It is a targeted, type-checked synchronization change following an established framework pattern; CI on this PR should confirm the leg is green.

Generated by CI Failure Fixer (main) · 919.8 AIC · ⌖ 46 AIC · ⊞ 24.2K ·

…enceException)

The Android UI test SafeAreaShouldWorkOnAllShellTabs intermittently fails with a
StaleElementReferenceException thrown from IUIElement.GetRect(). After App.TapTab
switches tabs, the tab-switch animation recycles the EdgeLabel view between the
WaitForElement query and the geometry read, invalidating the element reference.

Add a stale-resilient WaitForElementAndGetRect helper that re-finds the element and
retries GetRect() when the reference goes stale (mirroring the existing stale-element
handling in AppiumMouseActions), and use it at the two post-navigation rect reads in
the test. This makes the geometry read deterministic without weakening the assertions,
which are left untouched.

Refs: #36259

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expert Review — 1 findings

See inline comments for details.

@MauiBot MauiBot added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Jul 7, 2026
MauiBot

This comment was marked as outdated.

@PureWeen

PureWeen commented Jul 8, 2026

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 3 pipeline(s).

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

🎯 Target test validated green on head 74801915d4e0a7ced970b9eb8b95784263f3d5be (maui-pr-uitests buildId 1499884).

SafeAreaShouldWorkOnAllShellTabs passed on the Android API 30 legs (Controls (API 30) SafeAreaEdges,Shadow, both the CoreClr and default variants) with zero StaleElementReferenceException — the exact signature from #36259 no longer reproduces.

The remaining red legs are unrelated flakes — this fix is implicated in none of them:

  • maui-pr (buildId 1499883): AOTTemplateTest.PublishNativeAOTRootAllMauiAssemblies failed with "Unable to create template maui" — a NativeAOT template / workload-provisioning failure. maui-pr does not run Appium UI tests, so it cannot exercise this change.
  • maui-pr-uitests Android API 30 CollectionView / CarouselView / RadioButton / SearchBar legs (buildId 1499884): mass failures from an emulator/ADB provisioning problem ("Failed to push ADB keys after multiple attempts"). The CollectionView failure log has 0 references to this fix's WaitForElementAndGetRect, Issue33034, or SafeArea — every failing test is an unrelated EmptyView case.
  • WinUI CollectionView: a separate, pre-existing flake.

The change is purely additive — it adds a new WaitForElementAndGetRect extension method (which re-queries and retries the geometry read on StaleElementReferenceException) and calls it only inside SafeAreaShouldWorkOnAllShellTabs. No existing shared helper was modified, so it cannot affect any other leg.

Transitioning this PR from draft → ready for review (attempt 1/10). A maintainer still reviews and merges; the unrelated red legs can be re-run with /azp run if a clean board is desired.

Generated by CI Failure Fixer (main) · 313.7 AIC · ⌖ 31.5 AIC · ⊞ 43.9K ·

@github-actions
github-actions Bot marked this pull request as ready for review July 8, 2026 21:28
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Target test SafeAreaShouldWorkOnAllShellTabs validated green on head 7480191 (maui-pr-uitests buildId 1499884, Android API 30 SafeAreaEdges,Shadow legs, zero StaleElementReferenceException). Remaining red legs are unrelated infra flakes: NativeAOT template provisioning on maui-pr, and Android ADB/emulator provisioning on unrelated CollectionView/CarouselView/RadioButton/SearchBar legs. The fix is purely additive (new WaitForElementAndGetRect helper called only by this test), so it cannot affect other legs.

Generated by CI Failure Fixer (main) · 313.7 AIC · ⌖ 31.5 AIC · ⊞ 43.9K

PureWeen pushed a commit that referenced this pull request Jul 8, 2026
…obust)

The Step 3.6 preconditions stop with "already-ready" for any non-draft PR
BEFORE reaching the T3 mark-ready path, so the p/0 label-reconcile added in the
prior commit could never fire for a PR that was already flipped to ready. Move
the reconcile into the already-ready precondition itself: an already-ready
[ci-fix] PR (correct title + agentic-workflows label) that is missing p/0 now
gets it added there. This makes every already-marked-ready loop PR self-heal to
carry p/0, and makes the label path testable on PRs that are already ready
(e.g. #36429). T3's idempotency is simplified to defer label reconciliation to
that precondition. Mirrored to both twins; locks recompiled (0/0, body_hash only).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@kubaflo

kubaflo commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🔍 AI-generated review (multi-model: Opus 4.8 · GPT-5.5 · Gemini 3.1 Pro), on behalf of @kubaflo.

Code LGTM — but CI needs a maintainer flake-confirmation before merge

Code (safe): the HelperExtensions.cs change is purely additive — a new WaitForElementAndGetRect(app, elementId, timeout) that re-finds the element and retries (≤3×) when GetRect() throws StaleElementReferenceException mid-animation, then rethrows the last stale if it never settles. It modifies no existing method and mirrors the framework's existing stale-element handling (AppiumMouseActions), so it cannot affect any other test. The Issue33034.cs edit is the sole consumer. Clean, well-documented fix for the flaky SafeAreaShouldWorkOnAllShellTabs geometry read.

CI (needs confirmation): the run shows 19 red maui-pr-uitests legs spanning unrelated buckets (CollectionView, RadioButton, Shell, Entry, Layout, Navigation, ScrollView, WebView…) across macOS/Android/WinUI. That breadth is consistent with base-branch UI-test flakiness rather than this additive change — but before merge a maintainer should confirm the de-flaked test's own leg is green on this head and that the 19 reds are the usual unrelated flakes. Not approving over that many unexplained red UI legs; the code itself is LGTM.

(Bot-authored [ci-fix] PR — posting a comment rather than a formal review.)

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jul 10, 2026
@MauiBot MauiBot added s/agent-gate-failed AI could not verify tests catch the bug s/agent-fix-win AI found a better alternative fix than the PR and removed s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates labels Jul 10, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Review Summary

@github-actions[bot] — new AI review results are available based on this last commit: 7480191. To request a fresh review after new comments or commits, comment /review rerun.

Gate Failed Confidence Low Platform Android


🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix

Gate: Test Verification (Failure-Only Mode)

Result: ❌ FAILED

This is a test-only change (no fix files detected in the diff), so the gate only verifies that the new/changed tests fail against the merge base — proving they reproduce the bug they target.

Platform: ANDROID
Merge base: 0395a53b

Test Type Outcome
Issue33034 UITest PASS ❌ (should fail)

📱 UI Tests — SafeAreaEdges

Detected UI test categories: SafeAreaEdges

⚠️ Deep UI tests — 1 category (61 tests) could not run: OneTimeSetUp/fixture setup failure on the platform-pool agent — infrastructure, not a PR test failure (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
SafeAreaEdges 0/61 (setup failed; 61 marked failed)
⚠️ SafeAreaEdges — fixture setup failed for 61 tests

NUnit reported a OneTimeSetUp/fixture setup failure before test bodies ran; the TRX marked each affected test failed.

Multiple setup failure signatures were present; showing the first one. See the TRX artifact for all details.

OneTimeSetUp: System.TimeoutException : Verify AdjustPan mode does not apply keyboard insets (the app did not recover after crash-recovery attempts)
at Microsoft.Maui.TestCases.Tests.UtilExtensions.WaitForGoToTestButtonWithRecovery(IApp app, String timeoutMessage) in /_/src/Controls/tests/TestCases.Shared.Tests/UtilExtensions.cs:line 91
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
   at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
   at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 221
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)


📋 Pre-Flight — Context & Validation

Issue: #36259 - [ci-scan] Recurring: SafeAreaShouldWorkOnAllShellTabs fails with StaleElementReferenceException on Android API 30 in maui-pr-uitests
PR: #36429 - [ci-fix] De-flake SafeAreaShouldWorkOnAllShellTabs (StaleElementReferenceException on tab switch)
Platforms Affected: Android (test is compiled for Android and iOS; requested test platform: android)
Files Changed: 1 implementation/test-infrastructure, 1 test

Key Findings

  • PR #36429 changes Issue33034.SafeAreaShouldWorkOnAllShellTabs to use a new WaitForElementAndGetRect helper for the initial and post-tab-switch geometry reads.
  • The linked issue reports intermittent Android API 30 StaleElementReferenceException from GetRect() after Shell tab switching; the PR's current fix treats this as an Appium stale-element race.
  • A prior MauiBot inline review raised a critical regression-prevention concern: the test waits for the second tab, but measures only the first tab before and after navigation.
  • gh is unauthenticated in this environment, so pre-flight used local pr-review-36429 checkout plus public GitHub API/curl; required-check status could not be collected via gh pr checks --required.

Code Review Summary

Verdict: NEEDS_CHANGES
Confidence: low
Errors: 1 | Warnings: 1 | Suggestions: 1

Key code review findings:

  • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs:28 — test still does not validate the second tab's safe-area geometry; it compares first-tab geometry before/after navigation.
  • src/TestUtils/src/UITest.Appium/HelperExtensions.cs:198 — stale-element retries happen back-to-back, so the helper can repeatedly race the same transition window.
  • src/TestUtils/src/UITest.Appium/HelperExtensions.cs:189 — the AppiumMouseActions citation is imprecise for this exact stale-element behavior.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #36429 Add WaitForElementAndGetRect helper that re-finds EdgeLabel and retries GetRect() on StaleElementReferenceException; use it for both rect reads in Issue33034. ❌ Gate failed (prior step: tests did not behave as expected) src/TestUtils/src/UITest.Appium/HelperExtensions.cs, src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs Improves stale read handling but does not address second-tab coverage concern.

🔬 Code Review — Deep Analysis

Code Review — PR #36429

Independent Assessment

What this changes: Adds WaitForElementAndGetRect() to retry GetRect() when Appium reports a stale element, and uses it in Issue33034.
Inferred motivation: De-flake a SafeAreaEdges UI test where tab switching recycles EdgeLabel between element lookup and geometry read.

Reconciliation with PR Narrative

Author claims: The PR fixes intermittent StaleElementReferenceException without weakening assertions or adding sleeps.
Agreement/disagreement: The stale retry direction is reasonable, but the test still does not validate the second tab’s geometry, and the retry loop may re-hit the same animation race because retries are immediate.

Prior Review Reconciliation

Prior ❌ Error Finding Source Status Evidence
Test compares first-tab geometry before/after navigation and never asserts second-tab safe-area geometry MauiBot inline review, Issue33034.cs:28, [critical] Regression Prevention ❌ Unresolved Current code still captures initialRect on first tab, taps second tab only to wait, then taps first tab and measures afterSwitchRect at Issue33034.cs:23-28.

Blast Radius Assessment

  • Runs for all instances: No — only this UI test currently calls the helper.
  • Startup impact: No.
  • Static/shared state: No.
  • Shared helper impact: Yes — helper is added to common Appium test infrastructure and may be reused by future tests.

CI Status

  • Required-check result: gh pr checks --required unavailable; gh is unauthenticated (gh auth login required).
  • Public check-run fallback: PR head has failing/pending checks, including maui-pr, Build Analysis, several maui-pr-uitests failures/cancellations, and queued maui-pr-uitests.
  • Classification: Undetermined from available public data; not safe to treat as green.
  • Action taken: Invoked azdo-build-investigator skill per workflow; confidence capped low.

Findings

❌ Error — Test still does not validate the second tab

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs:28

The test waits for EdgeLabel on the second tab, but never records or asserts that tab’s rectangle. It immediately taps back to the first tab and compares first-tab geometry before/after navigation. A regression where only the second tab collides with the cutout can still pass.

⚠️ Warning — Stale-element retries happen back-to-back

src/TestUtils/src/UITest.Appium/HelperExtensions.cs:198

WaitForElement() performs its first query immediately, and if the element is present, the loop can retry all three GetRect() calls without any pause. For an animation/view-recycle race, this may repeatedly hit the same stale window rather than waiting for the view to settle.

💡 Suggestion — Inaccurate AppiumMouseActions citation

src/TestUtils/src/UITest.Appium/HelperExtensions.cs:189

The doc says this mirrors stale-element handling in AppiumMouseActions, but that code catches broader click failures and does not handle StaleElementReferenceException specifically. Consider removing or correcting the reference.

Failure-Mode Probing

  • What if only the second tab has bad safe-area padding? The current test can still pass because it never compares the second tab’s rect.
  • What if the tab-switch animation is still recycling views? Immediate retries may keep racing the same transition.
  • What if WaitForElement() times out or GetRect() fails with a non-stale error? Those exceptions still propagate, which is appropriate.

Verdict: NEEDS_CHANGES

Confidence: low
Summary: The PR improves one stale-element symptom, but an unresolved prior critical finding remains: the test still does not assert the tab it claims to protect. CI is also not verifiably green from this environment.


🛠️ Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 maui-expert-reviewer + try-fix Use unique tab-specific EdgeLabel automation ids and a test-local stable-geometry polling helper; assert the second tab directly before returning to the first tab. ✅ PASS 3 files Demonstrably better than PR fix: resolves prior critical coverage finding and avoids shared immediate stale-retry helper.
PR PR #36429 Add shared WaitForElementAndGetRect helper with three immediate retries on StaleElementReferenceException; use it for both existing first-tab rect reads. ❌ Gate failed (prior step) 2 files Does not validate second-tab geometry; retry loop can hit same animation window.

Cross-Pollination

Model Round New Ideas? Details
gpt-5.5 / maui-expert-reviewer 1 Yes Stable active-tab geometry with distinct automation ids and direct second-tab assertion.

Exhausted: No — stopped because candidate #1 passed the Android target test and is demonstrably better than the PR fix.
Selected Fix: Candidate #1 — It validates the actual active second tab and passed SafeAreaShouldWorkOnAllShellTabs on Android while keeping assertions strict.


📝 Recommended PR Title & Description

Assessment: ✏️ Recommend updating — the current metadata accurately describes the raw PR helper, but the winning fix changes the test fixture/assertion strategy instead.

Recommended title

[Android] SafeArea: De-flake Shell tab safe-area UI test

Recommended description

## Summary

De-flakes the Android UI test `SafeAreaShouldWorkOnAllShellTabs` (`Issue33034`), which intermittently fails with a `StaleElementReferenceException` from `IUIElement.GetRect()` during Shell tab switching.

Target branch: main
Refs: dotnet/maui#36259
Flake class: test-quality (genuine test defect) -> de-flake

## Reproduction evidence

Pipeline `maui-pr-uitests` (def 313), branch `main`. The signature is intermittent across recent completed builds, which indicates a real flake rather than a permanently fixed issue:

| Build | Leg outcome | Signature |
|---|---|---|
| 1484478 | failed on first attempt, passed on retry | `StaleElementReferenceException` at `get_Rect` |
| 1486368 | failed on first attempt, passed on retry | present |
| 3 newest (incl. latest 1495318) | passed | absent |

Failed-then-passed-on-retry and present-in-some-but-not-all recent builds -> genuinely flaky. `Issue33034.cs` was last modified well before the failures began, so the recent greens are luck, not a landed fix.

## Root cause

The test reads Appium geometry while Shell tab switching can still be recycling native views:

```csharp
App.TapTab("Second Tab");
App.WaitForElement("EdgeLabel");
App.TapTab("First Tab");
var afterSwitchRect = App.WaitForElement("EdgeLabel").GetRect();

WaitForElement returns as soon as the label exists, but the element reference can become stale before the getRect round-trip completes. The original test also used the same EdgeLabel automation id on both tabs and only compared first-tab geometry before/after navigation, so it did not directly prove that the second tab's safe-area layout was correct.

Fix

Update Issue33034 so each Shell tab has a unique label automation id (FirstTabEdgeLabel, SecondTabEdgeLabel), then assert the second tab's geometry while the second tab is active before returning to the first tab.

The test now uses a test-local WaitForStableRect helper that:

  • re-queries the active tab's label before each rect read;
  • catches StaleElementReferenceException caused by tab-switch view recycling;
  • waits briefly between attempts instead of retrying back-to-back in the same animation window;
  • requires two consecutive stable bounds before returning.

The existing .Within(5) X/Width assertions remain strict. No [ActiveIssue], [SkipOnPlatform], category exclusion, timeout-only workaround, muted assertion, or weakened tolerance is added.

Key files

  • src/Controls/tests/TestCases.HostApp/Issues/Issue33034.cs
  • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs

Validation

Android HostApp UI test run:

pwsh -NoProfile -File .github/scripts/BuildAndRunHostApp.ps1 -Platform android -TestFilter 'FullyQualifiedName~Issue33034'

Result: SafeAreaShouldWorkOnAllShellTabs passed on Android.



</details>

---

<details>
<summary><strong>🏁 Report — Final Recommendation</strong></summary>
<br/>

## Comparative Report — PR #36429

### Candidates

| Rank | Candidate | Regression result | Assessment |
|---:|---|---|---|
| 1 | `try-fix-1` | ✅ PASS | Best candidate. It uses unique tab-specific automation ids, directly asserts the second tab's safe-area geometry, waits for stable rects across navigation animation/recycle windows, and passed `SafeAreaShouldWorkOnAllShellTabs` on Android. |
| 2 | `pr-plus-reviewer` | Not re-run | Strong code candidate and functionally equivalent to `try-fix-1` after applying expert feedback in a sandbox. Ranked below `try-fix-1` only because the equivalent try-fix candidate has the recorded Android pass. |
| 3 | `pr` | ❌ Gate failed | Improves the stale `GetRect()` symptom, but still compares only first-tab geometry and uses a shared immediate retry helper that can race the same transition window. Failed candidates must rank below passing candidates. |

### Why `try-fix-1` wins

`try-fix-1` is the only candidate with both the corrected assertion model and a recorded passing Android regression run. It fixes the core coverage defect by measuring `SecondTabEdgeLabel` while the second tab is active, then confirms the first tab remains stable after returning. Its test-local stable-geometry polling also addresses the Appium stale-element race without adding a shared helper with broad future blast radius.

### Candidate details

#### `pr`

The raw PR adds `WaitForElementAndGetRect()` and uses it for two first-tab rect reads. This is not sufficient because a regression limited to the second tab can still pass: the test taps the second tab only long enough to wait for an `EdgeLabel`, then returns to the first tab before taking the second measured rectangle. The expert reviewer also found that the helper retries immediately after stale exceptions, which may not allow the tab-switch animation/recycle window to settle.

#### `pr-plus-reviewer`

The sandboxed reviewer-improved PR applies the expert feedback by adopting the same approach as `try-fix-1`: unique first/second tab automation ids, direct second-tab assertion, and stable rect polling. This is a good implementation direction, but it does not have a separate recorded regression-test result in this phase.

#### `try-fix-1`

`try-fix-1` changes the HostApp test fixture so each tab has a distinct label id, then updates the test to assert first-tab, second-tab, and return-to-first-tab geometry with strict existing `.Within(5)` tolerances. Its `WaitForStableRect()` loop re-queries the active element, catches stale references, waits 250 ms between attempts, and requires consecutive stable bounds before returning. The recorded Android run selected `Issue33034` and passed.

### Winner

**Winner:** `try-fix-1`

**Rationale:** It is the only candidate that both passed the Android regression run and fully addresses the expert review's coverage/flakiness findings.


</details>

</details>
<!-- SESSION:7480191 END -->

---

<details>
<summary><strong>🧭 Next Steps</strong> — alternative fix proposed (<code>try-fix-1</code>)</summary>
<br/>

**Automated review — alternative fix proposed**

The expert-reviewer evaluation compared the PR fix against automatically generated candidates and selected <code>try-fix-1</code> as the strongest fix.

**Why:** try-fix-1 wins because it directly validates the active second tab, handles stale geometry reads with stable polling, and is the only candidate with a recorded passing Android regression run. The raw PR failed the gate and leaves the second-tab coverage gap unresolved.

Please consider applying the candidate diff below (or use it as guidance). Once you push an update, this workflow will re-trigger and re-evaluate.

<details><summary>Candidate diff (<code>try-fix-1</code>)</summary>

````diff
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue33034.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue33034.cs
index 509e349f82..de10b1614e 100644
--- a/src/Controls/tests/TestCases.HostApp/Issues/Issue33034.cs
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue33034.cs
@@ -12,7 +12,7 @@ public class Issue33034 : TestShell
 		{
 			Title = "First Tab",
 			AutomationId = "FirstTab",
-			ContentTemplate = new DataTemplate(typeof(Issue33034TabContent)),
+			ContentTemplate = new DataTemplate(() => new Issue33034TabContent("FirstTabEdgeLabel")),
 			Route = "tab1"
 		});
 
@@ -20,7 +20,7 @@ public class Issue33034 : TestShell
 		{
 			Title = "Second Tab",
 			AutomationId = "SecondTab",
-			ContentTemplate = new DataTemplate(typeof(Issue33034TabContent)),
+			ContentTemplate = new DataTemplate(() => new Issue33034TabContent("SecondTabEdgeLabel")),
 			Route = "tab2"
 		});
 
@@ -31,13 +31,13 @@ public class Issue33034 : TestShell
 
 public class Issue33034TabContent : ContentPage
 {
-	public Issue33034TabContent()
+	public Issue33034TabContent(string edgeLabelAutomationId)
 	{
 		// Full-width label to detect safe area padding on either side
 		var edgeLabel = new Label
 		{
 			Text = "EDGE LABEL",
-			AutomationId = "EdgeLabel",
+			AutomationId = edgeLabelAutomationId,
 			FontSize = 18,
 			FontAttributes = FontAttributes.Bold,
 			BackgroundColor = Colors.Red,
@@ -52,4 +52,3 @@ public class Issue33034TabContent : ContentPage
 		};
 	}
 }
-
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 d6b8ba4e90..23eb1aa815 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33034.cs
@@ -1,5 +1,7 @@
 #if ANDROID || IOS  // SafeAreaEdges not supported on Catalyst and Windows
 
+using System.Drawing;
+using OpenQA.Selenium;
 using NUnit.Framework;
 using UITest.Appium;
 using UITest.Core;
@@ -16,19 +18,56 @@ public class Issue33034 : _IssuesUITest
 	[Category(UITestCategories.SafeAreaEdges)]
 	public void SafeAreaShouldWorkOnAllShellTabs()
 	{
-		App.WaitForElement("EdgeLabel");
+		App.WaitForElement("FirstTabEdgeLabel");
 		App.SetOrientationLandscape();
 		//Adding delay to allow for orientation change to complete
 		Thread.Sleep(2000);
-		var initialRect = App.WaitForElementAndGetRect("EdgeLabel");
+		var initialRect = WaitForStableRect("FirstTabEdgeLabel");
 
 		App.TapTab("Second Tab");
-		App.WaitForElement("EdgeLabel");
+		var secondTabRect = WaitForStableRect("SecondTabEdgeLabel");
+
+		Assert.That(secondTabRect.X, Is.EqualTo(initialRect.X).Within(5));
+		Assert.That(secondTabRect.Width, Is.EqualTo(initialRect.Width).Within(5));
+
 		App.TapTab("First Tab");
-		var afterSwitchRect = App.WaitForElementAndGetRect("EdgeLabel");
+		var afterSwitchRect = WaitForStableRect("FirstTabEdgeLabel");
 
 		Assert.That(afterSwitchRect.X, Is.EqualTo(initialRect.X).Within(5));
 		Assert.That(afterSwitchRect.Width, Is.EqualTo(initialRect.Width).Within(5));
 	}
+
+	Rectangle WaitForStableRect(string elementId)
+	{
+		Rectangle? previous = null;
+		var started = DateTime.UtcNow;
+
+		while (DateTime.UtcNow - started < TimeSpan.FromSeconds(15))
+		{
+			try
+			{
+				var rect = App.WaitForElement(elementId).GetRect();
+
+				if (previous is Rectangle last &&
+					Math.Abs(last.X - rect.X) <= 1 &&
+					Math.Abs(last.Y - rect.Y) <= 1 &&
+					Math.Abs(last.Width - rect.Width) <= 1 &&
+					Math.Abs(last.Height - rect.Height) <= 1)
+				{
+					return rect;
+				}
+
+				previous = rect;
+			}
+			catch (StaleElementReferenceException)
+			{
+				previous = null;
+			}
+
+			Thread.Sleep(250);
+		}
+
+		throw new TimeoutException($"Timed out waiting for '{elementId}' to report stable bounds.");
+	}
 }
 #endif
diff --git a/src/TestUtils/src/UITest.Appium/HelperExtensions.cs b/src/TestUtils/src/UITest.Appium/HelperExtensions.cs
index 1343d574af..9bd0aefa2b 100644
--- a/src/TestUtils/src/UITest.Appium/HelperExtensions.cs
+++ b/src/TestUtils/src/UITest.Appium/HelperExtensions.cs
@@ -179,39 +179,6 @@ namespace UITest.Appium
 			})!;
 		}
 
-		/// <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>

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 11, 2026
@kubaflo

kubaflo commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 3 pipeline(s).

@kubaflo

This comment has been minimized.

@github-actions

This comment has been minimized.

@kubaflo

kubaflo commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Tests Failure Analysis

🔍 AI-generated preview — improved Tests Failure Analysis based on commit 7480191.
Manual preview of the multi-build base-branch regression diff (#36533) — not an automated workflow run.

Overall Not ready Failures 23 Regressed vs base 2 Baseline 2 on base

Test Failure Review: Not ready - click to expand

Overall verdict: Not ready: against several recent main base builds, only 2 of 23 distinct failures are flagged as regressions — and both are build/publish-infrastructure legs, not test failures, so for a single-test de-flake PR they're most likely transient CI infra. The other 11 failures are dismissed as pre-existing flakiness, so nothing here points at your change.

  • ✗ PR-related — build/publish infra legs (2 legs): Controls (API 30) …InputTransparent… - build error and publish artifacts - build error were green on the sampled base builds and red here; both are build/upload steps unrelated to this PR's single UI-test retry change, so almost certainly transient — re-run to confirm.
  • ● Unrelated — CollectionView footer + misc UI tests (~11 tests): ValidateDynamicFooter*, CollectionViewInfiniteScroll, Issue17400Test already flip green/red on main, so not this PR.
  • ℹ Uncertain — unexplained legs + 1 aborted check (~16 legs): failed legs with no extractable test name — can't be attributed either way.

Coverage: 160 checks · 149 passing · 10 failing · 1 pending · 1 unmapped · 16 unexplained build legs · 1 aborted · 0 device-test unverified · 21 unattributed · 2 regressed-vs-base. Deterministic ceiling: Not ready — 2 legs regressed vs base.

Builds (this PR): maui-pr 1504721 · maui-pr-uitests 1504722 · maui-pr-devicetests 1504723 (succeeded). Base sampling (main, ~5 recent builds per definition): maui-pr 1503430 · maui-pr-uitests 1503618 · maui-pr-devicetests 1503431.

Scope: ci-fix / UI-test retry. Base branch: main.

Recommended action

Confirm the 2 regressed-vs-base failure(s) flagged above are resolved before merging; the remaining failures reproduce on the base branch and are not caused by this PR.

@kubaflo

This comment has been minimized.

@github-actions

This comment has been minimized.

PureWeen added a commit that referenced this pull request Jul 15, 2026
…#36461)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## What this changes

Follow-up to #36317 (the self-watching `ci-status-fix` loop). Today,
when a `[ci-fix]` draft PR's CI comes back green — or red only on
**unrelated** flakes — the loop posts a comment but **leaves the PR as a
draft forever**. A maintainer has to notice it, confirm the specific
fixed test actually passed, and flip it to ready. In practice these
validated-green draft PRs sit unreviewed for weeks.

This PR adds a **target-test verification + mark-ready gate (Step 3.6)**
to both twins (`main` + `net11.0`). When a draft `[ci-fix]` /
`[ci-fix-net11]` PR reaches the green-surface or unrelated-flake branch,
the loop now drills into the PR's **own** AzDO test-results for the
**specific test(s)** the fix targeted. If every target test is `Passed`
on ≥1 leg and `Failed` on none (VALIDATED-GREEN), it:

- posts a `🎯 Target test validated green on <headSha>` comment (naming
the test + legs + buildId), and
- transitions the draft PR to **ready for review**.

This is a **state transition only** — it never approves and never
merges; a human still reviews and merges. Overall red on **unrelated**
legs no longer keeps a validated fix parked as a draft.

## How it works

- **Preconditions** (all required): PR `isDraft == true`; it is
unmistakably this workflow's own PR (`[ci-fix]`/`[ci-fix-net11]` title
prefix **and** `agentic-workflows` label); and it was reached from the
green or **unrelated-flake** path (never from caused-by-fix — that path
advances an attempt instead).
- **T1 — identify target test(s)** from the `[ci-scan]` issue signature
+ the PR diff. If no specific test can be identified (e.g. a product
build-break), it records a skip — build-only fixes are validated by
overall-green, which the existing green branch already handles.
- **T2 — drill AzDO test-results** for the build(s) on the PR's current
head SHA, filtered to the target test's `testCaseTitle`. A test that
never ran (e.g. an `/azp`-gated `maui-pr-uitests`/`maui-pr-devicetests`
leg that wasn't kicked) is **not** validated — the loop records an
honest "not yet executed" skip and does **not** mark ready. No
overclaiming: a green *sibling* leg is not the target test.
- **T3 — mark ready + report**, guarded by a per-head-SHA idempotency
marker and the existing `dry_run` gate (dry-run emits nothing and
tallies `would-mark-ready`).

## Safe-output

Adds the `mark-pull-request-as-ready-for-review` safe-output to both
twins (`max: 3`, `target: "*"`, `required-title-prefix` +
`required-labels`). Unlike `update-pull-request`, this output's
`required-*` guards **do** survive the gh-aw v0.80.9 compile (verified
against the generated locks), so which-PR scoping is enforced at the
handler level in addition to the Step 3.6 preconditions and
`min-integrity: approved`. No gh-aw version bump is required — the
capability already exists at our pinned v0.80.9.

## Enabling fix — the loop's own create-PR commit no longer counts as
"human engaged"

While validating this feature against #36429 I found the mark-ready path
was **unreachable for every loop-owned draft PR**, and traced it to a
regression from #36317's own review-hardening.

gh-aw's `create_pull_request` builds a PR's initial commit through the
GitHub API, which stamps `author=github-actions[bot]` but
**`committer=web-flow`**. Commit `2f6b77b330` (in #36317) removed
`web-flow` from the prefetch's bot-login denylist so a maintainer
"Update branch" would correctly hand the PR off — but that also made
`Test-AnyHumanCommitActor`'s committer check read the loop's **own**
first commit as human engagement. Result: every freshly opened
`[ci-fix]` draft PR computed `humanEngaged=true` from commit #1, so the
watch loop skipped it forever — never surfacing green, never marking
ready. This regression is live on `main` today (all four open loop-owned
draft PRs have `committer=web-flow`).

Fix (`Query-CiFixPRs.ps1`): a human **committer** only trips the
hand-off when the commit **author** is not one of this workflow's own
bot identities (`$LoopBotCommitAuthors`). A human **author** still
counts unconditionally, so maintainer direct commits and
web-flow-authored "Update branch" merges continue to hand off correctly.
Unit-tested across all six author/committer shapes.

## Validation

- Both twins recompiled with `gh aw compile` (0 errors / 0 warnings);
locks show no action-SHA or `compiler_version` drift (only
frontmatter/body hash + the new handler config).
- `mark_pull_request_as_ready_for_review` config confirmed present in
**both** locks with the correct `[ci-fix] ` / `[ci-fix-net11] ` prefixes
and `agentic-workflows` label; the `safe_outputs` job carries
`pull-requests: write`.
- Twin symmetry preserved (only `[ci-fix]` ↔ `[ci-fix-net11]` /
`ci-scan` ↔ `ci-scan-net11` token differences).
- **Live dry-run against #36429** (scoped `workflow_dispatch`,
`dry_run=true`, this branch): the workflow prefetch now computes
`humanEngaged=false` for #36429 (was `true` pre-fix), and the agent's
gate walk correctly advances **past** the human-engaged gate to the
CI-pending WAIT gate — `checksSettled=false` because #36429's macOS
`SafeAreaEdges` leg is still queued. Once that leg settles green, the
same run path reaches Step 3.6 and marks the PR ready. Emitted zero
writes (dry-run).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: PureWeen <223556219+Copilot@users.noreply.github.com>

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 AI-generated review (multi-model pipeline: Opus 4.8 · GPT-5.5 · Gemini 3.1 Pro), on behalf of @kubaflo.

✅ LGTM — 3-model consensus (unanimous, high confidence) at 74801915

Three independent reviews (Opus 4.8 · GPT-5.5 · Gemini 3.1 Pro) all returned LGTM / high, with zero blocking findings. The de-flake is correct, targeted, and strictly non-regressive.

What it does: wraps the flaky WaitForElement("EdgeLabel").GetRect() (which races a tab-switch animation recycling the native view between the element query and the geometry read) in a new additive helper WaitForElementAndGetRect that re-queries the element fresh and retries up to 3× on StaleElementReferenceException.

Verified across all three models:

  • Fresh reference on retryWaitForElement → FindElement → Driver.FindElements → new AppiumDriverElement re-queries on every iteration, so each attempt discards the stale handle. The retry does exactly what's intended.
  • The stale exception actually surfaces as the caught typeGetRect runs inside RunWithTimeout/Task.Run; a faulted task's AggregateException is unwrapped and rethrown via ExceptionDispatchInfo as the exact StaleElementReferenceException, so the new catch genuinely intercepts it (not masked as a timeout).
  • Failure semantics preserved — only StaleElementReferenceException is caught; TimeoutException (element never found) and GetRect's InvalidOperationException still propagate unchanged. Happy path is byte-for-byte equivalent to the original. throw lastStale! is provably null-safe (only reachable after 3 caught staleness). Worst case is bounded (3 finds + 3 timeout-protected reads) — no hot loop.
  • Zero blast radius — purely additive to the shared HelperExtensions.cs; no existing member modified, no overload collision. StaleElementReferenceException resolves via using OpenQA.Selenium; (line 6).

Non-blocking 💡 (2/3 model agreement, optional): throw lastStale! overwrites the exception's original stack trace with the helper location. Since RunWithTimeout in this same file already uses ExceptionDispatchInfo.Capture(x).Throw() to preserve stacks, matching that here (ExceptionDispatchInfo.Capture(lastStale!).Throw()) would keep triage stacks intact. Also optional: a small Thread.Sleep in the catch if the flake ever recurs under a long recycle window. Neither is required to merge.

CI note: maui-pr shows red, but the failures are not PR-caused — the two Build legs fail with MSB4024 (.buildtasks/*.targets "could not be loaded / being used by another process"), a known in-tree buildtasks load race, and the red uitests legs are unrelated CollectionView/Image categories (this PR only touches a SafeArea/Shell test). Pack + Helix unit + integration legs are green. A re-run should clear the infra flakes.

ℹ Automated multi-model review. This is advisory — a human maintainer makes the final merge decision.

@kubaflo

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor Author

Tests Failure Analysis

@kubaflo — test-failure review results are available based on commit 7480191.
To request a fresh review after new comments, commits, or CI runs, comment /review tests.

Overall Not ready Failures 23 Regressed vs base 2 Baseline 2 on base

Test Failure Review: Not ready - click to expand

Overall verdict: Not ready. Against main (5 recent base builds sampled per definition), 2 build legs are deterministic regressions vs base and 21 further failures could not be attributed (flaky-on-base, provisioning/infra, or unexplained build legs); only 2 distinct failures also appear on the base branch and none is confirmed pre-existing or a known-issue match, so nothing is safely dismissable while an interesting check is still pending.

  • ✗ PR-related — build-leg regressions vs base (~2 legs): publish artifacts file-upload failure and the Android Controls (API 30) Image,ImageButton,... leg (PowerShell exited with code '1') were red on the PR but green across all 5 sampled base builds; deterministic regressions, though both resemble build-host/infra errors rather than the changed test code.
  • i Uncertain — MSB4024 build-task import failures (~4 legs): .buildtasks targets missing or file-in-use during Build Microsoft.Maui.sln on macOS/Windows; per-leg regressed-vs-base but attribution indeterminate, matching recurring #36115.
  • i Uncertain — Android SDK provisioning failures (~6 legs): Failed to find package 'platform-tools;35.0.2' / avdmanager errors across macOS, Android and Windows; environmental, 2 also observed on base but not confirmable as pre-existing.
  • i Uncertain — CollectionView UI-test failures (~13 tests): timeouts and crashes such as ValidateDynamicItemTemplateDisplayed, BottomSheetDetentHeightIsCorrectWhenCollectionViewIsMeasuredBeforeMount, CollectionViewInfiniteScroll, Issue17400Test; flaky-on-base and unattributed (some tied to #36258).
  • i Uncertain — unexplained / aborted / pending legs (~17 legs): 15 failed build legs produced no extractable failure, the macOS Controls CollectionView check was CANCELLED, and the iOS Controls (vlatest) WebView check is still in progress.

Coverage: 160 checks · 149 passing · 10 failing · 1 pending · 0 inaccessible · 1 unmapped · 15 unexplained build legs · 0 unaccounted failing checks · 1 aborted failing check · 0 canceled-build checks · 0 device-test unverified · 21 unattributed · 2 regressed-vs-base. Deterministic ceiling: Not ready — pending/in-progress check, unexplained build legs, an aborted check, and 2 legs regressed vs base.

Builds (this PR): maui-pr 1504721, maui-pr-uitests 1504722, maui-pr-devicetests 1504723 (device tests confirmed clean). Base sampling (main, 5 recent builds per definition): 1503430, 1503618, 1503431.

Recommended action

Human investigation needed: confirm whether the 2 regressed-vs-base build legs and the MSB4024 .buildtasks failures are infra flakiness or real breaks, wait for the pending iOS WebView check, and re-run the cancelled macOS CollectionView leg before merging.

@kubaflo
kubaflo changed the base branch from main to inflight/current July 21, 2026 21:10
@kubaflo
kubaflo merged commit e55cb34 into inflight/current Jul 21, 2026
151 of 162 checks passed
@kubaflo
kubaflo deleted the ci-fix/issue-36259-attempt-1-fb45f4747ef0b315 branch July 21, 2026 21:10
@github-actions github-actions Bot added this to the .NET 10 SR10 milestone Jul 21, 2026
kubaflo pushed a commit that referenced this pull request Jul 22, 2026
…enceException on tab switch) (#36429)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Summary

De-flakes the Android UI test `SafeAreaShouldWorkOnAllShellTabs`
(`Issue33034`), which intermittently fails with a
`StaleElementReferenceException` thrown from `IUIElement.GetRect()`.

Target branch: main
Refs: #36259
Attempt: 1/5
Flake class: test-quality (genuine test defect) → de-flake

## Reproduction evidence

Pipeline `maui-pr-uitests` (def 313), branch `main`. The signature is
**intermittent** across the most recent completed builds — the hallmark
of a real flake, not a fixed issue:

| Build | Leg outcome | Signature |
|---|---|---|
| 1484478 | failed on first attempt, passed on retry |
`StaleElementReferenceException` at `get_Rect` |
| 1486368 | failed on first attempt, passed on retry | present |
| 3 newest (incl. latest 1495318) | passed | absent |

Failed-then-passed-on-retry **and** present-in-some-but-not-all recent
builds → genuinely flaky. `Issue33034.cs` was last modified well before
the failures began, so the recent greens are luck, not a landed fix.

## Root cause

```
App.TapTab("First Tab");                                          // starts tab-switch animation
var afterSwitchRect = App.WaitForElement("EdgeLabel").GetRect();  // find succeeds, then get_Rect races the animation
```

`WaitForElement` returns as soon as `EdgeLabel` exists, but the
tab-switch animation recycles the underlying view between the query and
the `getRect` round-trip, invalidating the element reference →
`StaleElementReferenceException` on `get_Rect()`. This is a
*pre-assertion crash*, not an assertion failure.

## Fix

Add a stale-resilient `WaitForElementAndGetRect` helper to
`HelperExtensions` that re-finds the element and retries `GetRect()`
when the reference goes stale, then use it at the two post-UI-change
rect reads in the test.

- **Condition-based, not a fixed wait** — it retries on the actual stale
condition (re-querying a fresh element each attempt via
`WaitForElement`), with no new `Thread.Sleep`/`Task.Delay`.
- **Mirrors existing framework behavior** —
`AppiumMouseActions.ProcessException` already re-finds stale elements
(*"Appium elements will sometimes become stale ... we retrieve it
here"*).
- **Assertions untouched** — the `.Within(5)` tolerance checks are
unchanged; nothing is weakened, muted, or skipped.

## Not muting

No `[ActiveIssue]`, `[SkipOnPlatform]`, `[Retry]`/`[Repeat]`, category
exclusion, csproj incompatibility, weakened assertion, or timeout bump.
The test still exercises and asserts the same SafeArea behavior on every
tab; it is simply made robust against a known Appium view-recycling
artifact during navigation animations.

## Validation

⚠️ This is an on-device Android UI test that cannot be executed in the
fixer's sandbox, so the change is **not runner-validated** (help-style).
It is a targeted, type-checked synchronization change following an
established framework pattern; CI on this PR should confirm the leg is
green.




> Generated by [CI Failure Fixer
(main)](https://github.com/dotnet/maui/actions/runs/28868353740) · 919.8
AIC · ⌖ 46 AIC · ⊞ 24.2K ·
[◷](https://github.com/search?q=repo%3Adotnet%2Fmaui+%22gh-aw-workflow-id%3A+ci-status-fix%22&type=pullrequests)

<!-- gh-aw-agentic-workflow: CI Failure Fixer (main), engine: copilot,
version: 1.0.63, model: claude-opus-4.8, id: 28868353740, workflow_id:
ci-status-fix, run:
https://github.com/dotnet/maui/actions/runs/28868353740 -->

<!-- gh-aw-workflow-id: ci-status-fix -->
<!-- gh-aw-workflow-call-id: dotnet/maui/ci-status-fix -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SyedAbdulAzeemSF4852 pushed a commit to SyedAbdulAzeemSF4852/maui that referenced this pull request Jul 27, 2026
…dotnet#36461)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## What this changes

Follow-up to dotnet#36317 (the self-watching `ci-status-fix` loop). Today,
when a `[ci-fix]` draft PR's CI comes back green — or red only on
**unrelated** flakes — the loop posts a comment but **leaves the PR as a
draft forever**. A maintainer has to notice it, confirm the specific
fixed test actually passed, and flip it to ready. In practice these
validated-green draft PRs sit unreviewed for weeks.

This PR adds a **target-test verification + mark-ready gate (Step 3.6)**
to both twins (`main` + `net11.0`). When a draft `[ci-fix]` /
`[ci-fix-net11]` PR reaches the green-surface or unrelated-flake branch,
the loop now drills into the PR's **own** AzDO test-results for the
**specific test(s)** the fix targeted. If every target test is `Passed`
on ≥1 leg and `Failed` on none (VALIDATED-GREEN), it:

- posts a `🎯 Target test validated green on <headSha>` comment (naming
the test + legs + buildId), and
- transitions the draft PR to **ready for review**.

This is a **state transition only** — it never approves and never
merges; a human still reviews and merges. Overall red on **unrelated**
legs no longer keeps a validated fix parked as a draft.

## How it works

- **Preconditions** (all required): PR `isDraft == true`; it is
unmistakably this workflow's own PR (`[ci-fix]`/`[ci-fix-net11]` title
prefix **and** `agentic-workflows` label); and it was reached from the
green or **unrelated-flake** path (never from caused-by-fix — that path
advances an attempt instead).
- **T1 — identify target test(s)** from the `[ci-scan]` issue signature
+ the PR diff. If no specific test can be identified (e.g. a product
build-break), it records a skip — build-only fixes are validated by
overall-green, which the existing green branch already handles.
- **T2 — drill AzDO test-results** for the build(s) on the PR's current
head SHA, filtered to the target test's `testCaseTitle`. A test that
never ran (e.g. an `/azp`-gated `maui-pr-uitests`/`maui-pr-devicetests`
leg that wasn't kicked) is **not** validated — the loop records an
honest "not yet executed" skip and does **not** mark ready. No
overclaiming: a green *sibling* leg is not the target test.
- **T3 — mark ready + report**, guarded by a per-head-SHA idempotency
marker and the existing `dry_run` gate (dry-run emits nothing and
tallies `would-mark-ready`).

## Safe-output

Adds the `mark-pull-request-as-ready-for-review` safe-output to both
twins (`max: 3`, `target: "*"`, `required-title-prefix` +
`required-labels`). Unlike `update-pull-request`, this output's
`required-*` guards **do** survive the gh-aw v0.80.9 compile (verified
against the generated locks), so which-PR scoping is enforced at the
handler level in addition to the Step 3.6 preconditions and
`min-integrity: approved`. No gh-aw version bump is required — the
capability already exists at our pinned v0.80.9.

## Enabling fix — the loop's own create-PR commit no longer counts as
"human engaged"

While validating this feature against dotnet#36429 I found the mark-ready path
was **unreachable for every loop-owned draft PR**, and traced it to a
regression from dotnet#36317's own review-hardening.

gh-aw's `create_pull_request` builds a PR's initial commit through the
GitHub API, which stamps `author=github-actions[bot]` but
**`committer=web-flow`**. Commit `2f6b77b330` (in dotnet#36317) removed
`web-flow` from the prefetch's bot-login denylist so a maintainer
"Update branch" would correctly hand the PR off — but that also made
`Test-AnyHumanCommitActor`'s committer check read the loop's **own**
first commit as human engagement. Result: every freshly opened
`[ci-fix]` draft PR computed `humanEngaged=true` from commit #1, so the
watch loop skipped it forever — never surfacing green, never marking
ready. This regression is live on `main` today (all four open loop-owned
draft PRs have `committer=web-flow`).

Fix (`Query-CiFixPRs.ps1`): a human **committer** only trips the
hand-off when the commit **author** is not one of this workflow's own
bot identities (`$LoopBotCommitAuthors`). A human **author** still
counts unconditionally, so maintainer direct commits and
web-flow-authored "Update branch" merges continue to hand off correctly.
Unit-tested across all six author/committer shapes.

## Validation

- Both twins recompiled with `gh aw compile` (0 errors / 0 warnings);
locks show no action-SHA or `compiler_version` drift (only
frontmatter/body hash + the new handler config).
- `mark_pull_request_as_ready_for_review` config confirmed present in
**both** locks with the correct `[ci-fix] ` / `[ci-fix-net11] ` prefixes
and `agentic-workflows` label; the `safe_outputs` job carries
`pull-requests: write`.
- Twin symmetry preserved (only `[ci-fix]` ↔ `[ci-fix-net11]` /
`ci-scan` ↔ `ci-scan-net11` token differences).
- **Live dry-run against dotnet#36429** (scoped `workflow_dispatch`,
`dry_run=true`, this branch): the workflow prefetch now computes
`humanEngaged=false` for dotnet#36429 (was `true` pre-fix), and the agent's
gate walk correctly advances **past** the human-engaged gate to the
CI-pending WAIT gate — `checksSettled=false` because dotnet#36429's macOS
`SafeAreaEdges` leg is still queued. Once that leg settles green, the
same run path reaches Step 3.6 and marks the PR ready. Emitted zero
writes (dry-run).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: PureWeen <223556219+Copilot@users.noreply.github.com>
kubaflo pushed a commit that referenced this pull request Jul 28, 2026
…enceException on tab switch) (#36429)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Summary

De-flakes the Android UI test `SafeAreaShouldWorkOnAllShellTabs`
(`Issue33034`), which intermittently fails with a
`StaleElementReferenceException` thrown from `IUIElement.GetRect()`.

Target branch: main
Refs: #36259
Attempt: 1/5
Flake class: test-quality (genuine test defect) → de-flake

## Reproduction evidence

Pipeline `maui-pr-uitests` (def 313), branch `main`. The signature is
**intermittent** across the most recent completed builds — the hallmark
of a real flake, not a fixed issue:

| Build | Leg outcome | Signature |
|---|---|---|
| 1484478 | failed on first attempt, passed on retry |
`StaleElementReferenceException` at `get_Rect` |
| 1486368 | failed on first attempt, passed on retry | present |
| 3 newest (incl. latest 1495318) | passed | absent |

Failed-then-passed-on-retry **and** present-in-some-but-not-all recent
builds → genuinely flaky. `Issue33034.cs` was last modified well before
the failures began, so the recent greens are luck, not a landed fix.

## Root cause

```
App.TapTab("First Tab");                                          // starts tab-switch animation
var afterSwitchRect = App.WaitForElement("EdgeLabel").GetRect();  // find succeeds, then get_Rect races the animation
```

`WaitForElement` returns as soon as `EdgeLabel` exists, but the
tab-switch animation recycles the underlying view between the query and
the `getRect` round-trip, invalidating the element reference →
`StaleElementReferenceException` on `get_Rect()`. This is a
*pre-assertion crash*, not an assertion failure.

## Fix

Add a stale-resilient `WaitForElementAndGetRect` helper to
`HelperExtensions` that re-finds the element and retries `GetRect()`
when the reference goes stale, then use it at the two post-UI-change
rect reads in the test.

- **Condition-based, not a fixed wait** — it retries on the actual stale
condition (re-querying a fresh element each attempt via
`WaitForElement`), with no new `Thread.Sleep`/`Task.Delay`.
- **Mirrors existing framework behavior** —
`AppiumMouseActions.ProcessException` already re-finds stale elements
(*"Appium elements will sometimes become stale ... we retrieve it
here"*).
- **Assertions untouched** — the `.Within(5)` tolerance checks are
unchanged; nothing is weakened, muted, or skipped.

## Not muting

No `[ActiveIssue]`, `[SkipOnPlatform]`, `[Retry]`/`[Repeat]`, category
exclusion, csproj incompatibility, weakened assertion, or timeout bump.
The test still exercises and asserts the same SafeArea behavior on every
tab; it is simply made robust against a known Appium view-recycling
artifact during navigation animations.

## Validation

⚠️ This is an on-device Android UI test that cannot be executed in the
fixer's sandbox, so the change is **not runner-validated** (help-style).
It is a targeted, type-checked synchronization change following an
established framework pattern; CI on this PR should confirm the leg is
green.




> Generated by [CI Failure Fixer
(main)](https://github.com/dotnet/maui/actions/runs/28868353740) · 919.8
AIC · ⌖ 46 AIC · ⊞ 24.2K ·
[◷](https://github.com/search?q=repo%3Adotnet%2Fmaui+%22gh-aw-workflow-id%3A+ci-status-fix%22&type=pullrequests)

<!-- gh-aw-agentic-workflow: CI Failure Fixer (main), engine: copilot,
version: 1.0.63, model: claude-opus-4.8, id: 28868353740, workflow_id:
ci-status-fix, run:
https://github.com/dotnet/maui/actions/runs/28868353740 -->

<!-- gh-aw-workflow-id: ci-status-fix -->
<!-- gh-aw-workflow-call-id: dotnet/maui/ci-status-fix -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kubaflo pushed a commit that referenced this pull request Jul 29, 2026
…enceException on tab switch) (#36429)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Summary

De-flakes the Android UI test `SafeAreaShouldWorkOnAllShellTabs`
(`Issue33034`), which intermittently fails with a
`StaleElementReferenceException` thrown from `IUIElement.GetRect()`.

Target branch: main
Refs: #36259
Attempt: 1/5
Flake class: test-quality (genuine test defect) → de-flake

## Reproduction evidence

Pipeline `maui-pr-uitests` (def 313), branch `main`. The signature is
**intermittent** across the most recent completed builds — the hallmark
of a real flake, not a fixed issue:

| Build | Leg outcome | Signature |
|---|---|---|
| 1484478 | failed on first attempt, passed on retry |
`StaleElementReferenceException` at `get_Rect` |
| 1486368 | failed on first attempt, passed on retry | present |
| 3 newest (incl. latest 1495318) | passed | absent |

Failed-then-passed-on-retry **and** present-in-some-but-not-all recent
builds → genuinely flaky. `Issue33034.cs` was last modified well before
the failures began, so the recent greens are luck, not a landed fix.

## Root cause

```
App.TapTab("First Tab");                                          // starts tab-switch animation
var afterSwitchRect = App.WaitForElement("EdgeLabel").GetRect();  // find succeeds, then get_Rect races the animation
```

`WaitForElement` returns as soon as `EdgeLabel` exists, but the
tab-switch animation recycles the underlying view between the query and
the `getRect` round-trip, invalidating the element reference →
`StaleElementReferenceException` on `get_Rect()`. This is a
*pre-assertion crash*, not an assertion failure.

## Fix

Add a stale-resilient `WaitForElementAndGetRect` helper to
`HelperExtensions` that re-finds the element and retries `GetRect()`
when the reference goes stale, then use it at the two post-UI-change
rect reads in the test.

- **Condition-based, not a fixed wait** — it retries on the actual stale
condition (re-querying a fresh element each attempt via
`WaitForElement`), with no new `Thread.Sleep`/`Task.Delay`.
- **Mirrors existing framework behavior** —
`AppiumMouseActions.ProcessException` already re-finds stale elements
(*"Appium elements will sometimes become stale ... we retrieve it
here"*).
- **Assertions untouched** — the `.Within(5)` tolerance checks are
unchanged; nothing is weakened, muted, or skipped.

## Not muting

No `[ActiveIssue]`, `[SkipOnPlatform]`, `[Retry]`/`[Repeat]`, category
exclusion, csproj incompatibility, weakened assertion, or timeout bump.
The test still exercises and asserts the same SafeArea behavior on every
tab; it is simply made robust against a known Appium view-recycling
artifact during navigation animations.

## Validation

⚠️ This is an on-device Android UI test that cannot be executed in the
fixer's sandbox, so the change is **not runner-validated** (help-style).
It is a targeted, type-checked synchronization change following an
established framework pattern; CI on this PR should confirm the leg is
green.




> Generated by [CI Failure Fixer
(main)](https://github.com/dotnet/maui/actions/runs/28868353740) · 919.8
AIC · ⌖ 46 AIC · ⊞ 24.2K ·
[◷](https://github.com/search?q=repo%3Adotnet%2Fmaui+%22gh-aw-workflow-id%3A+ci-status-fix%22&type=pullrequests)

<!-- gh-aw-agentic-workflow: CI Failure Fixer (main), engine: copilot,
version: 1.0.63, model: claude-opus-4.8, id: 28868353740, workflow_id:
ci-status-fix, run:
https://github.com/dotnet/maui/actions/runs/28868353740 -->

<!-- gh-aw-workflow-id: ci-status-fix -->
<!-- gh-aw-workflow-call-id: dotnet/maui/ci-status-fix -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kubaflo pushed a commit that referenced this pull request Aug 7, 2026
…enceException on tab switch) (#36429)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Summary

De-flakes the Android UI test `SafeAreaShouldWorkOnAllShellTabs`
(`Issue33034`), which intermittently fails with a
`StaleElementReferenceException` thrown from `IUIElement.GetRect()`.

Target branch: main
Refs: #36259
Attempt: 1/5
Flake class: test-quality (genuine test defect) → de-flake

## Reproduction evidence

Pipeline `maui-pr-uitests` (def 313), branch `main`. The signature is
**intermittent** across the most recent completed builds — the hallmark
of a real flake, not a fixed issue:

| Build | Leg outcome | Signature |
|---|---|---|
| 1484478 | failed on first attempt, passed on retry |
`StaleElementReferenceException` at `get_Rect` |
| 1486368 | failed on first attempt, passed on retry | present |
| 3 newest (incl. latest 1495318) | passed | absent |

Failed-then-passed-on-retry **and** present-in-some-but-not-all recent
builds → genuinely flaky. `Issue33034.cs` was last modified well before
the failures began, so the recent greens are luck, not a landed fix.

## Root cause

```
App.TapTab("First Tab");                                          // starts tab-switch animation
var afterSwitchRect = App.WaitForElement("EdgeLabel").GetRect();  // find succeeds, then get_Rect races the animation
```

`WaitForElement` returns as soon as `EdgeLabel` exists, but the
tab-switch animation recycles the underlying view between the query and
the `getRect` round-trip, invalidating the element reference →
`StaleElementReferenceException` on `get_Rect()`. This is a
*pre-assertion crash*, not an assertion failure.

## Fix

Add a stale-resilient `WaitForElementAndGetRect` helper to
`HelperExtensions` that re-finds the element and retries `GetRect()`
when the reference goes stale, then use it at the two post-UI-change
rect reads in the test.

- **Condition-based, not a fixed wait** — it retries on the actual stale
condition (re-querying a fresh element each attempt via
`WaitForElement`), with no new `Thread.Sleep`/`Task.Delay`.
- **Mirrors existing framework behavior** —
`AppiumMouseActions.ProcessException` already re-finds stale elements
(*"Appium elements will sometimes become stale ... we retrieve it
here"*).
- **Assertions untouched** — the `.Within(5)` tolerance checks are
unchanged; nothing is weakened, muted, or skipped.

## Not muting

No `[ActiveIssue]`, `[SkipOnPlatform]`, `[Retry]`/`[Repeat]`, category
exclusion, csproj incompatibility, weakened assertion, or timeout bump.
The test still exercises and asserts the same SafeArea behavior on every
tab; it is simply made robust against a known Appium view-recycling
artifact during navigation animations.

## Validation

⚠️ This is an on-device Android UI test that cannot be executed in the
fixer's sandbox, so the change is **not runner-validated** (help-style).
It is a targeted, type-checked synchronization change following an
established framework pattern; CI on this PR should confirm the leg is
green.




> Generated by [CI Failure Fixer
(main)](https://github.com/dotnet/maui/actions/runs/28868353740) · 919.8
AIC · ⌖ 46 AIC · ⊞ 24.2K ·
[◷](https://github.com/search?q=repo%3Adotnet%2Fmaui+%22gh-aw-workflow-id%3A+ci-status-fix%22&type=pullrequests)

<!-- gh-aw-agentic-workflow: CI Failure Fixer (main), engine: copilot,
version: 1.0.63, model: claude-opus-4.8, id: 28868353740, workflow_id:
ci-status-fix, run:
https://github.com/dotnet/maui/actions/runs/28868353740 -->

<!-- gh-aw-workflow-id: ci-status-fix -->
<!-- gh-aw-workflow-call-id: dotnet/maui/ci-status-fix -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kubaflo pushed a commit that referenced this pull request Aug 12, 2026
…enceException on tab switch) (#36429)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Summary

De-flakes the Android UI test `SafeAreaShouldWorkOnAllShellTabs`
(`Issue33034`), which intermittently fails with a
`StaleElementReferenceException` thrown from `IUIElement.GetRect()`.

Target branch: main
Refs: #36259
Attempt: 1/5
Flake class: test-quality (genuine test defect) → de-flake

## Reproduction evidence

Pipeline `maui-pr-uitests` (def 313), branch `main`. The signature is
**intermittent** across the most recent completed builds — the hallmark
of a real flake, not a fixed issue:

| Build | Leg outcome | Signature |
|---|---|---|
| 1484478 | failed on first attempt, passed on retry |
`StaleElementReferenceException` at `get_Rect` |
| 1486368 | failed on first attempt, passed on retry | present |
| 3 newest (incl. latest 1495318) | passed | absent |

Failed-then-passed-on-retry **and** present-in-some-but-not-all recent
builds → genuinely flaky. `Issue33034.cs` was last modified well before
the failures began, so the recent greens are luck, not a landed fix.

## Root cause

```
App.TapTab("First Tab");                                          // starts tab-switch animation
var afterSwitchRect = App.WaitForElement("EdgeLabel").GetRect();  // find succeeds, then get_Rect races the animation
```

`WaitForElement` returns as soon as `EdgeLabel` exists, but the
tab-switch animation recycles the underlying view between the query and
the `getRect` round-trip, invalidating the element reference →
`StaleElementReferenceException` on `get_Rect()`. This is a
*pre-assertion crash*, not an assertion failure.

## Fix

Add a stale-resilient `WaitForElementAndGetRect` helper to
`HelperExtensions` that re-finds the element and retries `GetRect()`
when the reference goes stale, then use it at the two post-UI-change
rect reads in the test.

- **Condition-based, not a fixed wait** — it retries on the actual stale
condition (re-querying a fresh element each attempt via
`WaitForElement`), with no new `Thread.Sleep`/`Task.Delay`.
- **Mirrors existing framework behavior** —
`AppiumMouseActions.ProcessException` already re-finds stale elements
(*"Appium elements will sometimes become stale ... we retrieve it
here"*).
- **Assertions untouched** — the `.Within(5)` tolerance checks are
unchanged; nothing is weakened, muted, or skipped.

## Not muting

No `[ActiveIssue]`, `[SkipOnPlatform]`, `[Retry]`/`[Repeat]`, category
exclusion, csproj incompatibility, weakened assertion, or timeout bump.
The test still exercises and asserts the same SafeArea behavior on every
tab; it is simply made robust against a known Appium view-recycling
artifact during navigation animations.

## Validation

⚠️ This is an on-device Android UI test that cannot be executed in the
fixer's sandbox, so the change is **not runner-validated** (help-style).
It is a targeted, type-checked synchronization change following an
established framework pattern; CI on this PR should confirm the leg is
green.




> Generated by [CI Failure Fixer
(main)](https://github.com/dotnet/maui/actions/runs/28868353740) · 919.8
AIC · ⌖ 46 AIC · ⊞ 24.2K ·
[◷](https://github.com/search?q=repo%3Adotnet%2Fmaui+%22gh-aw-workflow-id%3A+ci-status-fix%22&type=pullrequests)

<!-- gh-aw-agentic-workflow: CI Failure Fixer (main), engine: copilot,
version: 1.0.63, model: claude-opus-4.8, id: 28868353740, workflow_id:
ci-status-fix, run:
https://github.com/dotnet/maui/actions/runs/28868353740 -->

<!-- gh-aw-workflow-id: ci-status-fix -->
<!-- gh-aw-workflow-call-id: dotnet/maui/ci-status-fix -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 21, 2026
@sheiksyedm sheiksyedm modified the milestones: .NET 10 SR10, .NET 10 SR11 Aug 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

agentic-workflows s/agent-fix-win AI found a better alternative fix than the PR s/agent-gate-failed AI could not verify tests catch the bug s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants