Files
wx-win-agent/node-agent/WxAgent.Core/UiSnapshotDiagnostics.cs
T

45 lines
1.7 KiB
C#

namespace WxAgent.Core;
public sealed class UiTraversalGuard(int maxNodes = 10_000, int maxDepth = 40)
{
private readonly HashSet<string> _visited = new(StringComparer.Ordinal);
public int NodeCount { get; private set; }
public bool Truncated { get; private set; }
public bool CycleDetected { get; private set; }
public bool TryVisit(string runtimeId, int depth)
{
if (NodeCount >= maxNodes || depth > maxDepth)
{
Truncated = true;
return false;
}
if (runtimeId.Length > 0 && !_visited.Add(runtimeId))
{
CycleDetected = true;
return false;
}
NodeCount++;
return true;
}
}
public sealed record UiSnapshotComparison(IReadOnlyList<string> AddedAutomationIds,
IReadOnlyList<string> RemovedAutomationIds, IReadOnlyList<string> MissingRequiredControls)
{
public static UiSnapshotComparison Compare(UiNodeSnapshot baseline, UiNodeSnapshot current)
{
static IEnumerable<string> ReadIds(UiNodeSnapshot root) =>
new[] { root.AutomationId }.Concat(root.Children.SelectMany(ReadIds));
static HashSet<string> Ids(UiNodeSnapshot root) => ReadIds(root)
.Where(id => id.Length > 0 && !id.StartsWith("[id:", StringComparison.Ordinal))
.ToHashSet(StringComparer.Ordinal);
var before = Ids(baseline);
var after = Ids(current);
return new UiSnapshotComparison(
after.Except(before).Order(StringComparer.Ordinal).ToArray(),
before.Except(after).Order(StringComparer.Ordinal).ToArray(),
WechatLocators.RequiredAutomationIds.Where(id => !after.Contains(id)).ToArray());
}
}