Skip to content

refactor(ios): single CommandTraits table for runner command classification#642

Merged
thymikee merged 3 commits into
mainfrom
refactor/ios-runner-command-traits
Jun 1, 2026
Merged

refactor(ios): single CommandTraits table for runner command classification#642
thymikee merged 3 commits into
mainfrom
refactor/ios-runner-command-traits

Conversation

@thymikee
Copy link
Copy Markdown
Member

@thymikee thymikee commented Jun 1, 2026

What

Replace the three hand-maintained switches in RunnerTests+Lifecycle.swiftisInteractionCommand, isReadOnlyCommand, isRunnerLifecycleCommand — with a single source of truth: CommandType.traits, an exhaustive switch returning a CommandTraits struct, collocated with CommandType in RunnerTests+Models.swift.

CommandTraits has three independent axes:

  • isInteraction — needs the foreground-guard + stabilization preflight
  • readOnly: .always/.never/.conditional — eligible for the session-invalidating retry (.conditional preserves alert's action-dependent behavior)
  • isLifecycle — skips the app-activation preflight

Why

Adding a command meant editing up to three separate switches; screenshot already lived in two. That scatter is exactly what historically let tapSeries/dragSeries/keyboardReturn drift out of isInteractionCommand. The exhaustive switch makes it a compile error to add a CommandType without classifying it.

Pure refactor — no behavior change

Every command's classification is reproduced verbatim. The three predicates become one-line lookups with unchanged signatures, so all call sites in CommandExecution are untouched. Classification feeds ADR-0002 session invalidation (the read-only retry that nulls currentApp/currentBundleId), so behaviour is intentionally identical.

A NOTE comment in the table documents the pre-existing classifications it preserves — including two latent inconsistencies the work surfaced: querySelector is not read-only, and recordStart is not a lifecycle command. These (and the isInteraction omissions) are deliberately left for a separate normalization PR.

Verification

  • xcodebuild build-for-testing (UITest bundle) compiles: TEST BUILD SUCCEEDED.
  • No unit-test target exists in the project; correctness rests on the exhaustive switch (completeness) + a verbatim, reviewable diff.

Docs

Adds the "Runner command traits" term to CONTEXT.md.

Follow-up (separate PR)

Reclassify tapSeries/dragSeries/keyboardReturn as interaction commands, and evaluate mouseClick (macOS-only; needs a macOS smoke check) — each with e2e evidence.

…cation

Replace the three hand-maintained switches in RunnerTests+Lifecycle.swift
(isInteractionCommand / isReadOnlyCommand / isRunnerLifecycleCommand) with one
source of truth: CommandType.traits, an exhaustive switch returning a
CommandTraits struct (interaction / readOnly / lifecycle axes), collocated with
CommandType in RunnerTests+Models.swift.

Pure refactor: every command's classification is reproduced verbatim, and the
three predicates become one-line lookups with unchanged signatures, so call
sites are untouched. The exhaustive switch makes it a compile error to add a
CommandType without classifying it, closing the drift that historically let
tapSeries/dragSeries/keyboardReturn fall out of isInteractionCommand.

readOnly is a 3-state enum (.always/.never/.conditional); .conditional preserves
alert's action-dependent read-only behavior, resolved in isReadOnlyCommand.
Classification feeds ADR-0002 session invalidation (the read-only retry that
nulls currentApp/currentBundleId), so behavior is intentionally unchanged.

Adds the "Runner command traits" term to CONTEXT.md.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 1, 2026

Size Report

Metric Base Current Diff
JS raw 1.1 MB 1.1 MB 0 B
JS gzip 357.7 kB 357.7 kB 0 B
npm tarball 457.2 kB 458.5 kB +1.3 kB
npm unpacked 1.5 MB 1.5 MB +3.3 kB

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 26.2 ms 26.3 ms +0.1 ms
CLI --help 41.3 ms 41.5 ms +0.2 ms

Top changed chunks: no changes in the largest emitted chunks.

thymikee added a commit that referenced this pull request Jun 1, 2026
… commands

tapSeries and dragSeries are the series forms of tap/drag (already interaction
commands); keyboardReturn is the sibling of keyboardDismiss (already an
interaction command). All three were missing from the historical
isInteractionCommand switch — a drift the new CommandTraits table (#642) makes
visible. Classifying them as interaction commands gives them the foreground-guard
+ stabilization preflight that their single-shot/sibling forms already get.

Behavior change: these three commands now re-activate a backgrounded target to
foreground and pay the stabilization delays before running. Ships separately from
the CommandTraits refactor (#642) and should land after that bakes.

mouseClick left unchanged: macOS-only and the foreground guard interacts with
bespoke macOS activation, so it needs a macOS smoke check first.
… commands (#643)

* fix(ios): classify tapSeries/dragSeries/keyboardReturn as interaction commands

tapSeries and dragSeries are the series forms of tap/drag (already interaction
commands); keyboardReturn is the sibling of keyboardDismiss (already an
interaction command). All three were missing from the historical
isInteractionCommand switch — a drift the new CommandTraits table (#642) makes
visible. Classifying them as interaction commands gives them the foreground-guard
+ stabilization preflight that their single-shot/sibling forms already get.

Behavior change: these three commands now re-activate a backgrounded target to
foreground and pay the stabilization delays before running. Ships separately from
the CommandTraits refactor (#642) and should land after that bakes.

mouseClick left unchanged: macOS-only and the foreground guard interacts with
bespoke macOS activation, so it needs a macOS smoke check first.

* test: cover iOS runner series commands in perf harness
@thymikee thymikee merged commit 5492cf4 into main Jun 1, 2026
18 checks passed
@thymikee thymikee deleted the refactor/ios-runner-command-traits branch June 1, 2026 16:11
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 1, 2026

PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-06-01 16:11 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant