Skip to content

feat(runtime): add pilot runtime adapter - #112

Closed
drown0315 wants to merge 12 commits into
mainfrom
refactor/split-cli-command-modules
Closed

drown0315 wants to merge 12 commits into
mainfrom
refactor/split-cli-command-modules

Conversation

@drown0315

Copy link
Copy Markdown
Owner

What Changed

  • Added the pilot runtime package and adapter path for VM-service handshake, runtime adapter selection, widget tree capture normalization, and related runtime tests.
  • Split the monolithic CLI command implementation into command-specific modules and extracted test command execution, output, device discovery, and scenario runner factory support.
  • Updated runtime planning/docs and issue tracking notes, and added the missing package lint dependency needed by the new package layout.

Risk Assessment

🚨 High: The change introduces a likely package-resolution break for the Dart CLI by pulling a Flutter SDK dependency into the root package, so it should not merge without an explicit packaging decision.

Testing

Exercised the refactored CLI command surface, command orchestration, runtime adapter selection, pilot runtime adapter/VM-service behavior, nested pilot_runtime Flutter tests, and manual end-user CLI/report generation evidence; the valid commands passed and the only failures were corrected test-runner/package-context attempts.

Evidence: Generated timeline report
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>split_cli_command_modules timeline</title>
<style>
body {
  margin: 0;
  background: #f6f7f9;
  color: #202124;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

main {
  max-width: 960px;
  margin: 0 auto;
  padding: 32px 20px;
}

.run-summary,
.step {
  background: #ffffff;
  border: 1px solid #d9dde3;
  border-radius: 8px;
  margin-bottom: 16px;
  padding: 20px;
}

.step-heading {
  align-items: center;
  display: flex;
  gap: 12px;
  justify-content: space-between;
}

h1,
h2,
p {
  margin-top: 0;
}

dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 8px 16px;
}

dt {
  color: #59616e;
  font-weight: 600;
}

dd {
  margin: 0;
}

.status {
  border-radius: 999px;
  display: inline-block;
  font-size: 13px;
  font-weight: 700;
  padding: 4px 10px;
  text-transform: uppercase;
}

.status-passed {
  background: #d8f5df;
  color: #116329;
}

.status-failed {
  background: #ffe0e0;
  color: #9f1c1c;
}

.status-skipped {
  background: #eceff3;
  color: #4f5b67;
}

.step-failed {
  border-color: #e05b5b;
}

.failure-reason {
  color: #9f1c1c;
  font-weight: 600;
}

.artifacts {
  display: grid;
  gap: 12px;
  list-style: none;
  padding: 0;
}

.artifacts img {
  border: 1px solid #d9dde3;
  display: block;
  margin-top: 8px;
  max-width: 100%;
}

</style>
</head>
<body>
<main>
<header class="run-summary">
<h1>split_cli_command_modules</h1>
<p class="status status-failed">failed</p>
<dl>
<dt>Started</dt>
<dd>2026-07-08T09:00:00.000Z</dd>
<dt>Duration</dt>
<dd>87 ms</dd>
</dl>
</header>
<section class="timeline">
<article class="step step-failed">
<div class="step-heading">
<h2>Step 1: submit</h2>
<span class="status status-failed">failed</span>
</div>
<dl>
<dt>Action</dt>
<dd>tap</dd>
<dt>Duration</dt>
<dd>12 ms</dd>
</dl>
<p class="failure-reason">Finder matched no widgets.</p>
</article>
</section>
</main>
</body>
</html>
Evidence: test --help output

Launch the Target App Package and run a Scenario. Usage: flutter_pilot test [arguments] -h, --help Print this usage information. -d, --device Target Device id, exact name, or unique id/name prefix. --flavor Flutter flavor passed to flutter run. -t, --target Flutter app entrypoint file passed to flutter run. --until Run through a 1-based step number or step label. --print Print diagnostics after --until. [snapshot, widget-tree, errors] --json Print raw diagnostics as indented JSON. Run "flutter_pilot help" to see global options.

Launch the Target App Package and run a Scenario.

Usage: flutter_pilot test [arguments]
-h, --help      Print this usage information.
-d, --device    Target Device id, exact name, or unique id/name prefix.
    --flavor    Flutter flavor passed to flutter run.
-t, --target    Flutter app entrypoint file passed to flutter run.
    --until     Run through a 1-based step number or step label.
    --print     Print diagnostics after --until.
                [snapshot, widget-tree, errors]
    --json      Print raw diagnostics as indented JSON.

Run "flutter_pilot help" to see global options.
Evidence: validate command output

Scenario is valid.

Scenario is valid.
Evidence: report command output

HTML report: /var/folders/1b/xbh8qb0d0j11fzyfm0qs0pf40000gn/T/no-mistakes-evidence/01KX0XMY4BTNEXM92FDNB8YA3Y/report-run/timeline.html

HTML report: /var/folders/1b/xbh8qb0d0j11fzyfm0qs0pf40000gn/T/no-mistakes-evidence/01KX0XMY4BTNEXM92FDNB8YA3Y/report-run/timeline.html

Pipeline

Updates from git push no-mistakes

⏭️ **intent** - skipped

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⏭️ **Review** - skipped
  • 🚨 pubspec.yaml:15 - The root CLI package now has a direct path dependency on pilot_runtime, but that package depends on the Flutter SDK. This turns the previously Dart-only CLI into a package that cannot be resolved with the Dart SDK alone, contradicting the repo's documented dart format/analyze/test workflow and breaking users/environments without Flutter SDK package resolution. Consider splitting the non-Flutter VM-service client/protocol into a Dart-only package or keeping Flutter-only binding code out of the CLI dependency graph.
  • ⚠️ packages/pilot_runtime/lib/src/pilot_runtime_client.dart:269 - initialize() only maps PilotRuntimeServiceExtensionMissingException into a typed initialization failure. VM Service connection errors, RPC errors other than missing extension, or unexpected service failures will escape as raw exceptions through PilotRuntimeAdapter.initialize(), so ScenarioRunner will not turn them into a run-level failure/report. Wrap lower-level handshake call failures in PilotRuntimeInitializationException so the adapter consistently raises RuntimeOperationException.
✅ **Test** - passed

✅ No issues found.

  • dart test test/cli_test.dart test/test_command_executor_test.dart test/runtime_adapter_selection_test.dart test/pilot_runtime_adapter_test.dart test/pilot_runtime_vm_service_test.dart
  • dart test packages/pilot_runtime/test (setup-mismatched attempt: failed because Flutter package tests require Flutter test runner/package context)
  • flutter test packages/pilot_runtime/test (setup-mismatched attempt: failed because it resolved from the root package instead of packages/pilot_runtime)
  • flutter test test from packages/pilot_runtime
  • dart run bin/flutter_pilot.dart test --help > .../test-help.stdout 2> .../test-help.stderr
  • dart run bin/flutter_pilot.dart validate examples/login_error.yaml > .../validate-valid.stdout 2> .../validate-valid.stderr
  • dart run bin/flutter_pilot.dart report .../report-run > .../report-command.stdout 2> .../report-command.stderr
  • Verified generated timeline.html contains split_cli_command_modules, step-failed, and Finder matched no widgets.
  • Removed transient packages/pilot_runtime/pubspec.lock created by Flutter dependency resolution and rechecked git status --short.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@drown0315 drown0315 closed this Jul 8, 2026
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