InkkOops

Selectors and waits

This page covers the mechanics of finding a target and deciding when it is safe to interact with that target. These details matter because many runtime failures are really target-resolution failures or actionability failures.

Selector types

  • Name("...") targets an explicit x:Name.
  • AutomationId("...") targets an automation id.
  • AutomationName("...") targets an automation name.
  • Within(...) scopes one selector inside another.
  • DescendantOf(...) scopes the target beneath a container.
  • WithIndex(...) disambiguates multiple matches.

Resolution order

When a simple identifier selector is used, resolution prefers:

  1. x:Name
  2. automation id
  3. automation name

If none of those produce a match, the selector is Unresolved. If more than one match remains and no index is given, the selector is Ambiguous.

Examples

var sidebar = InkkOopsTargetSelector.Name("CatalogSidebarScrollViewer");
var previewHost = InkkOopsTargetSelector.AutomationId("PreviewHost");
var richTextBox = InkkOopsTargetSelector.AutomationName("RichTextBox");

var richTextBoxInSidebar =
    InkkOopsTargetSelector.Within(sidebar, richTextBox);

var secondDeleteButton =
    InkkOopsTargetSelector.DescendantOf(
        InkkOopsTargetSelector.Name("ToolbarHost"),
        InkkOopsTargetSelector.AutomationName("Delete"))
    .WithIndex(1);

Those identifiers are host-profile examples from this repository, not universal core names.

Wait conditions

  • WaitForElement: the selector resolves.
  • WaitForVisible: the target exists and is visible.
  • WaitForEnabled: the target exists and is enabled.
  • WaitForInViewport: the action point is inside the viewport.
  • WaitForInteractive: the target is usable for pointer interaction.

Why actionability matters

A target can exist and still fail interaction for multiple reasons: it may be unrealized, offscreen, clipped, disabled, or blocked at the action point. InkkOops exposes those cases explicitly instead of treating every failure as "not found."

Example wait pattern

var target = InkkOopsTargetSelector.Within(
    InkkOopsTargetSelector.Name("CatalogSidebarScrollViewer"),
    InkkOopsTargetSelector.AutomationName("RichTextBox"));

return new InkkOopsScriptBuilder("sidebar-richtextbox")
    .WaitForInteractive(target, maxFrames: 120)
    .Hover(target)
    .Click(target)
    .WaitForIdle(InkkOopsIdlePolicy.DiagnosticsStable)
    .Build();

Failure categories you will see

  • Unresolved
  • Ambiguous
  • Unrealized
  • Offscreen
  • Clipped
  • Disabled
  • NotInteractive