From 3783c349b0875638cfd3c55f001d651e015fe134 Mon Sep 17 00:00:00 2001 From: Cameron Cooke Date: Wed, 8 Apr 2026 22:06:26 +0100 Subject: [PATCH 1/9] refactor: add snapshot test fixtures and benchmarks for rendering pipeline --- .../flowdeck-run-1.stderr.txt | 0 .../flowdeck-run-1.stdout.txt | 51 ++ .../flowdeck-run-2.stderr.txt | 0 .../flowdeck-run-2.stdout.txt | 51 ++ .../flowdeck-run-3.stderr.txt | 0 .../flowdeck-run-3.stdout.txt | 51 ++ .../2026-03-17T14-18-19-390Z/summary.json | 74 ++ .../xcodebuildmcp-run-1.stderr.txt | 0 .../xcodebuildmcp-run-1.stdout.txt | 669 ++++++++++++++++++ .../xcodebuildmcp-run-2.stderr.txt | 0 .../xcodebuildmcp-run-2.stdout.txt | 461 ++++++++++++ .../xcodebuildmcp-run-3.stderr.txt | 0 .../xcodebuildmcp-run-3.stdout.txt | 495 +++++++++++++ .../flowdeck-run-1.stderr.txt | 0 .../flowdeck-run-1.stdout.txt | 51 ++ .../2026-03-17T14-22-25-469Z/summary.json | 30 + .../xcodebuildmcp-run-1.stderr.txt | 0 .../xcodebuildmcp-run-1.stdout.txt | 669 ++++++++++++++++++ .../flowdeck-run-1.stderr.txt | 0 .../flowdeck-run-1.stdout.txt | 51 ++ .../2026-03-17T14-57-22-646Z/summary.json | 30 + .../xcodebuildmcp-run-1.stderr.txt | 0 .../xcodebuildmcp-run-1.stdout.txt | 635 +++++++++++++++++ ...-coverage-report--error-invalid-bundle.txt | 6 + .../coverage/get-coverage-report--success.txt | 13 + ...et-file-coverage--error-invalid-bundle.txt | 7 + .../coverage/get-file-coverage--success.txt | 29 + .../add-breakpoint--error-no-session.txt | 4 + .../debugging/add-breakpoint--success.txt | 7 + .../debugging/attach--error-no-process.txt | 4 + .../debugging/attach--success-continue.txt | 12 + .../debugging/attach--success.txt | 12 + .../debugging/continue--error-no-session.txt | 4 + .../debugging/continue--success.txt | 4 + .../debugging/detach--error-no-session.txt | 4 + .../debugging/detach--success.txt | 4 + .../lldb-command--error-no-session.txt | 6 + .../debugging/lldb-command--success.txt | 12 + .../remove-breakpoint--error-no-session.txt | 4 + .../debugging/remove-breakpoint--success.txt | 7 + .../debugging/stack--error-no-session.txt | 4 + .../__fixtures__/debugging/stack--success.txt | 11 + .../debugging/variables--error-no-session.txt | 4 + .../debugging/variables--success.txt | 18 + .../device/build--error-wrong-scheme.txt | 15 + .../__fixtures__/device/build--success.txt | 14 + .../device/build-and-run--success.txt | 25 + .../get-app-path--error-wrong-scheme.txt | 13 + .../device/get-app-path--success.txt | 15 + .../device/install--error-invalid-app.txt | 10 + .../__fixtures__/device/install--success.txt | 7 + .../device/launch--error-invalid-bundle.txt | 10 + .../__fixtures__/device/launch--success.txt | 11 + .../__fixtures__/device/list--success.txt | 34 + .../device/stop--error-no-app.txt | 10 + .../__fixtures__/device/stop--success.txt | 7 + .../__fixtures__/device/test--failure.txt | 21 + .../__fixtures__/device/test--success.txt | 11 + .../macos/build--error-wrong-scheme.txt | 15 + .../__fixtures__/macos/build--success.txt | 15 + .../build-and-run--error-wrong-scheme.txt | 15 + .../macos/build-and-run--success.txt | 23 + .../get-app-path--error-wrong-scheme.txt | 13 + .../macos/get-app-path--success.txt | 14 + ...get-macos-bundle-id--error-missing-app.txt | 6 + .../macos/get-macos-bundle-id--success.txt | 11 + .../macos/launch--error-invalid-app.txt | 6 + .../__fixtures__/macos/launch--success.txt | 8 + .../__fixtures__/macos/stop--error-no-app.txt | 6 + .../__fixtures__/macos/stop--success.txt | 6 + .../macos/test--error-wrong-scheme.txt | 14 + .../__fixtures__/macos/test--failure.txt | 20 + .../__fixtures__/macos/test--success.txt | 10 + .../discover-projs--error-invalid-root.txt | 8 + .../discover-projs--success.txt | 17 + .../get-app-bundle-id--error-missing-app.txt | 6 + .../get-app-bundle-id--success.txt | 13 + ...get-macos-bundle-id--error-missing-app.txt | 6 + .../get-macos-bundle-id--success.txt | 11 + .../list-schemes--error-invalid-workspace.txt | 7 + .../list-schemes--success.txt | 16 + ...how-build-settings--error-wrong-scheme.txt | 8 + .../show-build-settings--success.txt | 617 ++++++++++++++++ .../scaffold-ios--error-existing.txt | 8 + .../scaffold-ios--success.txt | 14 + .../scaffold-macos--error-existing.txt | 8 + .../scaffold-macos--success.txt | 14 + .../resources/devices--success.txt | 29 + .../resources/doctor--success.txt | 125 ++++ .../resources/session-status--success.txt | 34 + .../resources/simulators--success.txt | 45 ++ .../session-clear-defaults--success.txt | 6 + .../session-set-defaults--success.txt | 24 + .../session-show-defaults--success.txt | 38 + .../session-sync-xcode-defaults--success.txt | 6 + .../session-use-defaults-profile--success.txt | 6 + .../boot--error-invalid-id.txt | 6 + .../simulator-management/boot--success.txt | 6 + .../erase--error-invalid-id.txt | 6 + .../simulator-management/erase--success.txt | 6 + .../simulator-management/list--success.txt | 120 ++++ .../simulator-management/open--success.txt | 7 + ...eset-location--error-invalid-simulator.txt | 6 + .../reset-location--success.txt | 6 + ...et-appearance--error-invalid-simulator.txt | 7 + .../set-appearance--success.txt | 7 + .../set-location--error-invalid-simulator.txt | 7 + .../set-location--success.txt | 7 + .../statusbar--error-invalid-simulator.txt | 7 + .../statusbar--success.txt | 7 + .../simulator/build--error-wrong-scheme.txt | 16 + .../__fixtures__/simulator/build--success.txt | 15 + .../build-and-run--error-wrong-scheme.txt | 16 + .../simulator/build-and-run--success.txt | 29 + .../get-app-path--error-wrong-scheme.txt | 14 + .../simulator/get-app-path--success.txt | 17 + .../simulator/install--error-invalid-app.txt | 12 + .../simulator/install--success.txt | 11 + .../launch-app--error-not-installed.txt | 7 + .../simulator/launch-app--success.txt | 14 + .../__fixtures__/simulator/list--success.txt | 52 ++ .../screenshot--error-invalid-simulator.txt | 6 + .../simulator/screenshot--success.txt | 9 + .../simulator/stop--error-no-app.txt | 12 + .../__fixtures__/simulator/stop--success.txt | 7 + .../simulator/test--error-wrong-scheme.txt | 15 + .../__fixtures__/simulator/test--failure.txt | 21 + .../__fixtures__/simulator/test--success.txt | 11 + .../swift-package/build--error-bad-path.txt | 11 + .../swift-package/build--success.txt | 7 + .../swift-package/clean--error-bad-path.txt | 6 + .../swift-package/clean--success.txt | 6 + .../swift-package/list--no-processes.txt | 4 + .../swift-package/list--success.txt | 12 + .../run--error-bad-executable.txt | 11 + .../swift-package/run--success.txt | 14 + .../swift-package/stop--error-no-process.txt | 6 + .../swift-package/test--error-bad-path.txt | 14 + .../swift-package/test--failure.txt | 21 + .../swift-package/test--success.txt | 10 + .../button--error-no-simulator.txt | 9 + .../ui-automation/button--success.txt | 6 + .../gesture--error-no-simulator.txt | 9 + .../ui-automation/gesture--success.txt | 6 + .../key-press--error-no-simulator.txt | 9 + .../ui-automation/key-press--success.txt | 6 + .../key-sequence--error-no-simulator.txt | 9 + .../ui-automation/key-sequence--success.txt | 6 + .../long-press--error-no-simulator.txt | 9 + .../ui-automation/long-press--success.txt | 8 + .../snapshot-ui--error-no-simulator.txt | 9 + .../ui-automation/snapshot-ui--success.txt | 588 +++++++++++++++ .../swipe--error-no-simulator.txt | 9 + .../ui-automation/swipe--success.txt | 8 + .../ui-automation/tap--error-no-simulator.txt | 9 + .../ui-automation/tap--success.txt | 8 + .../touch--error-no-simulator.txt | 9 + .../ui-automation/touch--success.txt | 8 + .../type-text--error-no-simulator.txt | 9 + .../ui-automation/type-text--success.txt | 6 + .../utilities/clean--error-wrong-scheme.txt | 9 + .../__fixtures__/utilities/clean--success.txt | 9 + .../__tests__/coverage.snapshot.test.ts | 107 +++ .../__tests__/debugging.snapshot.test.ts | 214 ++++++ .../__tests__/device.snapshot.test.ts | 206 ++++++ .../__tests__/macos.snapshot.test.ts | 222 ++++++ .../project-discovery.snapshot.test.ts | 150 ++++ .../project-scaffolding.snapshot.test.ts | 97 +++ .../__tests__/resources.snapshot.test.ts | 44 ++ .../session-management.snapshot.test.ts | 83 +++ .../simulator-management.snapshot.test.ts | 284 ++++++++ .../__tests__/simulator.snapshot.test.ts | 245 +++++++ .../__tests__/swift-package.snapshot.test.ts | 152 ++++ .../__tests__/ui-automation.snapshot.test.ts | 254 +++++++ .../__tests__/utilities.snapshot.test.ts | 39 + src/snapshot-tests/capture-debug-output.mjs | 51 ++ src/snapshot-tests/fixture-io.ts | 35 + src/snapshot-tests/flowdeck-fixture-io.ts | 16 + src/snapshot-tests/flowdeck-pty.py | 36 + src/snapshot-tests/harness.ts | 226 ++++++ src/snapshot-tests/normalize.ts | 189 +++++ src/snapshot-tests/resource-harness.ts | 73 ++ 182 files changed, 9037 insertions(+) create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-1.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-1.stdout.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-2.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-2.stdout.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-3.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-3.stdout.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/summary.json create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-1.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-1.stdout.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-2.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-2.stdout.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-3.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-3.stdout.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-22-25-469Z/flowdeck-run-1.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-22-25-469Z/flowdeck-run-1.stdout.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-22-25-469Z/summary.json create mode 100644 benchmarks/simulator-test/2026-03-17T14-22-25-469Z/xcodebuildmcp-run-1.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-22-25-469Z/xcodebuildmcp-run-1.stdout.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-57-22-646Z/flowdeck-run-1.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-57-22-646Z/flowdeck-run-1.stdout.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-57-22-646Z/summary.json create mode 100644 benchmarks/simulator-test/2026-03-17T14-57-22-646Z/xcodebuildmcp-run-1.stderr.txt create mode 100644 benchmarks/simulator-test/2026-03-17T14-57-22-646Z/xcodebuildmcp-run-1.stdout.txt create mode 100644 src/snapshot-tests/__fixtures__/coverage/get-coverage-report--error-invalid-bundle.txt create mode 100644 src/snapshot-tests/__fixtures__/coverage/get-coverage-report--success.txt create mode 100644 src/snapshot-tests/__fixtures__/coverage/get-file-coverage--error-invalid-bundle.txt create mode 100644 src/snapshot-tests/__fixtures__/coverage/get-file-coverage--success.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/add-breakpoint--error-no-session.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/add-breakpoint--success.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/attach--error-no-process.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/attach--success-continue.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/attach--success.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/continue--error-no-session.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/continue--success.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/detach--error-no-session.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/detach--success.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/lldb-command--error-no-session.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/lldb-command--success.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/remove-breakpoint--error-no-session.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/remove-breakpoint--success.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/stack--error-no-session.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/stack--success.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/variables--error-no-session.txt create mode 100644 src/snapshot-tests/__fixtures__/debugging/variables--success.txt create mode 100644 src/snapshot-tests/__fixtures__/device/build--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/device/build--success.txt create mode 100644 src/snapshot-tests/__fixtures__/device/build-and-run--success.txt create mode 100644 src/snapshot-tests/__fixtures__/device/get-app-path--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/device/get-app-path--success.txt create mode 100644 src/snapshot-tests/__fixtures__/device/install--error-invalid-app.txt create mode 100644 src/snapshot-tests/__fixtures__/device/install--success.txt create mode 100644 src/snapshot-tests/__fixtures__/device/launch--error-invalid-bundle.txt create mode 100644 src/snapshot-tests/__fixtures__/device/launch--success.txt create mode 100644 src/snapshot-tests/__fixtures__/device/list--success.txt create mode 100644 src/snapshot-tests/__fixtures__/device/stop--error-no-app.txt create mode 100644 src/snapshot-tests/__fixtures__/device/stop--success.txt create mode 100644 src/snapshot-tests/__fixtures__/device/test--failure.txt create mode 100644 src/snapshot-tests/__fixtures__/device/test--success.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/build--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/build--success.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/build-and-run--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/build-and-run--success.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/get-app-path--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/get-app-path--success.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/get-macos-bundle-id--error-missing-app.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/get-macos-bundle-id--success.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/launch--error-invalid-app.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/launch--success.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/stop--error-no-app.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/stop--success.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/test--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/test--failure.txt create mode 100644 src/snapshot-tests/__fixtures__/macos/test--success.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/discover-projs--error-invalid-root.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/discover-projs--success.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/get-app-bundle-id--error-missing-app.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/get-app-bundle-id--success.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/get-macos-bundle-id--error-missing-app.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/get-macos-bundle-id--success.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/list-schemes--error-invalid-workspace.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/list-schemes--success.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/show-build-settings--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/project-discovery/show-build-settings--success.txt create mode 100644 src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-ios--error-existing.txt create mode 100644 src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-ios--success.txt create mode 100644 src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-macos--error-existing.txt create mode 100644 src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-macos--success.txt create mode 100644 src/snapshot-tests/__fixtures__/resources/devices--success.txt create mode 100644 src/snapshot-tests/__fixtures__/resources/doctor--success.txt create mode 100644 src/snapshot-tests/__fixtures__/resources/session-status--success.txt create mode 100644 src/snapshot-tests/__fixtures__/resources/simulators--success.txt create mode 100644 src/snapshot-tests/__fixtures__/session-management/session-clear-defaults--success.txt create mode 100644 src/snapshot-tests/__fixtures__/session-management/session-set-defaults--success.txt create mode 100644 src/snapshot-tests/__fixtures__/session-management/session-show-defaults--success.txt create mode 100644 src/snapshot-tests/__fixtures__/session-management/session-sync-xcode-defaults--success.txt create mode 100644 src/snapshot-tests/__fixtures__/session-management/session-use-defaults-profile--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/boot--error-invalid-id.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/boot--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/erase--error-invalid-id.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/erase--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/list--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/open--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/reset-location--error-invalid-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/reset-location--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/set-appearance--error-invalid-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/set-appearance--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/set-location--error-invalid-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/set-location--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/statusbar--error-invalid-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator-management/statusbar--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/build--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/build--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/build-and-run--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/build-and-run--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/get-app-path--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/get-app-path--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/install--error-invalid-app.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/install--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/launch-app--error-not-installed.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/launch-app--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/list--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/screenshot--error-invalid-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/screenshot--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/stop--error-no-app.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/stop--success.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/test--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/test--failure.txt create mode 100644 src/snapshot-tests/__fixtures__/simulator/test--success.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/build--error-bad-path.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/build--success.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/clean--error-bad-path.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/clean--success.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/list--no-processes.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/list--success.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/run--error-bad-executable.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/run--success.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/stop--error-no-process.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/test--error-bad-path.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/test--failure.txt create mode 100644 src/snapshot-tests/__fixtures__/swift-package/test--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/button--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/button--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/gesture--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/gesture--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/key-press--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/key-press--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/key-sequence--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/key-sequence--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/long-press--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/long-press--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/snapshot-ui--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/snapshot-ui--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/swipe--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/swipe--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/tap--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/tap--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/touch--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/touch--success.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/type-text--error-no-simulator.txt create mode 100644 src/snapshot-tests/__fixtures__/ui-automation/type-text--success.txt create mode 100644 src/snapshot-tests/__fixtures__/utilities/clean--error-wrong-scheme.txt create mode 100644 src/snapshot-tests/__fixtures__/utilities/clean--success.txt create mode 100644 src/snapshot-tests/__tests__/coverage.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/debugging.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/device.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/macos.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/project-discovery.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/project-scaffolding.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/resources.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/session-management.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/simulator-management.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/simulator.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/swift-package.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/ui-automation.snapshot.test.ts create mode 100644 src/snapshot-tests/__tests__/utilities.snapshot.test.ts create mode 100644 src/snapshot-tests/capture-debug-output.mjs create mode 100644 src/snapshot-tests/fixture-io.ts create mode 100644 src/snapshot-tests/flowdeck-fixture-io.ts create mode 100644 src/snapshot-tests/flowdeck-pty.py create mode 100644 src/snapshot-tests/harness.ts create mode 100644 src/snapshot-tests/normalize.ts create mode 100644 src/snapshot-tests/resource-harness.ts diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-1.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-1.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-1.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-1.stdout.txt new file mode 100644 index 00000000..d865f0d2 --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-1.stdout.txt @@ -0,0 +1,51 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +๐Ÿงช Running tests (0, 0 failures) +๐Ÿงช Running tests (1, 0 failures) +๐Ÿงช Running tests (2, 0 failures) +๐Ÿงช Running tests (3, 0 failures) +๐Ÿงช Running tests (4, 0 failures) +๐Ÿงช Running tests (5, 0 failures) +๐Ÿงช Running tests (6, 0 failures) +๐Ÿงช Running tests (7, 0 failures)/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: -[CalculatorAppTests.CalculatorAppTests testCalculatorServiceFailure] : XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +๐Ÿงช Running tests (8, 1 failure) +๐Ÿงช Running tests (9, 1 failure) +๐Ÿงช Running tests (10, 1 failure) +๐Ÿงช Running tests (11, 1 failure) +๐Ÿงช Running tests (12, 1 failure) +๐Ÿงช Running tests (13, 1 failure) +๐Ÿงช Running tests (14, 1 failure) +๐Ÿงช Running tests (15, 1 failure) +๐Ÿงช Running tests (16, 1 failure) +๐Ÿงช Running tests (17, 1 failure) +๐Ÿงช Running tests (18, 1 failure) +๐Ÿงช Running tests (19, 1 failure) +๐Ÿงช Running tests (20, 1 failure) +๐Ÿงช Running tests (21, 1 failure) +Failed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.003s) +โ””โ”€ XCTAssertEqual failed: ("0") is not +equal to ("999") - This test should fail +- display should be 0, not 999 +(CalculatorAppTests.swift:52) +Test Summary +โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ +โ”‚ Total: 21 โ”‚ +โ”‚ Passed: 20 โ”‚ +โ”‚ Failed: 1 โ”‚ +โ”‚ Skipped: 0 โ”‚ +โ”‚ Duration: 27.96s โ”‚ +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ +โœ— 1 test(s) failed. \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-2.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-2.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-2.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-2.stdout.txt new file mode 100644 index 00000000..6b6e2197 --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-2.stdout.txt @@ -0,0 +1,51 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +๐Ÿงช Running tests (0, 0 failures) +๐Ÿงช Running tests (1, 0 failures) +๐Ÿงช Running tests (2, 0 failures) +๐Ÿงช Running tests (3, 0 failures) +๐Ÿงช Running tests (4, 0 failures) +๐Ÿงช Running tests (5, 0 failures) +๐Ÿงช Running tests (6, 0 failures) +๐Ÿงช Running tests (7, 0 failures)/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: -[CalculatorAppTests.CalculatorAppTests testCalculatorServiceFailure] : XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +๐Ÿงช Running tests (8, 1 failure) +๐Ÿงช Running tests (9, 1 failure) +๐Ÿงช Running tests (10, 1 failure) +๐Ÿงช Running tests (11, 1 failure) +๐Ÿงช Running tests (12, 1 failure) +๐Ÿงช Running tests (13, 1 failure) +๐Ÿงช Running tests (14, 1 failure) +๐Ÿงช Running tests (15, 1 failure) +๐Ÿงช Running tests (16, 1 failure) +๐Ÿงช Running tests (17, 1 failure) +๐Ÿงช Running tests (18, 1 failure) +๐Ÿงช Running tests (19, 1 failure) +๐Ÿงช Running tests (20, 1 failure) +๐Ÿงช Running tests (21, 1 failure) +Failed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.009s) +โ””โ”€ XCTAssertEqual failed: ("0") is not +equal to ("999") - This test should fail +- display should be 0, not 999 +(CalculatorAppTests.swift:52) +Test Summary +โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ +โ”‚ Total: 21 โ”‚ +โ”‚ Passed: 20 โ”‚ +โ”‚ Failed: 1 โ”‚ +โ”‚ Skipped: 0 โ”‚ +โ”‚ Duration: 20.31s โ”‚ +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ +โœ— 1 test(s) failed. \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-3.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-3.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-3.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-3.stdout.txt new file mode 100644 index 00000000..68c8fcf7 --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-3.stdout.txt @@ -0,0 +1,51 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +๐Ÿงช Running tests (0, 0 failures) +๐Ÿงช Running tests (1, 0 failures) +๐Ÿงช Running tests (2, 0 failures) +๐Ÿงช Running tests (3, 0 failures) +๐Ÿงช Running tests (4, 0 failures) +๐Ÿงช Running tests (5, 0 failures) +๐Ÿงช Running tests (6, 0 failures) +๐Ÿงช Running tests (7, 0 failures)/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: -[CalculatorAppTests.CalculatorAppTests testCalculatorServiceFailure] : XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +๐Ÿงช Running tests (8, 1 failure) +๐Ÿงช Running tests (9, 1 failure) +๐Ÿงช Running tests (10, 1 failure) +๐Ÿงช Running tests (11, 1 failure) +๐Ÿงช Running tests (12, 1 failure) +๐Ÿงช Running tests (13, 1 failure) +๐Ÿงช Running tests (14, 1 failure) +๐Ÿงช Running tests (15, 1 failure) +๐Ÿงช Running tests (16, 1 failure) +๐Ÿงช Running tests (17, 1 failure) +๐Ÿงช Running tests (18, 1 failure) +๐Ÿงช Running tests (19, 1 failure) +๐Ÿงช Running tests (20, 1 failure) +๐Ÿงช Running tests (21, 1 failure) +Failed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.009s) +โ””โ”€ XCTAssertEqual failed: ("0") is not +equal to ("999") - This test should fail +- display should be 0, not 999 +(CalculatorAppTests.swift:52) +Test Summary +โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ +โ”‚ Total: 21 โ”‚ +โ”‚ Passed: 20 โ”‚ +โ”‚ Failed: 1 โ”‚ +โ”‚ Skipped: 0 โ”‚ +โ”‚ Duration: 16.44s โ”‚ +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ +โœ— 1 test(s) failed. \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/summary.json b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/summary.json new file mode 100644 index 00000000..24c3a209 --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/summary.json @@ -0,0 +1,74 @@ +{ + "generatedAt": "2026-03-17T14:20:36.285Z", + "mode": "warm", + "iterations": 3, + "workspacePath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "results": [ + { + "tool": "xcodebuildmcp", + "iteration": 1, + "exitCode": 1, + "wallClockMs": 29067.379917000002, + "firstStdoutMs": 2.148291999999998, + "firstMilestoneMs": 2152.612708, + "startupToFirstStreamedTestProgressMs": 13020.933500000001, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-1.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-1.stderr.txt" + }, + { + "tool": "flowdeck", + "iteration": 1, + "exitCode": 1, + "wallClockMs": 28296.29575, + "firstStdoutMs": 3.5727919999990263, + "firstMilestoneMs": 12480.404625, + "startupToFirstStreamedTestProgressMs": 12480.409000000003, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-1.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-1.stderr.txt" + }, + { + "tool": "xcodebuildmcp", + "iteration": 2, + "exitCode": 1, + "wallClockMs": 20358.631999999998, + "firstStdoutMs": 3.855666999996174, + "firstMilestoneMs": 1894.4525829999984, + "startupToFirstStreamedTestProgressMs": 6474.262499999997, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-2.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-2.stderr.txt" + }, + { + "tool": "flowdeck", + "iteration": 2, + "exitCode": 1, + "wallClockMs": 20567.050875, + "firstStdoutMs": 3.934166000006371, + "firstMilestoneMs": 5885.525833000007, + "startupToFirstStreamedTestProgressMs": 5885.5267500000045, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-2.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-2.stderr.txt" + }, + { + "tool": "xcodebuildmcp", + "iteration": 3, + "exitCode": 1, + "wallClockMs": 21910.729708, + "firstStdoutMs": 3.3832499999989523, + "firstMilestoneMs": 2140.4143329999933, + "startupToFirstStreamedTestProgressMs": 6239.000874999998, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-3.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-3.stderr.txt" + }, + { + "tool": "flowdeck", + "iteration": 3, + "exitCode": 1, + "wallClockMs": 16693.48666699999, + "firstStdoutMs": 3.411791999998968, + "firstMilestoneMs": 5152.938666999995, + "startupToFirstStreamedTestProgressMs": 5152.9394579999935, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-3.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/flowdeck-run-3.stderr.txt" + } + ] +} \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-1.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-1.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-1.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-1.stdout.txt new file mode 100644 index 00000000..8a8d44cc --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-1.stdout.txt @@ -0,0 +1,669 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +[?25lโ”‚ +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling.. +.[?25h[?25lโ”‚ +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures +)[?25h/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +[?25lโ”‚ +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure).. +.[?25hFailed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.004 seconds) +โ””โ”€ XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 (/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52) +Test Summary +Total: 21 Passed: 20 Failed: 1 Skipped: 0 Duration: 27.98s \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-2.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-2.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-2.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-2.stdout.txt new file mode 100644 index 00000000..bdc1537c --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-2.stdout.txt @@ -0,0 +1,461 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +[?25lโ”‚ +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling +.[?25h[?25lโ”‚ +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures +)[?25h/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +[?25lโ”‚ +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure).. +.[?25hFailed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.004 seconds) +โ””โ”€ XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 (/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52) +Test Summary +Total: 21 Passed: 20 Failed: 1 Skipped: 0 Duration: 19.26s \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-3.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-3.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-3.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-3.stdout.txt new file mode 100644 index 00000000..3f4d5b30 --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-18-19-390Z/xcodebuildmcp-run-3.stdout.txt @@ -0,0 +1,495 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +[?25lโ”‚ +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling +.[?25h[?25lโ”‚ +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿงช +Runningtests(1,0failures)... +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures +)[?25h/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +[?25lโ”‚ +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure). +.[?25hFailed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.009 seconds) +โ””โ”€ XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 (/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52) +Test Summary +Total: 21 Passed: 20 Failed: 1 Skipped: 0 Duration: 20.84s \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/flowdeck-run-1.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/flowdeck-run-1.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/flowdeck-run-1.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/flowdeck-run-1.stdout.txt new file mode 100644 index 00000000..1fdd1bac --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/flowdeck-run-1.stdout.txt @@ -0,0 +1,51 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +๐Ÿงช Running tests (0, 0 failures) +๐Ÿงช Running tests (1, 0 failures) +๐Ÿงช Running tests (2, 0 failures) +๐Ÿงช Running tests (3, 0 failures) +๐Ÿงช Running tests (4, 0 failures) +๐Ÿงช Running tests (5, 0 failures) +๐Ÿงช Running tests (6, 0 failures) +๐Ÿงช Running tests (7, 0 failures)/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: -[CalculatorAppTests.CalculatorAppTests testCalculatorServiceFailure] : XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +๐Ÿงช Running tests (8, 1 failure) +๐Ÿงช Running tests (9, 1 failure) +๐Ÿงช Running tests (10, 1 failure) +๐Ÿงช Running tests (11, 1 failure) +๐Ÿงช Running tests (12, 1 failure) +๐Ÿงช Running tests (13, 1 failure) +๐Ÿงช Running tests (14, 1 failure) +๐Ÿงช Running tests (15, 1 failure) +๐Ÿงช Running tests (16, 1 failure) +๐Ÿงช Running tests (17, 1 failure) +๐Ÿงช Running tests (18, 1 failure) +๐Ÿงช Running tests (19, 1 failure) +๐Ÿงช Running tests (20, 1 failure) +๐Ÿงช Running tests (21, 1 failure) +Failed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.009s) +โ””โ”€ XCTAssertEqual failed: ("0") is not +equal to ("999") - This test should fail +- display should be 0, not 999 +(CalculatorAppTests.swift:52) +Test Summary +โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ +โ”‚ Total: 21 โ”‚ +โ”‚ Passed: 20 โ”‚ +โ”‚ Failed: 1 โ”‚ +โ”‚ Skipped: 0 โ”‚ +โ”‚ Duration: 27.52s โ”‚ +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ +โœ— 1 test(s) failed. \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/summary.json b/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/summary.json new file mode 100644 index 00000000..dfb3878e --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/summary.json @@ -0,0 +1,30 @@ +{ + "generatedAt": "2026-03-17T14:23:22.406Z", + "mode": "warm", + "iterations": 1, + "workspacePath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "results": [ + { + "tool": "xcodebuildmcp", + "iteration": 1, + "exitCode": 1, + "wallClockMs": 29005.319917, + "firstStdoutMs": 1.7743750000000063, + "firstMilestoneMs": 2082.7132079999997, + "startupToFirstStreamedTestProgressMs": 13278.247792, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/xcodebuildmcp-run-1.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/xcodebuildmcp-run-1.stderr.txt" + }, + { + "tool": "flowdeck", + "iteration": 1, + "exitCode": 1, + "wallClockMs": 27930.502958999998, + "firstStdoutMs": 3.876625000000786, + "firstMilestoneMs": 11681.301833999998, + "startupToFirstStreamedTestProgressMs": 11681.326125, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/flowdeck-run-1.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/flowdeck-run-1.stderr.txt" + } + ] +} \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/xcodebuildmcp-run-1.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/xcodebuildmcp-run-1.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/xcodebuildmcp-run-1.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/xcodebuildmcp-run-1.stdout.txt new file mode 100644 index 00000000..5f95bb32 --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-22-25-469Z/xcodebuildmcp-run-1.stdout.txt @@ -0,0 +1,669 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +[?25lโ”‚ +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling.. +.[?25h[?25lโ”‚ +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures +)[?25h/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +[?25lโ”‚ +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure). +.[?25hFailed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.004 seconds) +โ””โ”€ XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 (/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52) +Test Summary +Total: 21 Passed: 20 Failed: 1 Skipped: 0 Duration: 27.98s \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/flowdeck-run-1.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/flowdeck-run-1.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/flowdeck-run-1.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/flowdeck-run-1.stdout.txt new file mode 100644 index 00000000..affbd101 --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/flowdeck-run-1.stdout.txt @@ -0,0 +1,51 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +๐Ÿงช Running tests (0, 0 failures) +๐Ÿงช Running tests (1, 0 failures) +๐Ÿงช Running tests (2, 0 failures) +๐Ÿงช Running tests (3, 0 failures) +๐Ÿงช Running tests (4, 0 failures) +๐Ÿงช Running tests (5, 0 failures) +๐Ÿงช Running tests (6, 0 failures) +๐Ÿงช Running tests (7, 0 failures)/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: -[CalculatorAppTests.CalculatorAppTests testCalculatorServiceFailure] : XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +๐Ÿงช Running tests (8, 1 failure) +๐Ÿงช Running tests (9, 1 failure) +๐Ÿงช Running tests (10, 1 failure) +๐Ÿงช Running tests (11, 1 failure) +๐Ÿงช Running tests (12, 1 failure) +๐Ÿงช Running tests (13, 1 failure) +๐Ÿงช Running tests (14, 1 failure) +๐Ÿงช Running tests (15, 1 failure) +๐Ÿงช Running tests (16, 1 failure) +๐Ÿงช Running tests (17, 1 failure) +๐Ÿงช Running tests (18, 1 failure) +๐Ÿงช Running tests (19, 1 failure) +๐Ÿงช Running tests (20, 1 failure) +๐Ÿงช Running tests (21, 1 failure) +Failed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.003s) +โ””โ”€ XCTAssertEqual failed: ("0") is not +equal to ("999") - This test should fail +- display should be 0, not 999 +(CalculatorAppTests.swift:52) +Test Summary +โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ +โ”‚ Total: 21 โ”‚ +โ”‚ Passed: 20 โ”‚ +โ”‚ Failed: 1 โ”‚ +โ”‚ Skipped: 0 โ”‚ +โ”‚ Duration: 28.08s โ”‚ +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ +โœ— 1 test(s) failed. \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/summary.json b/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/summary.json new file mode 100644 index 00000000..a0fdb6b1 --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/summary.json @@ -0,0 +1,30 @@ +{ + "generatedAt": "2026-03-17T14:58:22.020Z", + "mode": "warm", + "iterations": 1, + "workspacePath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "results": [ + { + "tool": "xcodebuildmcp", + "iteration": 1, + "exitCode": 1, + "wallClockMs": 30882.488, + "firstStdoutMs": 2.211042000000006, + "firstMilestoneMs": 2160.745125, + "startupToFirstStreamedTestProgressMs": 14674.5665, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/xcodebuildmcp-run-1.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/xcodebuildmcp-run-1.stderr.txt" + }, + { + "tool": "flowdeck", + "iteration": 1, + "exitCode": 1, + "wallClockMs": 28490.114, + "firstStdoutMs": 5.035500000001775, + "firstMilestoneMs": 12153.824459000003, + "startupToFirstStreamedTestProgressMs": 12153.8315, + "stdoutPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/flowdeck-run-1.stdout.txt", + "stderrPath": "/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/flowdeck-run-1.stderr.txt" + } + ] +} \ No newline at end of file diff --git a/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/xcodebuildmcp-run-1.stderr.txt b/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/xcodebuildmcp-run-1.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/xcodebuildmcp-run-1.stdout.txt b/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/xcodebuildmcp-run-1.stdout.txt new file mode 100644 index 00000000..ff6d6262 --- /dev/null +++ b/benchmarks/simulator-test/2026-03-17T14-57-22-646Z/xcodebuildmcp-run-1.stdout.txt @@ -0,0 +1,635 @@ +^DUsing scheme test configuration: Debug +๐Ÿงช Test: CalculatorApp +Workspace: /Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorApp.xcworkspace +Configuration: Debug +Target: iPhone 17 Pro +๐Ÿงช Finding available tests... +Resolved to 21 test(s): +- CalculatorAppTests/CalculatorAppTests/testAppLaunch +- CalculatorAppTests/CalculatorAppTests/testCalculationPerformance +- CalculatorAppTests/CalculatorAppTests/testCalculatorOperationsEnum +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceBasicOperation +- CalculatorAppTests/CalculatorAppTests/testCalculatorServiceChainedOperations +... and 16 more +[?25lโ”‚ +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages.. +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages... +๐Ÿ“ฆ +Resolvingpackages +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling.. +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling... +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling +๐Ÿ› ๏ธ +Compiling. +๐Ÿ› ๏ธ +Compiling +.[?25h[?25lโ”‚ +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures) +๐Ÿงช +Runningtests(1,0failures +)[?25h/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52: error: XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 +[?25lโ”‚ +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(13,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure) +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure). +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure).. +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure)... +๐Ÿงช +Runningtests(21,1failure).. +.[?25hFailed Tests +CalculatorAppTests +โœ— testCalculatorServiceFailure (0.009 seconds) +โ””โ”€ XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 (/Users/cameroncooke/.codex/worktrees/43f4/XcodeBuildMCP/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52) +Test Summary +Total: 21 Passed: 20 Failed: 1 Skipped: 0 Duration: 29.76s \ No newline at end of file diff --git a/src/snapshot-tests/__fixtures__/coverage/get-coverage-report--error-invalid-bundle.txt b/src/snapshot-tests/__fixtures__/coverage/get-coverage-report--error-invalid-bundle.txt new file mode 100644 index 00000000..f1b738e6 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/coverage/get-coverage-report--error-invalid-bundle.txt @@ -0,0 +1,6 @@ + +๐Ÿ“Š Coverage Report + + xcresult: /invalid.xcresult + +โŒ Failed to get coverage report: Error: Error Domain=XCCovErrorDomain Code=0 "Failed to load result bundle" UserInfo={NSLocalizedDescription=Failed to load result bundle, NSUnderlyingError= {Error Domain=XCResultStorage.ResultBundleFactory.Error Code=0 "Failed to create a new result bundle reader, underlying error: Info.plist at /invalid.xcresult/Info.plist does not exist, the result bundle might be corrupted or the provided path is not a result bundle"}} diff --git a/src/snapshot-tests/__fixtures__/coverage/get-coverage-report--success.txt b/src/snapshot-tests/__fixtures__/coverage/get-coverage-report--success.txt new file mode 100644 index 00000000..fbfc9815 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/coverage/get-coverage-report--success.txt @@ -0,0 +1,13 @@ + +๐Ÿ“Š Coverage Report + + xcresult: /TestResults.xcresult + Target Filter: CalculatorAppTests + +โ„น๏ธ Overall: 94.9% (371/391 lines) + +Targets + CalculatorAppTests.xctest: 94.9% (371/391 lines) + +Next steps: +1. View file-level coverage: xcodebuildmcp coverage get-file-coverage --xcresult-path "/TestResults.xcresult" diff --git a/src/snapshot-tests/__fixtures__/coverage/get-file-coverage--error-invalid-bundle.txt b/src/snapshot-tests/__fixtures__/coverage/get-file-coverage--error-invalid-bundle.txt new file mode 100644 index 00000000..2d5def30 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/coverage/get-file-coverage--error-invalid-bundle.txt @@ -0,0 +1,7 @@ + +๐Ÿ“Š File Coverage + + xcresult: /invalid.xcresult + File: SomeFile.swift + +โŒ Failed to get file coverage: Error: Error Domain=XCCovErrorDomain Code=0 "Failed to load result bundle" UserInfo={NSLocalizedDescription=Failed to load result bundle, NSUnderlyingError= {Error Domain=XCResultStorage.ResultBundleFactory.Error Code=0 "Failed to create a new result bundle reader, underlying error: Info.plist at /invalid.xcresult/Info.plist does not exist, the result bundle might be corrupted or the provided path is not a result bundle"}} diff --git a/src/snapshot-tests/__fixtures__/coverage/get-file-coverage--success.txt b/src/snapshot-tests/__fixtures__/coverage/get-file-coverage--success.txt new file mode 100644 index 00000000..18f185fc --- /dev/null +++ b/src/snapshot-tests/__fixtures__/coverage/get-file-coverage--success.txt @@ -0,0 +1,29 @@ + +๐Ÿ“Š File Coverage + + xcresult: /TestResults.xcresult + File: CalculatorService.swift + +File: example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorService.swift + +โ„น๏ธ Coverage: 83.1% (157/189 lines) + +๐Ÿ”ด Not Covered (7 functions, 22 lines) + L159 CalculatorService.deleteLastDigit() -- 0/16 lines + L58 implicit closure #2 in CalculatorService.inputNumber(_:) -- 0/1 lines + L98 implicit closure #3 in CalculatorService.calculate() -- 0/1 lines + L99 implicit closure #4 in CalculatorService.calculate() -- 0/1 lines + L162 implicit closure #1 in CalculatorService.deleteLastDigit() -- 0/1 lines + L172 implicit closure #2 in CalculatorService.deleteLastDigit() -- 0/1 lines + L214 implicit closure #4 in CalculatorService.formatNumber(_:) -- 0/1 lines + +๐ŸŸก Partial Coverage (4 functions) + L184 CalculatorService.updateExpressionDisplay() -- 80.0% (8/10 lines) + L195 CalculatorService.formatNumber(_:) -- 85.7% (18/21 lines) + L93 CalculatorService.calculate() -- 89.5% (34/38 lines) + L63 CalculatorService.inputDecimal() -- 92.9% (13/14 lines) + +๐ŸŸข Full Coverage (28 functions) -- all at 100% + +Next steps: +1. View overall coverage: xcodebuildmcp coverage get-coverage-report --xcresult-path "/TestResults.xcresult" diff --git a/src/snapshot-tests/__fixtures__/debugging/add-breakpoint--error-no-session.txt b/src/snapshot-tests/__fixtures__/debugging/add-breakpoint--error-no-session.txt new file mode 100644 index 00000000..1495a4c5 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/add-breakpoint--error-no-session.txt @@ -0,0 +1,4 @@ + +๐Ÿ› Add Breakpoint + +โŒ Failed to add breakpoint: No active debug session. Provide debugSessionId or attach first. diff --git a/src/snapshot-tests/__fixtures__/debugging/add-breakpoint--success.txt b/src/snapshot-tests/__fixtures__/debugging/add-breakpoint--success.txt new file mode 100644 index 00000000..771bfb62 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/add-breakpoint--success.txt @@ -0,0 +1,7 @@ + +๐Ÿ› Add Breakpoint + +โœ… Breakpoint 1 set + +Output: + Set breakpoint 1 at ContentView.swift:42 diff --git a/src/snapshot-tests/__fixtures__/debugging/attach--error-no-process.txt b/src/snapshot-tests/__fixtures__/debugging/attach--error-no-process.txt new file mode 100644 index 00000000..06fc6b03 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/attach--error-no-process.txt @@ -0,0 +1,4 @@ + +๐Ÿ› Attach Debugger + +โŒ Failed to resolve simulator PID: Invalid device: diff --git a/src/snapshot-tests/__fixtures__/debugging/attach--success-continue.txt b/src/snapshot-tests/__fixtures__/debugging/attach--success-continue.txt new file mode 100644 index 00000000..6b1304e2 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/attach--success-continue.txt @@ -0,0 +1,12 @@ + +๐Ÿ› Attach Debugger + +โœ… Attached DAP debugger to simulator process () + โ”œ Debug session ID: + โ”œ Status: This session is now the current debug session. + โ”” Execution: Execution is running. App is responsive to UI interaction. + +Next steps: +1. Add a breakpoint: debug_breakpoint_add({ debugSessionId: "", file: "...", line: 123 }) +2. Continue execution: debug_continue({ debugSessionId: "" }) +3. Show call stack: debug_stack({ debugSessionId: "" }) diff --git a/src/snapshot-tests/__fixtures__/debugging/attach--success.txt b/src/snapshot-tests/__fixtures__/debugging/attach--success.txt new file mode 100644 index 00000000..4ddf7a58 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/attach--success.txt @@ -0,0 +1,12 @@ + +๐Ÿ› Attach Debugger + +โœ… Attached DAP debugger to simulator process () + โ”œ Debug session ID: + โ”œ Status: This session is now the current debug session. + โ”” Execution: Execution is paused. Use debug_continue to resume before UI automation. + +Next steps: +1. Add a breakpoint: debug_breakpoint_add({ debugSessionId: "", file: "...", line: 123 }) +2. Continue execution: debug_continue({ debugSessionId: "" }) +3. Show call stack: debug_stack({ debugSessionId: "" }) diff --git a/src/snapshot-tests/__fixtures__/debugging/continue--error-no-session.txt b/src/snapshot-tests/__fixtures__/debugging/continue--error-no-session.txt new file mode 100644 index 00000000..b3d0975a --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/continue--error-no-session.txt @@ -0,0 +1,4 @@ + +๐Ÿ› Continue + +โŒ Failed to resume debugger: No active debug session. Provide debugSessionId or attach first. diff --git a/src/snapshot-tests/__fixtures__/debugging/continue--success.txt b/src/snapshot-tests/__fixtures__/debugging/continue--success.txt new file mode 100644 index 00000000..bb44582d --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/continue--success.txt @@ -0,0 +1,4 @@ + +๐Ÿ› Continue + +โœ… Resumed debugger session diff --git a/src/snapshot-tests/__fixtures__/debugging/detach--error-no-session.txt b/src/snapshot-tests/__fixtures__/debugging/detach--error-no-session.txt new file mode 100644 index 00000000..2b4192bf --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/detach--error-no-session.txt @@ -0,0 +1,4 @@ + +๐Ÿ› Detach + +โŒ Failed to detach debugger: No active debug session. Provide debugSessionId or attach first. diff --git a/src/snapshot-tests/__fixtures__/debugging/detach--success.txt b/src/snapshot-tests/__fixtures__/debugging/detach--success.txt new file mode 100644 index 00000000..89a010f5 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/detach--success.txt @@ -0,0 +1,4 @@ + +๐Ÿ› Detach + +โœ… Detached debugger session diff --git a/src/snapshot-tests/__fixtures__/debugging/lldb-command--error-no-session.txt b/src/snapshot-tests/__fixtures__/debugging/lldb-command--error-no-session.txt new file mode 100644 index 00000000..74ba88dc --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/lldb-command--error-no-session.txt @@ -0,0 +1,6 @@ + +๐Ÿ› LLDB Command + + Command: bt + +โŒ Failed to run LLDB command: No active debug session. Provide debugSessionId or attach first. diff --git a/src/snapshot-tests/__fixtures__/debugging/lldb-command--success.txt b/src/snapshot-tests/__fixtures__/debugging/lldb-command--success.txt new file mode 100644 index 00000000..8a360697 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/lldb-command--success.txt @@ -0,0 +1,12 @@ + +๐Ÿ› LLDB Command + + Command: breakpoint list + +โœ… Command executed + +Output: + Current breakpoints: + 1: file = 'ContentView.swift', line = 42, exact_match = 0, locations = + Names: + dap diff --git a/src/snapshot-tests/__fixtures__/debugging/remove-breakpoint--error-no-session.txt b/src/snapshot-tests/__fixtures__/debugging/remove-breakpoint--error-no-session.txt new file mode 100644 index 00000000..83bd0130 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/remove-breakpoint--error-no-session.txt @@ -0,0 +1,4 @@ + +๐Ÿ› Remove Breakpoint + +โŒ Failed to remove breakpoint: No active debug session. Provide debugSessionId or attach first. diff --git a/src/snapshot-tests/__fixtures__/debugging/remove-breakpoint--success.txt b/src/snapshot-tests/__fixtures__/debugging/remove-breakpoint--success.txt new file mode 100644 index 00000000..4714ab85 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/remove-breakpoint--success.txt @@ -0,0 +1,7 @@ + +๐Ÿ› Remove Breakpoint + +โœ… Breakpoint 1 removed + +Output: + Removed breakpoint 1. diff --git a/src/snapshot-tests/__fixtures__/debugging/stack--error-no-session.txt b/src/snapshot-tests/__fixtures__/debugging/stack--error-no-session.txt new file mode 100644 index 00000000..72172a93 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/stack--error-no-session.txt @@ -0,0 +1,4 @@ + +๐Ÿ› Stack Trace + +โŒ Failed to get stack: No active debug session. Provide debugSessionId or attach first. diff --git a/src/snapshot-tests/__fixtures__/debugging/stack--success.txt b/src/snapshot-tests/__fixtures__/debugging/stack--success.txt new file mode 100644 index 00000000..37cc8867 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/stack--success.txt @@ -0,0 +1,11 @@ + +๐Ÿ› Stack Trace + +โœ… Stack trace retrieved + +Frames: + Thread (Thread 1) + + frame #: static CalculatorApp.$main() at /Library/Developer/CoreSimulator/Devices//data/Containers/Bundle/Application//CalculatorApp.app/CalculatorApp.debug.dylib`static CalculatorApp.CalculatorApp.$main() -> (): + frame #: main at /Library/Developer/CoreSimulator/Devices//data/Containers/Bundle/Application//CalculatorApp.app/CalculatorApp.debug.dylib`main: + diff --git a/src/snapshot-tests/__fixtures__/debugging/variables--error-no-session.txt b/src/snapshot-tests/__fixtures__/debugging/variables--error-no-session.txt new file mode 100644 index 00000000..e76aa900 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/variables--error-no-session.txt @@ -0,0 +1,4 @@ + +๐Ÿ› Variables + +โŒ Failed to get variables: No active debug session. Provide debugSessionId or attach first. diff --git a/src/snapshot-tests/__fixtures__/debugging/variables--success.txt b/src/snapshot-tests/__fixtures__/debugging/variables--success.txt new file mode 100644 index 00000000..bf96d0fd --- /dev/null +++ b/src/snapshot-tests/__fixtures__/debugging/variables--success.txt @@ -0,0 +1,18 @@ + +๐Ÿ› Variables + +โœ… Variables retrieved + +Values: + Locals: + (no variables) + + Globals: + (no variables) + + Registers: + General Purpose Registers () = + Floating Point Registers () = + Exception State Registers () = + Scalable Vector Extension Registers () = + Scalable Matrix Extension Registers () = diff --git a/src/snapshot-tests/__fixtures__/device/build--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/device/build--error-wrong-scheme.txt new file mode 100644 index 00000000..20da1b1c --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/build--error-wrong-scheme.txt @@ -0,0 +1,15 @@ + +๐Ÿ”จ Build + + Scheme: NONEXISTENT + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +Errors (1): + + โœ— The workspace named "CalculatorApp" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the workspace. + +โŒ Build failed. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_device__pid.log diff --git a/src/snapshot-tests/__fixtures__/device/build--success.txt b/src/snapshot-tests/__fixtures__/device/build--success.txt new file mode 100644 index 00000000..27282c0a --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/build--success.txt @@ -0,0 +1,14 @@ + +๐Ÿ”จ Build + + Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โœ… Build succeeded. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_device__pid.log + +Next steps: +1. Get built device app path: xcodebuildmcp device get-app-path --scheme "CalculatorApp" diff --git a/src/snapshot-tests/__fixtures__/device/build-and-run--success.txt b/src/snapshot-tests/__fixtures__/device/build-and-run--success.txt new file mode 100644 index 00000000..5596f05f --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/build-and-run--success.txt @@ -0,0 +1,25 @@ + +๐Ÿš€ Build & Run + + Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS + Device: () + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โ„น๏ธ Resolving app path +โœ… Resolving app path +โ„น๏ธ Installing app +โœ… Installing app +โ„น๏ธ Launching app + +โœ… Build succeeded. (โฑ๏ธ ) +โœ… Build & Run complete + โ”œ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app + โ”œ Bundle ID: io.sentry.calculatorapp + โ”œ Process ID: + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_device__pid.log + +Next steps: +1. Stop app on device: xcodebuildmcp device stop --device-id "" --process-id "" diff --git a/src/snapshot-tests/__fixtures__/device/get-app-path--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/device/get-app-path--error-wrong-scheme.txt new file mode 100644 index 00000000..6817789b --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/get-app-path--error-wrong-scheme.txt @@ -0,0 +1,13 @@ + +๐Ÿ” Get App Path + + Scheme: NONEXISTENT + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS + +Errors (1): + + โœ— The workspace named "CalculatorApp" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the workspace. + +โŒ Query failed. diff --git a/src/snapshot-tests/__fixtures__/device/get-app-path--success.txt b/src/snapshot-tests/__fixtures__/device/get-app-path--success.txt new file mode 100644 index 00000000..ec3e9c0b --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/get-app-path--success.txt @@ -0,0 +1,15 @@ + +๐Ÿ” Get App Path + + Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS + +โœ… Success + โ”” App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app + +Next steps: +1. Get bundle ID: xcodebuildmcp device get-app-bundle-id --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app" +2. Install app on device: xcodebuildmcp device install --device-id "DEVICE_UDID" --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app" +3. Launch app on device: xcodebuildmcp device launch --device-id "DEVICE_UDID" --bundle-id "BUNDLE_ID" diff --git a/src/snapshot-tests/__fixtures__/device/install--error-invalid-app.txt b/src/snapshot-tests/__fixtures__/device/install--error-invalid-app.txt new file mode 100644 index 00000000..53e5b6d8 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/install--error-invalid-app.txt @@ -0,0 +1,10 @@ + +๐Ÿ“ฆ Install App + + Device: + App: /tmp/nonexistent.app + +โŒ Failed to install app: Failed to load provisioning paramter list due to error: Error Domain=com.apple.dt.CoreDeviceError Code=1002 "No provider was found." UserInfo={NSLocalizedDescription=No provider was found.}. +`devicectl manage create` may support a reduced set of arguments. +ERROR: The specified device was not found. (Name: ) (com.apple.dt.CoreDeviceError error 1000 (0x3E8)) + DeviceName = diff --git a/src/snapshot-tests/__fixtures__/device/install--success.txt b/src/snapshot-tests/__fixtures__/device/install--success.txt new file mode 100644 index 00000000..c500efa9 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/install--success.txt @@ -0,0 +1,7 @@ + +๐Ÿ“ฆ Install App + + Device: () + App: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app + +โœ… App installed successfully. diff --git a/src/snapshot-tests/__fixtures__/device/launch--error-invalid-bundle.txt b/src/snapshot-tests/__fixtures__/device/launch--error-invalid-bundle.txt new file mode 100644 index 00000000..9ffa4ce5 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/launch--error-invalid-bundle.txt @@ -0,0 +1,10 @@ + +๐Ÿš€ Launch App + + Device: + Bundle ID: com.nonexistent.app + +โŒ Failed to launch app: Failed to load provisioning paramter list due to error: Error Domain=com.apple.dt.CoreDeviceError Code=1002 "No provider was found." UserInfo={NSLocalizedDescription=No provider was found.}. +`devicectl manage create` may support a reduced set of arguments. +ERROR: The specified device was not found. (Name: ) (com.apple.dt.CoreDeviceError error 1000 (0x3E8)) + DeviceName = diff --git a/src/snapshot-tests/__fixtures__/device/launch--success.txt b/src/snapshot-tests/__fixtures__/device/launch--success.txt new file mode 100644 index 00000000..a5f7ff46 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/launch--success.txt @@ -0,0 +1,11 @@ + +๐Ÿš€ Launch App + + Device: () + Bundle ID: io.sentry.calculatorapp + +โœ… App launched successfully. + โ”” Process ID: + +Next steps: +1. Stop the app: xcodebuildmcp device stop --device-id "" --process-id "" diff --git a/src/snapshot-tests/__fixtures__/device/list--success.txt b/src/snapshot-tests/__fixtures__/device/list--success.txt new file mode 100644 index 00000000..3c710681 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/list--success.txt @@ -0,0 +1,34 @@ + +๐Ÿ“ฑ List Devices + +iOS Devices: + + ๐Ÿ“ฑ [โœ“] Cameronโ€™s iPhone 16 Pro Max + OS: 26.3.1 (a) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone + OS: 26.1 + UDID: + +watchOS Devices: + + โŒš๏ธ [โœ—] Cameronโ€™s Appleย Watch + OS: 10.6.1 + UDID: + + โŒš๏ธ [โœ“] Cameronโ€™s Appleย Watch + OS: 26.3 + UDID: + +โœ… 4 physical devices discovered (2 iOS, 2 watchOS). + +Hints + Use the device ID/UDID from above when required by other tools. + Save a default device with session-set-defaults { deviceId: 'DEVICE_UDID' }. + Before running build/run/test/UI automation tools, set the desired device identifier in session defaults. + +Next steps: +1. Build for device: xcodebuildmcp device build +2. Run tests on device: xcodebuildmcp device test +3. Get app path: xcodebuildmcp device get-app-path diff --git a/src/snapshot-tests/__fixtures__/device/stop--error-no-app.txt b/src/snapshot-tests/__fixtures__/device/stop--error-no-app.txt new file mode 100644 index 00000000..76a7f793 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/stop--error-no-app.txt @@ -0,0 +1,10 @@ + +๐Ÿ›‘ Stop App + + Device: + PID: + +โŒ Failed to stop app: Failed to load provisioning paramter list due to error: Error Domain=com.apple.dt.CoreDeviceError Code=1002 "No provider was found." UserInfo={NSLocalizedDescription=No provider was found.}. +`devicectl manage create` may support a reduced set of arguments. +ERROR: The specified device was not found. (Name: ) (com.apple.dt.CoreDeviceError error 1000 (0x3E8)) + DeviceName = diff --git a/src/snapshot-tests/__fixtures__/device/stop--success.txt b/src/snapshot-tests/__fixtures__/device/stop--success.txt new file mode 100644 index 00000000..2fa57755 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/stop--success.txt @@ -0,0 +1,7 @@ + +๐Ÿ›‘ Stop App + + Device: () + PID: + +โœ… App stopped successfully diff --git a/src/snapshot-tests/__fixtures__/device/test--failure.txt b/src/snapshot-tests/__fixtures__/device/test--failure.txt new file mode 100644 index 00000000..ff1e90f3 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/test--failure.txt @@ -0,0 +1,21 @@ + +๐Ÿงช Test + + Scheme: CalculatorApp + Configuration: Debug + Platform: iOS + Device: () + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +CalculatorAppTests + โœ— testCalculatorServiceFailure: + - XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 + example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52 + +IntentionalFailureTests + โœ— test: + - XCTAssertTrue failed - This test should fail to verify error reporting + example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:286 + +โŒ 2 tests failed, 21 passed, 0 skipped (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/test_device__pid.log diff --git a/src/snapshot-tests/__fixtures__/device/test--success.txt b/src/snapshot-tests/__fixtures__/device/test--success.txt new file mode 100644 index 00000000..6e3662c9 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/device/test--success.txt @@ -0,0 +1,11 @@ + +๐Ÿงช Test + + Scheme: CalculatorApp + Configuration: Debug + Platform: iOS + Device: () + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โœ… 1 test passed, 0 skipped (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/test_device__pid.log diff --git a/src/snapshot-tests/__fixtures__/macos/build--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/macos/build--error-wrong-scheme.txt new file mode 100644 index 00000000..b07b3c73 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/build--error-wrong-scheme.txt @@ -0,0 +1,15 @@ + +๐Ÿ”จ Build + + Scheme: NONEXISTENT + Project: example_projects/macOS/MCPTest.xcodeproj + Configuration: Debug + Platform: macOS + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +Errors (1): + + โœ— The project named "MCPTest" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the project. + +โŒ Build failed. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_macos__pid.log diff --git a/src/snapshot-tests/__fixtures__/macos/build--success.txt b/src/snapshot-tests/__fixtures__/macos/build--success.txt new file mode 100644 index 00000000..c8d6655a --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/build--success.txt @@ -0,0 +1,15 @@ + +๐Ÿ”จ Build + + Scheme: MCPTest + Project: example_projects/macOS/MCPTest.xcodeproj + Configuration: Debug + Platform: macOS + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โœ… Build succeeded. (โฑ๏ธ ) + โ”œ Bundle ID: io.sentry.calculatorapp + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_macos__pid.log + +Next steps: +1. Get built macOS app path: xcodebuildmcp macos get-app-path --scheme "MCPTest" diff --git a/src/snapshot-tests/__fixtures__/macos/build-and-run--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/macos/build-and-run--error-wrong-scheme.txt new file mode 100644 index 00000000..a9e244cf --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/build-and-run--error-wrong-scheme.txt @@ -0,0 +1,15 @@ + +๐Ÿš€ Build & Run + + Scheme: NONEXISTENT + Project: example_projects/macOS/MCPTest.xcodeproj + Configuration: Debug + Platform: macOS + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +Errors (1): + + โœ— The project named "MCPTest" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the project. + +โŒ Build failed. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_macos__pid.log diff --git a/src/snapshot-tests/__fixtures__/macos/build-and-run--success.txt b/src/snapshot-tests/__fixtures__/macos/build-and-run--success.txt new file mode 100644 index 00000000..1a3fd1fe --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/build-and-run--success.txt @@ -0,0 +1,23 @@ + +๐Ÿš€ Build & Run + + Scheme: MCPTest + Project: example_projects/macOS/MCPTest.xcodeproj + Configuration: Debug + Platform: macOS + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โ„น๏ธ Resolving app path +โœ… Resolving app path +โ„น๏ธ Launching app +โœ… Launching app + +โœ… Build succeeded. (โฑ๏ธ ) +โœ… Build & Run complete + โ”œ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app + โ”œ Bundle ID: io.sentry.calculatorapp + โ”œ Process ID: + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_macos__pid.log + +Next steps: +1. Interact with the launched app in the foreground diff --git a/src/snapshot-tests/__fixtures__/macos/get-app-path--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/macos/get-app-path--error-wrong-scheme.txt new file mode 100644 index 00000000..0661e112 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/get-app-path--error-wrong-scheme.txt @@ -0,0 +1,13 @@ + +๐Ÿ” Get App Path + + Scheme: NONEXISTENT + Project: example_projects/macOS/MCPTest.xcodeproj + Configuration: Debug + Platform: macOS + +Errors (1): + + โœ— The project named "MCPTest" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the project. + +โŒ Query failed. diff --git a/src/snapshot-tests/__fixtures__/macos/get-app-path--success.txt b/src/snapshot-tests/__fixtures__/macos/get-app-path--success.txt new file mode 100644 index 00000000..1ab2fb05 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/get-app-path--success.txt @@ -0,0 +1,14 @@ + +๐Ÿ” Get App Path + + Scheme: MCPTest + Project: example_projects/macOS/MCPTest.xcodeproj + Configuration: Debug + Platform: macOS + +โœ… Success + โ”” App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app + +Next steps: +1. Get bundle ID: xcodebuildmcp macos get-macos-bundle-id --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app" +2. Launch app: xcodebuildmcp macos launch --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app" diff --git a/src/snapshot-tests/__fixtures__/macos/get-macos-bundle-id--error-missing-app.txt b/src/snapshot-tests/__fixtures__/macos/get-macos-bundle-id--error-missing-app.txt new file mode 100644 index 00000000..8448129e --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/get-macos-bundle-id--error-missing-app.txt @@ -0,0 +1,6 @@ + +๐Ÿ” Get macOS Bundle ID + + App: /nonexistent/path/Fake.app + +โŒ File not found: '/nonexistent/path/Fake.app'. Please check the path and try again. diff --git a/src/snapshot-tests/__fixtures__/macos/get-macos-bundle-id--success.txt b/src/snapshot-tests/__fixtures__/macos/get-macos-bundle-id--success.txt new file mode 100644 index 00000000..e1c8112e --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/get-macos-bundle-id--success.txt @@ -0,0 +1,11 @@ + +๐Ÿ” Get macOS Bundle ID + + App: /BundleTest.app + +โœ… Bundle ID + โ”” com.test.snapshot-macos + +Next steps: +1. Launch the app: xcodebuildmcp macos launch --app-path "/BundleTest.app" +2. Build again: xcodebuildmcp macos build --scheme "SCHEME_NAME" diff --git a/src/snapshot-tests/__fixtures__/macos/launch--error-invalid-app.txt b/src/snapshot-tests/__fixtures__/macos/launch--error-invalid-app.txt new file mode 100644 index 00000000..352508e4 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/launch--error-invalid-app.txt @@ -0,0 +1,6 @@ + +๐Ÿš€ Launch macOS App + + App: /NonExistent.app + +โŒ File not found: '/NonExistent.app'. Please check the path and try again. diff --git a/src/snapshot-tests/__fixtures__/macos/launch--success.txt b/src/snapshot-tests/__fixtures__/macos/launch--success.txt new file mode 100644 index 00000000..a7e59eee --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/launch--success.txt @@ -0,0 +1,8 @@ + +๐Ÿš€ Launch macOS App + + App: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app + +โœ… App launched successfully + โ”œ Bundle ID: io.sentry.calculatorapp + โ”” Process ID: diff --git a/src/snapshot-tests/__fixtures__/macos/stop--error-no-app.txt b/src/snapshot-tests/__fixtures__/macos/stop--error-no-app.txt new file mode 100644 index 00000000..f5380129 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/stop--error-no-app.txt @@ -0,0 +1,6 @@ + +๐Ÿ›‘ Stop macOS App + + App: PID 999999 + +โŒ Stop macOS app operation failed: kill: 999999: No such process diff --git a/src/snapshot-tests/__fixtures__/macos/stop--success.txt b/src/snapshot-tests/__fixtures__/macos/stop--success.txt new file mode 100644 index 00000000..dffe5e4e --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/stop--success.txt @@ -0,0 +1,6 @@ + +๐Ÿ›‘ Stop macOS App + + App: MCPTest + +โœ… App stopped successfully diff --git a/src/snapshot-tests/__fixtures__/macos/test--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/macos/test--error-wrong-scheme.txt new file mode 100644 index 00000000..94fa73ba --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/test--error-wrong-scheme.txt @@ -0,0 +1,14 @@ + +๐Ÿงช Test + + Scheme: NONEXISTENT + Configuration: Debug + Platform: macOS + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +Errors (1): + + โœ— The project named "MCPTest" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the project. + +โŒ Test failed. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/test_macos__pid.log diff --git a/src/snapshot-tests/__fixtures__/macos/test--failure.txt b/src/snapshot-tests/__fixtures__/macos/test--failure.txt new file mode 100644 index 00000000..c6fa1a4b --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/test--failure.txt @@ -0,0 +1,20 @@ + +๐Ÿงช Test + + Scheme: MCPTest + Configuration: Debug + Platform: macOS + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +MCPTestsXCTests + โœ— testDeliberateFailure(): + - XCTAssertTrue failed - This test is designed to fail for snapshot testing + MCPTestsXCTests.swift:11 + +MCPTestTests + โœ— deliberateFailure(): + - Expectation failed: 1 == 2: This test is designed to fail for snapshot testing + MCPTestTests.swift:11 + +โŒ 2 tests failed, 2 passed, 0 skipped (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/test_macos__pid.log diff --git a/src/snapshot-tests/__fixtures__/macos/test--success.txt b/src/snapshot-tests/__fixtures__/macos/test--success.txt new file mode 100644 index 00000000..50a4db50 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/macos/test--success.txt @@ -0,0 +1,10 @@ + +๐Ÿงช Test + + Scheme: MCPTest + Configuration: Debug + Platform: macOS + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โœ… 2 tests passed, 0 skipped (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/test_macos__pid.log diff --git a/src/snapshot-tests/__fixtures__/project-discovery/discover-projs--error-invalid-root.txt b/src/snapshot-tests/__fixtures__/project-discovery/discover-projs--error-invalid-root.txt new file mode 100644 index 00000000..b8c28324 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/discover-projs--error-invalid-root.txt @@ -0,0 +1,8 @@ + +๐Ÿ” Discover Projects + + Workspace root: /nonexistent/path/Fake.app + Scan path: /nonexistent/path + Max depth: 3 + +โŒ Failed to access scan path: /nonexistent/path. Error: ENOENT: no such file or directory, stat '/nonexistent/path' diff --git a/src/snapshot-tests/__fixtures__/project-discovery/discover-projs--success.txt b/src/snapshot-tests/__fixtures__/project-discovery/discover-projs--success.txt new file mode 100644 index 00000000..97a4fcda --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/discover-projs--success.txt @@ -0,0 +1,17 @@ + +๐Ÿ” Discover Projects + + Workspace root: + Scan path: + Max depth: 3 + +โœ… Found 1 project and 1 workspace + +Projects: + example_projects/iOS_Calculator/CalculatorApp.xcodeproj + +Workspaces: + example_projects/iOS_Calculator/CalculatorApp.xcworkspace + +Next steps: +1. Build and run once defaults are set: xcodebuildmcp simulator build-and-run diff --git a/src/snapshot-tests/__fixtures__/project-discovery/get-app-bundle-id--error-missing-app.txt b/src/snapshot-tests/__fixtures__/project-discovery/get-app-bundle-id--error-missing-app.txt new file mode 100644 index 00000000..8eb9031a --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/get-app-bundle-id--error-missing-app.txt @@ -0,0 +1,6 @@ + +๐Ÿ” Get Bundle ID + + App: /nonexistent/path/Fake.app + +โŒ File not found: '/nonexistent/path/Fake.app'. Please check the path and try again. diff --git a/src/snapshot-tests/__fixtures__/project-discovery/get-app-bundle-id--success.txt b/src/snapshot-tests/__fixtures__/project-discovery/get-app-bundle-id--success.txt new file mode 100644 index 00000000..f090f082 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/get-app-bundle-id--success.txt @@ -0,0 +1,13 @@ + +๐Ÿ” Get Bundle ID + + App: /BundleTest.app + +โœ… Bundle ID + โ”” com.test.snapshot + +Next steps: +1. Install on simulator: xcodebuildmcp simulator install --simulator-id "SIMULATOR_UUID" --app-path "/BundleTest.app" +2. Launch on simulator: xcodebuildmcp simulator launch-app --simulator-id "SIMULATOR_UUID" --bundle-id "com.test.snapshot" +3. Install on device: xcodebuildmcp device install --device-id "DEVICE_UDID" --app-path "/BundleTest.app" +4. Launch on device: xcodebuildmcp device launch --device-id "DEVICE_UDID" --bundle-id "com.test.snapshot" diff --git a/src/snapshot-tests/__fixtures__/project-discovery/get-macos-bundle-id--error-missing-app.txt b/src/snapshot-tests/__fixtures__/project-discovery/get-macos-bundle-id--error-missing-app.txt new file mode 100644 index 00000000..8448129e --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/get-macos-bundle-id--error-missing-app.txt @@ -0,0 +1,6 @@ + +๐Ÿ” Get macOS Bundle ID + + App: /nonexistent/path/Fake.app + +โŒ File not found: '/nonexistent/path/Fake.app'. Please check the path and try again. diff --git a/src/snapshot-tests/__fixtures__/project-discovery/get-macos-bundle-id--success.txt b/src/snapshot-tests/__fixtures__/project-discovery/get-macos-bundle-id--success.txt new file mode 100644 index 00000000..7a9e8b59 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/get-macos-bundle-id--success.txt @@ -0,0 +1,11 @@ + +๐Ÿ” Get macOS Bundle ID + + App: /BundleTest.app + +โœ… Bundle ID + โ”” com.test.snapshot + +Next steps: +1. Launch the app: xcodebuildmcp macos launch --app-path "/BundleTest.app" +2. Build again: xcodebuildmcp macos build --scheme "SCHEME_NAME" diff --git a/src/snapshot-tests/__fixtures__/project-discovery/list-schemes--error-invalid-workspace.txt b/src/snapshot-tests/__fixtures__/project-discovery/list-schemes--error-invalid-workspace.txt new file mode 100644 index 00000000..d9f29e7f --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/list-schemes--error-invalid-workspace.txt @@ -0,0 +1,7 @@ + +๐Ÿ” List Schemes + + Workspace: /nonexistent/path/Fake.xcworkspace + +โŒ +xcodebuild: error: '/nonexistent/path/Fake.xcworkspace' does not exist. diff --git a/src/snapshot-tests/__fixtures__/project-discovery/list-schemes--success.txt b/src/snapshot-tests/__fixtures__/project-discovery/list-schemes--success.txt new file mode 100644 index 00000000..5321bdc2 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/list-schemes--success.txt @@ -0,0 +1,16 @@ + +๐Ÿ” List Schemes + + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + +โœ… Found 2 schemes + +Schemes: + CalculatorApp + CalculatorAppFeature + +Next steps: +1. Build for macOS: xcodebuildmcp macos build --workspace-path "example_projects/iOS_Calculator/CalculatorApp.xcworkspace" --scheme "CalculatorApp" +2. Build and run on iOS Simulator (default for run intent): xcodebuildmcp simulator build-and-run --workspace-path "example_projects/iOS_Calculator/CalculatorApp.xcworkspace" --scheme "CalculatorApp" --simulator-name "iPhone 17" +3. Build for iOS Simulator (compile-only): xcodebuildmcp simulator build --workspace-path "example_projects/iOS_Calculator/CalculatorApp.xcworkspace" --scheme "CalculatorApp" --simulator-name "iPhone 17" +4. Show build settings: xcodebuildmcp device show-build-settings --workspace-path "example_projects/iOS_Calculator/CalculatorApp.xcworkspace" --scheme "CalculatorApp" diff --git a/src/snapshot-tests/__fixtures__/project-discovery/show-build-settings--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/project-discovery/show-build-settings--error-wrong-scheme.txt new file mode 100644 index 00000000..76f8c183 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/show-build-settings--error-wrong-scheme.txt @@ -0,0 +1,8 @@ + +๐Ÿ” Show Build Settings + + Scheme: NONEXISTENT + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + +โŒ +xcodebuild: error: The workspace named "CalculatorApp" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the workspace. diff --git a/src/snapshot-tests/__fixtures__/project-discovery/show-build-settings--success.txt b/src/snapshot-tests/__fixtures__/project-discovery/show-build-settings--success.txt new file mode 100644 index 00000000..30f1e84f --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-discovery/show-build-settings--success.txt @@ -0,0 +1,617 @@ + +๐Ÿ” Show Build Settings + + Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + +โœ… Build settings retrieved + +Settings + Build settings for action build and target CalculatorApp: + ACTION = build + AD_HOC_CODE_SIGNING_ALLOWED = NO + AGGREGATE_TRACKED_DOMAINS = YES + ALLOW_BUILD_REQUEST_OVERRIDES = NO + ALLOW_TARGET_PLATFORM_SPECIALIZATION = NO + ALTERNATE_GROUP = staff + ALTERNATE_MODE = u+w,go-w,a+rX + ALTERNATE_OWNER = cameroncooke + ALTERNATIVE_DISTRIBUTION_WEB = NO + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO + ALWAYS_SEARCH_USER_PATHS = NO + ALWAYS_USE_SEPARATE_HEADERMAPS = NO + APPLICATION_EXTENSION_API_ONLY = NO + APPLY_RULES_IN_COPY_FILES = NO + APPLY_RULES_IN_COPY_HEADERS = NO + APP_SHORTCUTS_ENABLE_FLEXIBLE_MATCHING = YES + ARCHS = arm64 + ARCHS_BASE = arm64 + ARCHS_STANDARD = arm64 + ARCHS_STANDARD_32_64_BIT = armv7 arm64 + ARCHS_STANDARD_32_BIT = armv7 + ARCHS_STANDARD_64_BIT = arm64 + ARCHS_STANDARD_INCLUDING_64_BIT = arm64 + ARCHS_UNIVERSAL_IPHONE_OS = armv7 arm64 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor + ASSETCATALOG_FILTER_FOR_DEVICE_MODEL = MacFamily20,1 + ASSETCATALOG_FILTER_FOR_DEVICE_OS_VERSION = 26.3 + ASSETCATALOG_FILTER_FOR_THINNING_DEVICE_CONFIGURATION = MacFamily20,1 + AUTOMATICALLY_MERGE_DEPENDENCIES = NO + AUTOMATION_APPLE_EVENTS = NO + AVAILABLE_PLATFORMS = android appletvos appletvsimulator driverkit freebsd iphoneos iphonesimulator linux macosx none openbsd qnx watchos watchsimulator webassembly xros xrsimulator + BUILD_ACTIVE_RESOURCES_ONLY = YES + BUILD_COMPONENTS = headers build + BUILD_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products + BUILD_LIBRARY_FOR_DISTRIBUTION = NO + BUILD_ONLY_KNOWN_LOCALIZATIONS = NO + BUILD_ROOT = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products + BUILD_STYLE = + BUILD_VARIANTS = normal + BUILT_PRODUCTS_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos + BUNDLE_CONTENTS_FOLDER_PATH_deep = Contents/ + BUNDLE_EXECUTABLE_FOLDER_NAME_deep = MacOS + BUNDLE_EXTENSIONS_FOLDER_PATH = Extensions + BUNDLE_FORMAT = shallow + BUNDLE_FRAMEWORKS_FOLDER_PATH = Frameworks + BUNDLE_PLUGINS_FOLDER_PATH = PlugIns + BUNDLE_PRIVATE_HEADERS_FOLDER_PATH = PrivateHeaders + BUNDLE_PUBLIC_HEADERS_FOLDER_PATH = Headers + CACHE_ROOT = /var/folders/_t/2njffz894t57qpp76v1sw__h0000gn/C/com.apple.DeveloperTools/26.4-17E192/Xcode + CCHROOT = /var/folders/_t/2njffz894t57qpp76v1sw__h0000gn/C/com.apple.DeveloperTools/26.4-17E192/Xcode + CHMOD = /bin/chmod + CHOWN = chown + CLANG_ANALYZER_NONNULL = YES + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE + CLANG_CACHE_FINE_GRAINED_OUTPUTS = YES + CLANG_COVERAGE_MAPPING = YES + CLANG_CXX_LANGUAGE_STANDARD = gnu++20 + CLANG_ENABLE_EXPLICIT_MODULES = YES + CLANG_ENABLE_MODULES = YES + CLANG_ENABLE_OBJC_ARC = YES + CLANG_ENABLE_OBJC_WEAK = YES + CLANG_MODULES_BUILD_SESSION_FILE = /Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation + CLANG_PROFILE_DATA_DIRECTORY = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/ProfileData + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES + CLANG_WARN_BOOL_CONVERSION = YES + CLANG_WARN_COMMA = YES + CLANG_WARN_CONSTANT_CONVERSION = YES + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR + CLANG_WARN_DOCUMENTATION_COMMENTS = YES + CLANG_WARN_EMPTY_BODY = YES + CLANG_WARN_ENUM_CONVERSION = YES + CLANG_WARN_INFINITE_RECURSION = YES + CLANG_WARN_INT_CONVERSION = YES + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES + CLANG_WARN_STRICT_PROTOTYPES = YES + CLANG_WARN_SUSPICIOUS_MOVE = YES + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE + CLANG_WARN_UNREACHABLE_CODE = YES + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES + CLASS_FILE_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/JavaClasses + CLEAN_PRECOMPS = YES + CLONE_HEADERS = NO + CODESIGNING_FOLDER_PATH = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app + CODE_SIGNING_ALLOWED = YES + CODE_SIGNING_REQUIRED = YES + CODE_SIGN_CONTEXT_CLASS = XCiPhoneOSCodeSignContext + CODE_SIGN_IDENTITY = Apple Development + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = YES + CODE_SIGN_STYLE = Automatic + COLOR_DIAGNOSTICS = NO + COMBINE_HIDPI_IMAGES = NO + COMPILATION_CACHE_CAS_PATH = /Library/Developer/Xcode/DerivedData/CompilationCache.noindex + COMPILATION_CACHE_KEEP_CAS_DIRECTORY = YES + COMPILER_INDEX_STORE_ENABLE = Default + COMPOSITE_SDK_DIRS = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CompositeSDKs + COMPRESS_PNG_FILES = YES + CONFIGURATION = Debug + CONFIGURATION_BUILD_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos + CONFIGURATION_TEMP_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos + CONTENTS_FOLDER_PATH = CalculatorApp.app + CONTENTS_FOLDER_PATH_SHALLOW_BUNDLE_NO = CalculatorApp.app/Contents + CONTENTS_FOLDER_PATH_SHALLOW_BUNDLE_YES = CalculatorApp.app + COPYING_PRESERVES_HFS_DATA = NO + COPY_HEADERS_RUN_UNIFDEF = NO + COPY_PHASE_STRIP = NO + CORRESPONDING_SIMULATOR_PLATFORM_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform + CORRESPONDING_SIMULATOR_PLATFORM_NAME = iphonesimulator + CORRESPONDING_SIMULATOR_SDK_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.4.sdk + CORRESPONDING_SIMULATOR_SDK_NAME = iphonesimulator26.4 + CP = /bin/cp + CREATE_INFOPLIST_SECTION_IN_BINARY = NO + CURRENT_ARCH = undefined_arch + CURRENT_PROJECT_VERSION = 1 + CURRENT_VARIANT = normal + DEAD_CODE_STRIPPING = YES + DEBUGGING_SYMBOLS = YES + DEBUG_INFORMATION_FORMAT = dwarf + DEBUG_INFORMATION_VERSION = compiler-default + DEFAULT_COMPILER = com.apple.compilers.llvm.clang.1_0 + DEFAULT_DEXT_INSTALL_PATH = /System/Library/DriverExtensions + DEFAULT_KEXT_INSTALL_PATH = /System/Library/Extensions + DEFINES_MODULE = NO + DEPLOYMENT_LOCATION = NO + DEPLOYMENT_POSTPROCESSING = NO + DEPLOYMENT_TARGET_SETTING_NAME = IPHONEOS_DEPLOYMENT_TARGET + DEPLOYMENT_TARGET_SUGGESTED_VALUES = 12.0 12.1 12.2 12.3 12.4 13.0 13.1 13.2 13.3 13.4 13.5 13.6 14.0 14.1 14.2 14.3 14.4 14.5 14.6 14.7 15.0 15.1 15.2 15.3 15.4 15.5 15.6 16.0 16.1 16.2 16.3 16.4 16.5 16.6 17.0 17.1 17.2 17.3 17.4 17.5 17.6 18.0 18.1 18.2 18.3 18.4 18.5 18.6 26.0 26.2 26.3 26.4 + DERIVED_FILES_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/DerivedSources + DERIVED_FILE_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/DerivedSources + DERIVED_SOURCES_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/DerivedSources + DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = NO + DEVELOPER_APPLICATIONS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Applications + DEVELOPER_BIN_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/usr/bin + DEVELOPER_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer + DEVELOPER_FRAMEWORKS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Library/Frameworks + DEVELOPER_FRAMEWORKS_DIR_QUOTED = /Applications/Xcode-26.4.0.app/Contents/Developer/Library/Frameworks + DEVELOPER_LIBRARY_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Library + DEVELOPER_SDK_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs + DEVELOPER_TOOLS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Tools + DEVELOPER_USR_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/usr + DEVELOPMENT_LANGUAGE = en + DEVELOPMENT_TEAM = BR6WD3M6ZD + DIAGNOSE_MISSING_TARGET_DEPENDENCIES = YES + DIFF = /usr/bin/diff + DOCUMENTATION_FOLDER_PATH = CalculatorApp.app/en.lproj/Documentation + DONT_GENERATE_INFOPLIST_FILE = NO + DRIVERKIT_DEPLOYMENT_TARGET = 25.4 + DSTROOT = /tmp/CalculatorApp.dst + DT_TOOLCHAIN_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain + DUMP_DEPENDENCIES = NO + DUMP_DEPENDENCIES_OUTPUT_PATH = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/CalculatorApp-BuildDependencyInfo.json + DWARF_DSYM_FILE_NAME = CalculatorApp.app.dSYM + DWARF_DSYM_FILE_SHOULD_ACCOMPANY_PRODUCT = NO + DWARF_DSYM_FOLDER_PATH = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos + DYNAMIC_LIBRARY_EXTENSION = dylib + EAGER_COMPILATION_ALLOW_SCRIPTS = YES + EAGER_LINKING = NO + EFFECTIVE_PLATFORM_NAME = -iphoneos + EFFECTIVE_SWIFT_VERSION = 5 + EMBEDDED_CONTENT_CONTAINS_SWIFT = NO + EMBEDDED_PROFILE_NAME = embedded.mobileprovision + EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = NO + ENABLE_APP_SANDBOX = NO + ENABLE_CODE_COVERAGE = YES + ENABLE_COHORT_ARCHS = NO + ENABLE_CPLUSPLUS_BOUNDS_SAFE_BUFFERS = NO + ENABLE_C_BOUNDS_SAFETY = NO + ENABLE_DEBUG_DYLIB = YES + ENABLE_DEFAULT_HEADER_SEARCH_PATHS = YES + ENABLE_DEFAULT_SEARCH_PATHS = YES + ENABLE_ENHANCED_SECURITY = NO + ENABLE_HARDENED_RUNTIME = NO + ENABLE_HEADER_DEPENDENCIES = YES + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO + ENABLE_ON_DEMAND_RESOURCES = YES + ENABLE_OUTGOING_NETWORK_CONNECTIONS = NO + ENABLE_POINTER_AUTHENTICATION = NO + ENABLE_PREVIEWS = YES + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO + ENABLE_RESOURCE_ACCESS_CALENDARS = NO + ENABLE_RESOURCE_ACCESS_CAMERA = NO + ENABLE_RESOURCE_ACCESS_CONTACTS = NO + ENABLE_RESOURCE_ACCESS_LOCATION = NO + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = NO + ENABLE_RESOURCE_ACCESS_PRINTING = NO + ENABLE_RESOURCE_ACCESS_USB = NO + ENABLE_SDK_IMPORTS = NO + ENABLE_SECURITY_COMPILER_WARNINGS = NO + ENABLE_STRICT_OBJC_MSGSEND = YES + ENABLE_TESTABILITY = YES + ENABLE_TESTING_SEARCH_PATHS = NO + ENABLE_THREAD_SANITIZER = NO + ENABLE_USER_SCRIPT_SANDBOXING = YES + ENFORCE_VALID_ARCHS = YES + ENTITLEMENTS_ALLOWED = YES + ENTITLEMENTS_DESTINATION = Signature + ENTITLEMENTS_REQUIRED = NO + EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS = .DS_Store .svn .git .hg CVS + EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = *.nib *.lproj *.framework *.gch *.xcode* *.xcassets *.icon (*) .DS_Store CVS .svn .git .hg *.pbproj *.pbxproj + EXECUTABLES_FOLDER_PATH = CalculatorApp.app/Executables + EXECUTABLE_FOLDER_PATH = CalculatorApp.app + EXECUTABLE_FOLDER_PATH_SHALLOW_BUNDLE_NO = CalculatorApp.app/MacOS + EXECUTABLE_FOLDER_PATH_SHALLOW_BUNDLE_YES = CalculatorApp.app + EXECUTABLE_NAME = CalculatorApp + EXECUTABLE_PATH = CalculatorApp.app/CalculatorApp + EXTENSIONS_FOLDER_PATH = CalculatorApp.app/Extensions + FILE_LIST = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects/LinkFileList + FIXED_FILES_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/FixedFiles + FRAMEWORKS_FOLDER_PATH = CalculatorApp.app/Frameworks + FRAMEWORK_FLAG_PREFIX = -framework + FRAMEWORK_SEARCH_PATHS = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos + FRAMEWORK_VERSION = A + FULL_PRODUCT_NAME = CalculatorApp.app + FUSE_BUILD_PHASES = YES + FUSE_BUILD_SCRIPT_PHASES = NO + GCC3_VERSION = 3.3 + GCC_C_LANGUAGE_STANDARD = gnu17 + GCC_DYNAMIC_NO_PIC = NO + GCC_INLINES_ARE_PRIVATE_EXTERN = YES + GCC_NO_COMMON_BLOCKS = YES + GCC_OPTIMIZATION_LEVEL = 0 + GCC_PFE_FILE_C_DIALECTS = c objective-c c++ objective-c++ + GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 + GCC_SYMBOLS_PRIVATE_EXTERN = NO + GCC_THUMB_SUPPORT = YES + GCC_TREAT_WARNINGS_AS_ERRORS = NO + GCC_VERSION = com.apple.compilers.llvm.clang.1_0 + GCC_VERSION_IDENTIFIER = com_apple_compilers_llvm_clang_1_0 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR + GCC_WARN_UNDECLARED_SELECTOR = YES + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE + GCC_WARN_UNUSED_FUNCTION = YES + GCC_WARN_UNUSED_VARIABLE = YES + GENERATED_MODULEMAP_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/GeneratedModuleMaps-iphoneos + GENERATE_INFOPLIST_FILE = YES + GENERATE_INTERMEDIATE_TEXT_BASED_STUBS = YES + GENERATE_PKGINFO_FILE = YES + GENERATE_PRELINK_OBJECT_FILE = NO + GENERATE_PROFILING_CODE = NO + GENERATE_TEXT_BASED_STUBS = NO + GID = 20 + GROUP = staff + HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT = YES + HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = YES + HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_TARGETS_NOT_BEING_BUILT = YES + HEADERMAP_INCLUDES_NONPUBLIC_NONPRIVATE_HEADERS = YES + HEADERMAP_INCLUDES_PROJECT_HEADERS = YES + HEADERMAP_USES_FRAMEWORK_PREFIX_ENTRIES = YES + HEADERMAP_USES_VFS = NO + HEADER_SEARCH_PATHS = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/include + HOME = + HOST_ARCH = arm64 + HOST_PLATFORM = macosx + ICONV = /usr/bin/iconv + IMPLICIT_DEPENDENCY_DOMAIN = default + INDEX_STORE_COMPRESS = NO + INDEX_STORE_ONLY_PROJECT_FILES = NO + INFOPLIST_ENABLE_CFBUNDLEICONS_MERGE = YES + INFOPLIST_EXPAND_BUILD_SETTINGS = YES + INFOPLIST_KEY_CFBundleDisplayName = Calculator + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES + INFOPLIST_KEY_UILaunchScreen_Generation = YES + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationLandscapeRight UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationPortrait + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = UIInterfaceOrientationLandscapeRight UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown + INFOPLIST_OUTPUT_FORMAT = binary + INFOPLIST_PATH = CalculatorApp.app/Info.plist + INFOPLIST_PREPROCESS = NO + INFOSTRINGS_PATH = CalculatorApp.app/en.lproj/InfoPlist.strings + INLINE_PRIVATE_FRAMEWORKS = NO + INSTALLAPI_IGNORE_SKIP_INSTALL = YES + INSTALLHDRS_COPY_PHASE = NO + INSTALLHDRS_SCRIPT_PHASE = NO + INSTALL_DIR = /tmp/CalculatorApp.dst/Applications + INSTALL_GROUP = staff + INSTALL_MODE_FLAG = u+w,go-w,a+rX + INSTALL_OWNER = cameroncooke + INSTALL_PATH = /Applications + INSTALL_ROOT = /tmp/CalculatorApp.dst + IPHONEOS_DEPLOYMENT_TARGET = 17.0 + IS_UNOPTIMIZED_BUILD = YES + JAVAC_DEFAULT_FLAGS = -J-Xms64m -J-XX:NewSize=4M -J-Dfile.encoding=UTF8 + JAVA_APP_STUB = /System/Library/Frameworks/JavaVM.framework/Resources/MacOS/JavaApplicationStub + JAVA_ARCHIVE_CLASSES = YES + JAVA_ARCHIVE_TYPE = JAR + JAVA_COMPILER = /usr/bin/javac + JAVA_FOLDER_PATH = CalculatorApp.app/Java + JAVA_FRAMEWORK_RESOURCES_DIRS = Resources + JAVA_JAR_FLAGS = cv + JAVA_SOURCE_SUBDIR = . + JAVA_USE_DEPENDENCIES = YES + JAVA_ZIP_FLAGS = -urg + JIKES_DEFAULT_FLAGS = +E +OLDCSO + KASAN_CFLAGS_CLASSIC = -DKASAN=1 -DKASAN_CLASSIC=1 -fsanitize=address -mllvm -asan-globals-live-support -mllvm -asan-force-dynamic-shadow + KASAN_CFLAGS_TBI = -DKASAN=1 -DKASAN_TBI=1 -fsanitize=kernel-hwaddress -mllvm -hwasan-recover=0 -mllvm -hwasan-instrument-atomics=0 -mllvm -hwasan-instrument-stack=1 -mllvm -hwasan-generate-tags-with-calls=1 -mllvm -hwasan-instrument-with-calls=1 -mllvm -hwasan-use-short-granules=0 -mllvm -hwasan-memory-access-callback-prefix=__asan_ + KASAN_DEFAULT_CFLAGS = -DKASAN=1 -DKASAN_CLASSIC=1 -fsanitize=address -mllvm -asan-globals-live-support -mllvm -asan-force-dynamic-shadow + KEEP_PRIVATE_EXTERNS = NO + LD_DEPENDENCY_INFO_FILE = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal/undefined_arch/CalculatorApp_dependency_info.dat + LD_EXPORT_GLOBAL_SYMBOLS = YES + LD_EXPORT_SYMBOLS = YES + LD_GENERATE_MAP_FILE = NO + LD_MAP_FILE_PATH = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/CalculatorApp-LinkMap-normal-undefined_arch.txt + LD_NO_PIE = NO + LD_QUOTE_LINKER_ARGUMENTS_FOR_COMPILER_DRIVER = YES + LD_RUNPATH_SEARCH_PATHS = @executable_path/Frameworks + LD_RUNPATH_SEARCH_PATHS_YES = @loader_path/../Frameworks + LD_SHARED_CACHE_ELIGIBLE = Automatic + LD_WARN_DUPLICATE_LIBRARIES = NO + LD_WARN_UNUSED_DYLIBS = NO + LEGACY_DEVELOPER_DIR = /Applications/Xcode-26.4.0.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer + LEX = lex + LIBRARY_DEXT_INSTALL_PATH = /Library/DriverExtensions + LIBRARY_FLAG_NOSPACE = YES + LIBRARY_FLAG_PREFIX = -l + LIBRARY_KEXT_INSTALL_PATH = /Library/Extensions + LIBRARY_SEARCH_PATHS = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos + LINKER_DISPLAYS_MANGLED_NAMES = NO + LINK_FILE_LIST_normal_arm64 = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal/arm64/CalculatorApp.LinkFileList + LINK_OBJC_RUNTIME = YES + LINK_WITH_STANDARD_LIBRARIES = YES + LLVM_TARGET_TRIPLE_OS_VERSION = ios17.0 + LLVM_TARGET_TRIPLE_VENDOR = apple + LM_AUX_CONST_METADATA_LIST_PATH_normal_arm64 = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal/arm64/CalculatorApp.SwiftConstValuesFileList + LOCALIZATION_EXPORT_SUPPORTED = YES + LOCALIZATION_PREFERS_STRING_CATALOGS = YES + LOCALIZED_RESOURCES_FOLDER_PATH = CalculatorApp.app/en.lproj + LOCALIZED_STRING_CODE_COMMENTS = NO + LOCALIZED_STRING_MACRO_NAMES = NSLocalizedString CFCopyLocalizedString + LOCALIZED_STRING_SWIFTUI_SUPPORT = YES + LOCAL_ADMIN_APPS_DIR = /Applications/Utilities + LOCAL_APPS_DIR = /Applications + LOCAL_DEVELOPER_DIR = /Library/Developer + LOCAL_LIBRARY_DIR = /Library + LOCROOT = /example_projects/iOS_Calculator + LOCSYMROOT = /example_projects/iOS_Calculator + MACH_O_TYPE = mh_execute + MACOSX_DEPLOYMENT_TARGET = 26.4 + MAC_OS_X_PRODUCT_BUILD_VERSION = 25D2128 + MAC_OS_X_VERSION_ACTUAL = 260301 + MAC_OS_X_VERSION_MAJOR = 260000 + MAC_OS_X_VERSION_MINOR = 260300 + MAKE_MERGEABLE = NO + MARKETING_VERSION = 1.0 + MERGEABLE_LIBRARY = NO + MERGED_BINARY_TYPE = none + MERGE_LINKED_LIBRARIES = NO + METAL_LIBRARY_FILE_BASE = default + METAL_LIBRARY_OUTPUT_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app + MODULES_FOLDER_PATH = CalculatorApp.app/Modules + MODULE_CACHE_DIR = /Library/Developer/Xcode/DerivedData/ModuleCache.noindex + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE + MTL_FAST_MATH = YES + NATIVE_ARCH = arm64 + NATIVE_ARCH_32_BIT = arm + NATIVE_ARCH_64_BIT = arm64 + NATIVE_ARCH_ACTUAL = arm64 + NO_COMMON = YES + OBJECT_FILE_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects + OBJECT_FILE_DIR_normal = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal + OBJROOT = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex + ONLY_ACTIVE_ARCH = YES + OS = MACOS + OSAC = /usr/bin/osacompile + PACKAGE_TYPE = com.apple.package-type.wrapper.application + PASCAL_STRINGS = YES + PATH = + PATH_PREFIXES_EXCLUDED_FROM_HEADER_DEPENDENCIES = /usr/include /usr/local/include /System/Library/Frameworks /System/Library/PrivateFrameworks /Applications/Xcode-26.4.0.app/Contents/Developer/Headers /Applications/Xcode-26.4.0.app/Contents/Developer/SDKs /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms + PBDEVELOPMENTPLIST_PATH = CalculatorApp.app/pbdevelopment.plist + PER_ARCH_MODULE_FILE_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal/undefined_arch + PER_ARCH_OBJECT_FILE_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal/undefined_arch + PER_VARIANT_OBJECT_FILE_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal + PKGINFO_FILE_PATH = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/PkgInfo + PKGINFO_PATH = CalculatorApp.app/PkgInfo + PLATFORM_DEVELOPER_APPLICATIONS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Applications + PLATFORM_DEVELOPER_BIN_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin + PLATFORM_DEVELOPER_LIBRARY_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library + PLATFORM_DEVELOPER_SDK_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs + PLATFORM_DEVELOPER_TOOLS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Tools + PLATFORM_DEVELOPER_USR_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr + PLATFORM_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform + PLATFORM_DISPLAY_NAME = iOS + PLATFORM_FAMILY_NAME = iOS + PLATFORM_NAME = iphoneos + PLATFORM_PREFERRED_ARCH = arm64 + PLATFORM_PRODUCT_BUILD_VERSION = 23E237 + PLATFORM_REQUIRES_SWIFT_AUTOLINK_EXTRACT = NO + PLATFORM_REQUIRES_SWIFT_MODULEWRAP = NO + PLATFORM_USES_DSYMS = YES + PLIST_FILE_OUTPUT_FORMAT = binary + PLUGINS_FOLDER_PATH = CalculatorApp.app/PlugIns + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES + PRECOMP_DESTINATION_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/PrefixHeaders + PRIVATE_HEADERS_FOLDER_PATH = CalculatorApp.app/PrivateHeaders + PROCESSED_INFOPLIST_PATH = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal/undefined_arch/Processed-Info.plist + PRODUCT_BUNDLE_IDENTIFIER = io.sentry.calculatorapp + PRODUCT_BUNDLE_PACKAGE_TYPE = APPL + PRODUCT_DISPLAY_NAME = Calculator + PRODUCT_MODULE_NAME = CalculatorApp + PRODUCT_NAME = CalculatorApp + PRODUCT_SETTINGS_PATH = + PRODUCT_TYPE = com.apple.product-type.application + PROFILING_CODE = NO + PROJECT = CalculatorApp + PROJECT_DERIVED_FILE_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/DerivedSources + PROJECT_DIR = /example_projects/iOS_Calculator + PROJECT_FILE_PATH = /example_projects/iOS_Calculator/CalculatorApp.xcodeproj + PROJECT_GUID = 5f13bb9ad2ee840212986da3cd4b87b0 + PROJECT_NAME = CalculatorApp + PROJECT_TEMP_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build + PROJECT_TEMP_ROOT = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex + PROVISIONING_PROFILE_REQUIRED = YES + PROVISIONING_PROFILE_REQUIRED_YES_YES = YES + PROVISIONING_PROFILE_SUPPORTED = YES + PUBLIC_HEADERS_FOLDER_PATH = CalculatorApp.app/Headers + RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET = 15.0 + RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS = YES + REMOVE_CVS_FROM_RESOURCES = YES + REMOVE_GIT_FROM_RESOURCES = YES + REMOVE_HEADERS_FROM_EMBEDDED_BUNDLES = YES + REMOVE_HG_FROM_RESOURCES = YES + REMOVE_STATIC_EXECUTABLES_FROM_EMBEDDED_BUNDLES = YES + REMOVE_SVN_FROM_RESOURCES = YES + RESCHEDULE_INDEPENDENT_HEADERS_PHASES = YES + REZ_COLLECTOR_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/ResourceManagerResources + REZ_OBJECTS_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/ResourceManagerResources/Objects + REZ_SEARCH_PATHS = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos + RPATH_ORIGIN = @loader_path + RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES = NO + RUNTIME_EXCEPTION_ALLOW_JIT = NO + RUNTIME_EXCEPTION_ALLOW_UNSIGNED_EXECUTABLE_MEMORY = NO + RUNTIME_EXCEPTION_DEBUGGING_TOOL = NO + RUNTIME_EXCEPTION_DISABLE_EXECUTABLE_PAGE_PROTECTION = NO + RUNTIME_EXCEPTION_DISABLE_LIBRARY_VALIDATION = NO + SCANNING_PCM_KEEP_CACHE_DIRECTORY = YES + SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = NO + SCRIPTS_FOLDER_PATH = CalculatorApp.app/Scripts + SDKROOT = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS26.4.sdk + SDK_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS26.4.sdk + SDK_DIR_iphoneos = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS26.4.sdk + SDK_DIR_iphoneos26_4 = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS26.4.sdk + SDK_NAME = iphoneos26.4 + SDK_NAMES = iphoneos26.4 + SDK_PRODUCT_BUILD_VERSION = 23E237 + SDK_STAT_CACHE_DIR = /Library/Developer/Xcode/DerivedData + SDK_STAT_CACHE_ENABLE = YES + SDK_STAT_CACHE_PATH = /Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphoneos26.4-23E237-c1e9a37d8fcda5dee89abd67dc927a23.sdkstatcache + SDK_VERSION = 26.4 + SDK_VERSION_ACTUAL = 260400 + SDK_VERSION_MAJOR = 260000 + SDK_VERSION_MINOR = 260400 + SED = /usr/bin/sed + SEPARATE_STRIP = NO + SEPARATE_SYMBOL_EDIT = NO + SET_DIR_MODE_OWNER_GROUP = YES + SET_FILE_MODE_OWNER_GROUP = NO + SHALLOW_BUNDLE = YES + SHALLOW_BUNDLE_TRIPLE = ios + SHALLOW_BUNDLE_ios_macabi = NO + SHALLOW_BUNDLE_macos = NO + SHARED_DERIVED_FILE_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/DerivedSources + SHARED_FRAMEWORKS_FOLDER_PATH = CalculatorApp.app/SharedFrameworks + SHARED_PRECOMPS_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/PrecompiledHeaders + SHARED_SUPPORT_FOLDER_PATH = CalculatorApp.app/SharedSupport + SKIP_INSTALL = NO + SKIP_MERGEABLE_LIBRARY_BUNDLE_HOOK = NO + SOURCE_ROOT = /example_projects/iOS_Calculator + SRCROOT = /example_projects/iOS_Calculator + STRINGSDATA_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal/undefined_arch + STRINGSDATA_ROOT = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build + STRINGS_FILE_INFOPLIST_RENAME = YES + STRINGS_FILE_OUTPUT_ENCODING = binary + STRING_CATALOG_GENERATE_SYMBOLS = NO + STRIP_BITCODE_FROM_COPIED_FILES = YES + STRIP_INSTALLED_PRODUCT = NO + STRIP_STYLE = all + STRIP_SWIFT_SYMBOLS = YES + SUPPORTED_DEVICE_FAMILIES = 1,2 + SUPPORTED_PLATFORMS = iphoneos iphonesimulator + SUPPORTS_MACCATALYST = NO + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES + SUPPORTS_ON_DEMAND_RESOURCES = YES + SUPPORTS_TEXT_BASED_API = NO + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES + SUPPRESS_WARNINGS = NO + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG + SWIFT_EMIT_CONST_VALUE_PROTOCOLS = AnyResolverProviding AppEntity AppEnum AppExtension AppIntent AppIntentsPackage AppShortcutProviding AppShortcutsProvider AppUnionValue AppUnionValueCasesProviding DynamicOptionsProvider EntityQuery ExtensionPointDefining IntentValueQuery Resolver TransientEntity _AssistantIntentsProvider _GenerativeFunctionExtractable _IntentValueRepresentable + SWIFT_EMIT_LOC_STRINGS = YES + SWIFT_ENABLE_EXPLICIT_MODULES = YES + SWIFT_OPTIMIZATION_LEVEL = -Onone + SWIFT_PLATFORM_TARGET_PREFIX = ios + SWIFT_RESPONSE_FILE_PATH_normal_arm64 = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build/Objects-normal/arm64/CalculatorApp.SwiftFileList + SWIFT_VERSION = 5.0 + SYMROOT = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products + SYSTEM_ADMIN_APPS_DIR = /Applications/Utilities + SYSTEM_APPS_DIR = /Applications + SYSTEM_CORE_SERVICES_DIR = /System/Library/CoreServices + SYSTEM_DEMOS_DIR = /Applications/Extras + SYSTEM_DEVELOPER_APPS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Applications + SYSTEM_DEVELOPER_BIN_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/usr/bin + SYSTEM_DEVELOPER_DEMOS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Applications/Utilities/Built Examples + SYSTEM_DEVELOPER_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer + SYSTEM_DEVELOPER_DOC_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/ADC Reference Library + SYSTEM_DEVELOPER_GRAPHICS_TOOLS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Applications/Graphics Tools + SYSTEM_DEVELOPER_JAVA_TOOLS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Applications/Java Tools + SYSTEM_DEVELOPER_PERFORMANCE_TOOLS_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Applications/Performance Tools + SYSTEM_DEVELOPER_RELEASENOTES_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/ADC Reference Library/releasenotes + SYSTEM_DEVELOPER_TOOLS = /Applications/Xcode-26.4.0.app/Contents/Developer/Tools + SYSTEM_DEVELOPER_TOOLS_DOC_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/ADC Reference Library/documentation/DeveloperTools + SYSTEM_DEVELOPER_TOOLS_RELEASENOTES_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/ADC Reference Library/releasenotes/DeveloperTools + SYSTEM_DEVELOPER_USR_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/usr + SYSTEM_DEVELOPER_UTILITIES_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Applications/Utilities + SYSTEM_DEXT_INSTALL_PATH = /System/Library/DriverExtensions + SYSTEM_DOCUMENTATION_DIR = /Library/Documentation + SYSTEM_EXTENSIONS_FOLDER_PATH = CalculatorApp.app/SystemExtensions + SYSTEM_EXTENSIONS_FOLDER_PATH_SHALLOW_BUNDLE_NO = CalculatorApp.app/Library/SystemExtensions + SYSTEM_EXTENSIONS_FOLDER_PATH_SHALLOW_BUNDLE_YES = CalculatorApp.app/SystemExtensions + SYSTEM_KEXT_INSTALL_PATH = /System/Library/Extensions + SYSTEM_LIBRARY_DIR = /System/Library + TAPI_DEMANGLE = YES + TAPI_ENABLE_PROJECT_HEADERS = NO + TAPI_LANGUAGE = objective-c + TAPI_LANGUAGE_STANDARD = compiler-default + TAPI_USE_SRCROOT = YES + TAPI_VERIFY_MODE = Pedantic + TARGETED_DEVICE_FAMILY = 1,2 + TARGETNAME = CalculatorApp + TARGET_BUILD_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos + TARGET_DEVICE_IDENTIFIER = + TARGET_DEVICE_MODEL = Mac16,8 + TARGET_DEVICE_OS_VERSION = 26.3.1 + TARGET_DEVICE_PLATFORM_NAME = macosx + TARGET_NAME = CalculatorApp + TARGET_TEMP_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build + TEMP_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build + TEMP_FILES_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build + TEMP_FILE_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/CalculatorApp.build/Debug-iphoneos/CalculatorApp.build + TEMP_ROOT = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex + TEMP_SANDBOX_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/TemporaryTaskSandboxes + TEST_FRAMEWORK_SEARCH_PATHS = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS26.4.sdk/Developer/Library/Frameworks + TEST_LIBRARY_SEARCH_PATHS = /Applications/Xcode-26.4.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib + TOOLCHAINS = com.apple.dt.toolchain.XcodeDefault + TOOLCHAIN_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain + TREAT_MISSING_BASELINES_AS_TEST_FAILURES = NO + TREAT_MISSING_SCRIPT_PHASE_OUTPUTS_AS_ERRORS = NO + TVOS_DEPLOYMENT_TARGET = 26.4 + UID = 501 + UNINSTALLED_PRODUCTS_DIR = /Library/Developer/Xcode/DerivedData/CalculatorApp-/Build/Intermediates.noindex/UninstalledProducts + UNLOCALIZED_RESOURCES_FOLDER_PATH = CalculatorApp.app + UNLOCALIZED_RESOURCES_FOLDER_PATH_SHALLOW_BUNDLE_NO = CalculatorApp.app/Resources + UNLOCALIZED_RESOURCES_FOLDER_PATH_SHALLOW_BUNDLE_YES = CalculatorApp.app + UNSTRIPPED_PRODUCT = NO + USER = cameroncooke + USER_APPS_DIR = /Applications + USER_LIBRARY_DIR = /Library + USE_DYNAMIC_NO_PIC = YES + USE_HEADERMAP = YES + USE_HEADER_SYMLINKS = NO + VALIDATE_DEVELOPMENT_ASSET_PATHS = YES_ERROR + VALIDATE_PRODUCT = NO + VALID_ARCHS = arm64 arm64e armv7 armv7s + VERBOSE_PBXCP = NO + VERSIONPLIST_PATH = CalculatorApp.app/version.plist + VERSION_INFO_BUILDER = cameroncooke + VERSION_INFO_FILE = CalculatorApp_vers.c + VERSION_INFO_STRING = "@(#)PROGRAM:CalculatorApp PROJECT:CalculatorApp-1" + WATCHOS_DEPLOYMENT_TARGET = 26.4 + WORKSPACE_DIR = /example_projects/iOS_Calculator + WRAPPER_EXTENSION = app + WRAPPER_NAME = CalculatorApp.app + WRAPPER_SUFFIX = .app + WRAP_ASSET_PACKS_IN_SEPARATE_DIRECTORIES = NO + XCODE_APP_SUPPORT_DIR = /Applications/Xcode-26.4.0.app/Contents/Developer/Library/Xcode + XCODE_PRODUCT_BUILD_VERSION = 17E192 + XCODE_VERSION_ACTUAL = 2640 + XCODE_VERSION_MAJOR = 2600 + XCODE_VERSION_MINOR = 2640 + XPCSERVICES_FOLDER_PATH = CalculatorApp.app/XPCServices + XROS_DEPLOYMENT_TARGET = 26.4 + YACC = yacc + _DISCOVER_COMMAND_LINE_LINKER_INPUTS = YES + _DISCOVER_COMMAND_LINE_LINKER_INPUTS_INCLUDE_WL = YES + _LD_MULTIARCH = YES + _WRAPPER_CONTENTS_DIR_SHALLOW_BUNDLE_NO = /Contents + _WRAPPER_PARENT_PATH_SHALLOW_BUNDLE_NO = /.. + _WRAPPER_RESOURCES_DIR_SHALLOW_BUNDLE_NO = /Resources + __DIAGNOSE_DEPRECATED_ARCHS = YES + __IS_NOT_MACOS = YES + __IS_NOT_MACOS_macosx = NO + __IS_NOT_SIMULATOR = YES + __IS_NOT_SIMULATOR_simulator = NO + __ORIGINAL_SDK_DEFINED_LLVM_TARGET_TRIPLE_SYS = ios + arch = undefined_arch + variant = normal + +Next steps: +1. Build for macOS: xcodebuildmcp macos build --workspace-path "example_projects/iOS_Calculator/CalculatorApp.xcworkspace" --scheme "CalculatorApp" +2. Build for iOS Simulator: xcodebuildmcp simulator build --workspace-path "example_projects/iOS_Calculator/CalculatorApp.xcworkspace" --scheme "CalculatorApp" --simulator-name "iPhone 17" +3. List schemes: xcodebuildmcp device list-schemes --workspace-path "example_projects/iOS_Calculator/CalculatorApp.xcworkspace" diff --git a/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-ios--error-existing.txt b/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-ios--error-existing.txt new file mode 100644 index 00000000..c0f01f43 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-ios--error-existing.txt @@ -0,0 +1,8 @@ + +๐Ÿ“ Scaffold iOS Project + + Name: SnapshotTestApp + Path: /ios-existing + Platform: iOS + +โŒ Xcode project files already exist in /ios-existing diff --git a/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-ios--success.txt b/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-ios--success.txt new file mode 100644 index 00000000..8c386788 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-ios--success.txt @@ -0,0 +1,14 @@ + +๐Ÿ“ Scaffold iOS Project + + Name: SnapshotTestApp + Path: /ios + Platform: iOS + +โœ… Project scaffolded successfully + โ”” /ios + +Next steps: +1. Important: Before working on the project make sure to read the README.md file in the workspace root directory. +2. Build for simulator: xcodebuildmcp simulator build --workspace-path "/ios/SnapshotTestApp.xcworkspace" --scheme "SnapshotTestApp" --simulator-name "iPhone 17" +3. Build and run on simulator: xcodebuildmcp simulator build-and-run --workspace-path "/ios/SnapshotTestApp.xcworkspace" --scheme "SnapshotTestApp" --simulator-name "iPhone 17" diff --git a/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-macos--error-existing.txt b/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-macos--error-existing.txt new file mode 100644 index 00000000..4f1820af --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-macos--error-existing.txt @@ -0,0 +1,8 @@ + +๐Ÿ“ Scaffold macOS Project + + Name: SnapshotTestMacApp + Path: /macos-existing + Platform: macOS + +โŒ Xcode project files already exist in /macos-existing diff --git a/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-macos--success.txt b/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-macos--success.txt new file mode 100644 index 00000000..ae87b758 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/project-scaffolding/scaffold-macos--success.txt @@ -0,0 +1,14 @@ + +๐Ÿ“ Scaffold macOS Project + + Name: SnapshotTestMacApp + Path: /macos + Platform: macOS + +โœ… Project scaffolded successfully + โ”” /macos + +Next steps: +1. Important: Before working on the project make sure to read the README.md file in the workspace root directory. +2. Build for macOS: xcodebuildmcp macos build --workspace-path "/macos/SnapshotTestMacApp.xcworkspace" --scheme "SnapshotTestMacApp" +3. Build & Run on macOS: xcodebuildmcp macos build-and-run --workspace-path "/macos/SnapshotTestMacApp.xcworkspace" --scheme "SnapshotTestMacApp" diff --git a/src/snapshot-tests/__fixtures__/resources/devices--success.txt b/src/snapshot-tests/__fixtures__/resources/devices--success.txt new file mode 100644 index 00000000..578860e9 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/resources/devices--success.txt @@ -0,0 +1,29 @@ + +๐Ÿ“ฑ List Devices + +iOS Devices: + + ๐Ÿ“ฑ [] Cameronโ€™s iPhone 16 Pro Max + OS: 26.3.1 (a) + UDID: + + ๐Ÿ“ฑ [] iPhone + OS: 26.1 + UDID: + +watchOS Devices: + + โŒš๏ธ [] Cameronโ€™s Appleย Watch + OS: 10.6.1 + UDID: + + โŒš๏ธ [] Cameronโ€™s Appleย Watch + OS: 26.3 + UDID: + +โœ… 4 physical devices discovered (2 iOS, 2 watchOS). + +Hints + Use the device ID/UDID from above when required by other tools. + Save a default device with session-set-defaults { deviceId: 'DEVICE_UDID' }. + Before running build/run/test/UI automation tools, set the desired device identifier in session defaults. diff --git a/src/snapshot-tests/__fixtures__/resources/doctor--success.txt b/src/snapshot-tests/__fixtures__/resources/doctor--success.txt new file mode 100644 index 00000000..418f110f --- /dev/null +++ b/src/snapshot-tests/__fixtures__/resources/doctor--success.txt @@ -0,0 +1,125 @@ + +โš™๏ธ XcodeBuildMCP Doctor + + Generated: + Server Version: + Output Mode: Redacted (default) + + โ”œ platform: darwin + โ”œ release: + โ”œ arch: arm64 + โ”œ cpus: + โ”œ memory: + โ”œ hostname: + โ”œ username: + โ”œ homedir: + โ”” tmpdir: + +Node.js Information + version: + execPath: + pid: + ppid: + platform: darwin + arch: arm64 + cwd: /Users//.codex/worktrees/43f4/ + argv: + +Process Tree + Running under Xcode: No + (ppid ): + +Xcode Information + version: + path: + selectedXcode: + xcrunVersion: + +Dependencies + axe: + mise: + +Environment Variables + INCREMENTAL_BUILDS_ENABLED: (not set) + DEVELOPER_DIR: (not set) + HOME: /Users/ + USER: + TMPDIR: + NODE_ENV: test + SENTRY_DISABLED: (not set) + AXE_PATH: (not set) + XBMCP_LAUNCH_JSON_WAIT_MS: (not set) + XCODEBUILDMCP_DEBUGGER_BACKEND: (not set) + XCODEBUILDMCP_UI_DEBUGGER_GUARD_MODE: (not set) + XCODEBUILDMCP_SILENCE_LOGS: true + +PATH + + +UI Automation (axe) + Available: Yes + UI Automation Supported: Yes + Simulator Video Capture Supported (AXe >= 1.1.0): No + UI-Debugger Guard Mode: error + +Incremental Builds + Enabled: No + xcodemake Binary Available: Yes + Makefile exists (cwd): (not checked: incremental builds disabled) + +Mise Integration + Running under mise: No + Mise available: Yes + +Debugger Backend (DAP) + lldb-dap available: Yes + Selected backend: dap + +Manifest Tool Inventory + Total Unique Tools: + Workflow Count: + coverage: tools + debugging: tools + device: tools + doctor: tools + macos: tools + project-discovery: tools + project-scaffolding: tools + session-management: tools + simulator-management: tools + simulator: tools + swift-package: tools + ui-automation: tools + utilities: tools + workflow-discovery: tools + xcode-ide: tools + +Runtime Tool Registration + Enabled Workflows: 0 + Registered Tools: 0 + Note: Runtime registry unavailable. + +Xcode IDE Bridge (mcpbridge) + Workflow enabled: No + mcpbridge path: + Xcode running: (unknown) + Connected: No + Bridge PID: (none) + Proxied tools: 0 + Last error: (none) + Note: Bridge debug tools (status/sync/disconnect) are only registered when debug: true + +Tool Availability Summary + Build Tools: Available + UI Automation Tools: Available + Incremental Build Support: Available but Disabled + +Sentry + Sentry enabled: Yes + +Troubleshooting Tips + If UI automation tools are not available, install axe: brew tap cameroncooke/axe && brew install axe + If incremental build support is not available, install xcodemake (https://github.com/cameroncooke/xcodemake) and ensure it is executable and available in your PATH + To enable xcodemake, set environment variable: export INCREMENTAL_BUILDS_ENABLED=1 + For mise integration, follow instructions in the README.md file +โœ… Doctor diagnostics complete diff --git a/src/snapshot-tests/__fixtures__/resources/session-status--success.txt b/src/snapshot-tests/__fixtures__/resources/session-status--success.txt new file mode 100644 index 00000000..d5b696d8 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/resources/session-status--success.txt @@ -0,0 +1,34 @@ +{ + "logging": { + "simulator": { + "activeSessionIds": [] + }, + "device": { + "activeSessionIds": [] + } + }, + "debug": { + "currentSessionId": null, + "sessionIds": [] + }, + "watcher": { + "running": false, + "watchedPath": null + }, + "video": { + "activeSessionIds": [] + }, + "swiftPackage": { + "activePids": [] + }, + "activity": { + "activeOperationCount": 0, + "byCategory": {} + }, + "process": { + "pid" : , + "uptimeMs": , + "rssBytes": , + "heapUsedBytes": + } +} diff --git a/src/snapshot-tests/__fixtures__/resources/simulators--success.txt b/src/snapshot-tests/__fixtures__/resources/simulators--success.txt new file mode 100644 index 00000000..2ba85f03 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/resources/simulators--success.txt @@ -0,0 +1,45 @@ + +๐Ÿ“ฑ List Simulators + +iOS Simulators: + + iOS 26.4: + + ๐Ÿ“ฑ [] iPhone 17 Pro (Shutdown) + UDID: + + ๐Ÿ“ฑ [] iPhone 17 Pro Max (Shutdown) + UDID: + + ๐Ÿ“ฑ [] iPhone 17e (Shutdown) + UDID: + + ๐Ÿ“ฑ [] iPhone Air (Shutdown) + UDID: + + ๐Ÿ“ฑ [] iPhone 17 (Booted) + UDID: + + ๐Ÿ“ฑ [] iPad Pro 13-inch (M5) (Shutdown) + UDID: + + ๐Ÿ“ฑ [] iPad Pro 11-inch (M5) (Shutdown) + UDID: + + ๐Ÿ“ฑ [] iPad mini (A17 Pro) (Shutdown) + UDID: + + ๐Ÿ“ฑ [] iPad Air 13-inch (M4) (Shutdown) + UDID: + + ๐Ÿ“ฑ [] iPad Air 11-inch (M4) (Shutdown) + UDID: + + ๐Ÿ“ฑ [] iPad (A16) (Shutdown) + UDID: +โœ… 11 simulators available (11 iOS). + +Hints + Use the simulator ID/UDID from above when required by other tools. + Save a default simulator with session-set-defaults { simulatorId: 'SIMULATOR_UDID' }. + Before running boot/build/run tools, set the desired simulator identifier in session defaults. diff --git a/src/snapshot-tests/__fixtures__/session-management/session-clear-defaults--success.txt b/src/snapshot-tests/__fixtures__/session-management/session-clear-defaults--success.txt new file mode 100644 index 00000000..7e2331d6 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/session-management/session-clear-defaults--success.txt @@ -0,0 +1,6 @@ + +โš™๏ธ Clear Defaults + + Profile: (default) + +โœ… Session defaults cleared (default profile) diff --git a/src/snapshot-tests/__fixtures__/session-management/session-set-defaults--success.txt b/src/snapshot-tests/__fixtures__/session-management/session-set-defaults--success.txt new file mode 100644 index 00000000..773d40cd --- /dev/null +++ b/src/snapshot-tests/__fixtures__/session-management/session-set-defaults--success.txt @@ -0,0 +1,24 @@ + +โš™๏ธ Set Defaults + + Workspace Path: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Scheme: CalculatorApp + Profile: (default) + +โœ… Session defaults updated (default profile) + โ”œ projectPath: (not set) + โ”œ workspacePath: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + โ”œ scheme: CalculatorApp + โ”œ configuration: (not set) + โ”œ simulatorName: (not set) + โ”œ simulatorId: (not set) + โ”œ simulatorPlatform: (not set) + โ”œ deviceId: (not set) + โ”œ useLatestOS: (not set) + โ”œ arch: (not set) + โ”œ suppressWarnings: (not set) + โ”œ derivedDataPath: (not set) + โ”œ preferXcodebuild: (not set) + โ”œ platform: (not set) + โ”œ bundleId: (not set) + โ”” env: (not set) diff --git a/src/snapshot-tests/__fixtures__/session-management/session-show-defaults--success.txt b/src/snapshot-tests/__fixtures__/session-management/session-show-defaults--success.txt new file mode 100644 index 00000000..d6372556 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/session-management/session-show-defaults--success.txt @@ -0,0 +1,38 @@ + +โš™๏ธ Show Defaults + +๐Ÿ“ (default) + โ”œ projectPath: (not set) + โ”œ workspacePath: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + โ”œ scheme: CalculatorApp + โ”œ configuration: (not set) + โ”œ simulatorName: (not set) + โ”œ simulatorId: (not set) + โ”œ simulatorPlatform: (not set) + โ”œ deviceId: (not set) + โ”œ useLatestOS: (not set) + โ”œ arch: (not set) + โ”œ suppressWarnings: (not set) + โ”œ derivedDataPath: (not set) + โ”œ preferXcodebuild: (not set) + โ”œ platform: (not set) + โ”œ bundleId: (not set) + โ”” env: (not set) + +๐Ÿ“ MyCustomProfile + โ”œ projectPath: (not set) + โ”œ workspacePath: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + โ”œ scheme: CalculatorApp + โ”œ configuration: (not set) + โ”œ simulatorName: (not set) + โ”œ simulatorId: (not set) + โ”œ simulatorPlatform: (not set) + โ”œ deviceId: (not set) + โ”œ useLatestOS: (not set) + โ”œ arch: (not set) + โ”œ suppressWarnings: (not set) + โ”œ derivedDataPath: (not set) + โ”œ preferXcodebuild: (not set) + โ”œ platform: (not set) + โ”œ bundleId: (not set) + โ”” env: (not set) diff --git a/src/snapshot-tests/__fixtures__/session-management/session-sync-xcode-defaults--success.txt b/src/snapshot-tests/__fixtures__/session-management/session-sync-xcode-defaults--success.txt new file mode 100644 index 00000000..4d87c486 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/session-management/session-sync-xcode-defaults--success.txt @@ -0,0 +1,6 @@ + +โš™๏ธ Sync Xcode Defaults + +โœ… Synced session defaults from Xcode IDE (default profile) + โ”œ scheme: CalculatorApp + โ”” bundleId: io.sentry.calculatorapp diff --git a/src/snapshot-tests/__fixtures__/session-management/session-use-defaults-profile--success.txt b/src/snapshot-tests/__fixtures__/session-management/session-use-defaults-profile--success.txt new file mode 100644 index 00000000..099bd99f --- /dev/null +++ b/src/snapshot-tests/__fixtures__/session-management/session-use-defaults-profile--success.txt @@ -0,0 +1,6 @@ + +โš™๏ธ Use Defaults Profile + + Current profile: (default) + +โœ… Activated profile (MyCustomProfile profile) diff --git a/src/snapshot-tests/__fixtures__/simulator-management/boot--error-invalid-id.txt b/src/snapshot-tests/__fixtures__/simulator-management/boot--error-invalid-id.txt new file mode 100644 index 00000000..a732897c --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/boot--error-invalid-id.txt @@ -0,0 +1,6 @@ + +๐Ÿ“ฑ Boot Simulator + + Simulator: + +โŒ Boot simulator operation failed: Invalid device or device pair: diff --git a/src/snapshot-tests/__fixtures__/simulator-management/boot--success.txt b/src/snapshot-tests/__fixtures__/simulator-management/boot--success.txt new file mode 100644 index 00000000..a0fd81d1 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/boot--success.txt @@ -0,0 +1,6 @@ + +๐Ÿ“ฑ Boot Simulator + + Simulator: + +โœ… Simulator booted successfully diff --git a/src/snapshot-tests/__fixtures__/simulator-management/erase--error-invalid-id.txt b/src/snapshot-tests/__fixtures__/simulator-management/erase--error-invalid-id.txt new file mode 100644 index 00000000..561f2bb2 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/erase--error-invalid-id.txt @@ -0,0 +1,6 @@ + +๐Ÿ—‘ Erase Simulator + + Simulator: + +โŒ Failed to erase simulator: Invalid device: diff --git a/src/snapshot-tests/__fixtures__/simulator-management/erase--success.txt b/src/snapshot-tests/__fixtures__/simulator-management/erase--success.txt new file mode 100644 index 00000000..f8055402 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/erase--success.txt @@ -0,0 +1,6 @@ + +๐Ÿ—‘ Erase Simulator + + Simulator: + +โœ… Simulators were erased successfully diff --git a/src/snapshot-tests/__fixtures__/simulator-management/list--success.txt b/src/snapshot-tests/__fixtures__/simulator-management/list--success.txt new file mode 100644 index 00000000..34419dff --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/list--success.txt @@ -0,0 +1,120 @@ + +๐Ÿ“ฑ List Simulators + +iOS Simulators: + + iOS 26.4: + + ๐Ÿ“ฑ [โœ—] iPhone 17 Pro (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone 17 Pro Max (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone 17e (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone Air (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ“] iPhone 17 (Booted) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Pro 13-inch (M5) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Pro 11-inch (M5) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad mini (A17 Pro) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Air 13-inch (M4) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Air 11-inch (M4) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad (A16) (Shutdown) + UDID: + + iOS 26.2: + + ๐Ÿ“ฑ [โœ—] iPhone 17 Pro (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone 17 Pro Max (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone Air (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone 17 (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone 16e (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Pro 13-inch (M5) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Pro 11-inch (M5) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad mini (A17 Pro) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad (A16) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Air 13-inch (M3) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Air 11-inch (M3) (Shutdown) + UDID: + +visionOS Simulators: + + xrOS 26.2: + + ๐Ÿฅฝ [โœ—] Apple Vision Pro (Shutdown) + UDID: + +watchOS Simulators: + + watchOS 26.2: + + โŒš๏ธ [โœ—] Apple Watch Series 11 (46mm) (Shutdown) + UDID: + + โŒš๏ธ [โœ—] Apple Watch Series 11 (42mm) (Shutdown) + UDID: + + โŒš๏ธ [โœ—] Apple Watch Ultra 3 (49mm) (Shutdown) + UDID: + + โŒš๏ธ [โœ—] Apple Watch SE 3 (44mm) (Shutdown) + UDID: + + โŒš๏ธ [โœ—] Apple Watch SE 3 (40mm) (Shutdown) + UDID: + +tvOS Simulators: + + tvOS 26.2: + + ๐Ÿ“บ [โœ—] Apple TV 4K (3rd generation) (Shutdown) + UDID: + + ๐Ÿ“บ [โœ—] Apple TV 4K (3rd generation) (at 1080p) (Shutdown) + UDID: + + ๐Ÿ“บ [โœ—] Apple TV (Shutdown) + UDID: + +โœ… 31 simulators available (22 iOS, 1 visionOS, 5 watchOS, 3 tvOS). + +Hints + Use the simulator ID/UDID from above when required by other tools. + Save a default simulator with session-set-defaults { simulatorId: 'SIMULATOR_UDID' }. + Before running boot/build/run tools, set the desired simulator identifier in session defaults. diff --git a/src/snapshot-tests/__fixtures__/simulator-management/open--success.txt b/src/snapshot-tests/__fixtures__/simulator-management/open--success.txt new file mode 100644 index 00000000..3402e373 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/open--success.txt @@ -0,0 +1,7 @@ + +๐Ÿ“ฑ Open Simulator + +โœ… Simulator opened successfully + +Next steps: +1. Boot a simulator for manual workflows: xcodebuildmcp simulator-management boot --simulator-id "UUID_FROM_LIST_SIMS" diff --git a/src/snapshot-tests/__fixtures__/simulator-management/reset-location--error-invalid-simulator.txt b/src/snapshot-tests/__fixtures__/simulator-management/reset-location--error-invalid-simulator.txt new file mode 100644 index 00000000..429bddde --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/reset-location--error-invalid-simulator.txt @@ -0,0 +1,6 @@ + +๐Ÿ“ Reset Location + + Simulator: + +โŒ Failed to reset simulator location: Invalid device: diff --git a/src/snapshot-tests/__fixtures__/simulator-management/reset-location--success.txt b/src/snapshot-tests/__fixtures__/simulator-management/reset-location--success.txt new file mode 100644 index 00000000..0626956e --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/reset-location--success.txt @@ -0,0 +1,6 @@ + +๐Ÿ“ Reset Location + + Simulator: + +โœ… Location successfully reset to default diff --git a/src/snapshot-tests/__fixtures__/simulator-management/set-appearance--error-invalid-simulator.txt b/src/snapshot-tests/__fixtures__/simulator-management/set-appearance--error-invalid-simulator.txt new file mode 100644 index 00000000..7dd258fc --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/set-appearance--error-invalid-simulator.txt @@ -0,0 +1,7 @@ + +๐ŸŽจ Set Appearance + + Simulator: + Mode: dark + +โŒ Failed to set simulator appearance: Invalid device: diff --git a/src/snapshot-tests/__fixtures__/simulator-management/set-appearance--success.txt b/src/snapshot-tests/__fixtures__/simulator-management/set-appearance--success.txt new file mode 100644 index 00000000..bd3a256c --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/set-appearance--success.txt @@ -0,0 +1,7 @@ + +๐ŸŽจ Set Appearance + + Simulator: + Mode: dark + +โœ… Appearance successfully set to dark mode diff --git a/src/snapshot-tests/__fixtures__/simulator-management/set-location--error-invalid-simulator.txt b/src/snapshot-tests/__fixtures__/simulator-management/set-location--error-invalid-simulator.txt new file mode 100644 index 00000000..a1d6aace --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/set-location--error-invalid-simulator.txt @@ -0,0 +1,7 @@ + +๐Ÿ“ Set Location + + Simulator: + Coordinates: 37.7749,-122.4194 + +โŒ Failed to set simulator location: Invalid device: diff --git a/src/snapshot-tests/__fixtures__/simulator-management/set-location--success.txt b/src/snapshot-tests/__fixtures__/simulator-management/set-location--success.txt new file mode 100644 index 00000000..783dc9f2 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/set-location--success.txt @@ -0,0 +1,7 @@ + +๐Ÿ“ Set Location + + Simulator: + Coordinates: 37.7749,-122.4194 + +โœ… Location set successfully diff --git a/src/snapshot-tests/__fixtures__/simulator-management/statusbar--error-invalid-simulator.txt b/src/snapshot-tests/__fixtures__/simulator-management/statusbar--error-invalid-simulator.txt new file mode 100644 index 00000000..0c00f0cd --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/statusbar--error-invalid-simulator.txt @@ -0,0 +1,7 @@ + +๐Ÿ“ฑ Statusbar + + Simulator: + Data Network: wifi + +โŒ Failed to set status bar: Invalid device: diff --git a/src/snapshot-tests/__fixtures__/simulator-management/statusbar--success.txt b/src/snapshot-tests/__fixtures__/simulator-management/statusbar--success.txt new file mode 100644 index 00000000..3d93eeaf --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator-management/statusbar--success.txt @@ -0,0 +1,7 @@ + +๐Ÿ“ฑ Statusbar + + Simulator: + Data Network: wifi + +โœ… Status bar data network set successfully diff --git a/src/snapshot-tests/__fixtures__/simulator/build--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/simulator/build--error-wrong-scheme.txt new file mode 100644 index 00000000..de358b6d --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/build--error-wrong-scheme.txt @@ -0,0 +1,16 @@ + +๐Ÿ”จ Build + + Scheme: NONEXISTENT + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS Simulator + Simulator: iPhone 17 + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +Errors (1): + + โœ— The workspace named "CalculatorApp" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the workspace. + +โŒ Build failed. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_sim__pid.log diff --git a/src/snapshot-tests/__fixtures__/simulator/build--success.txt b/src/snapshot-tests/__fixtures__/simulator/build--success.txt new file mode 100644 index 00000000..d48009f4 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/build--success.txt @@ -0,0 +1,15 @@ + +๐Ÿ”จ Build + + Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS Simulator + Simulator: iPhone 17 + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โœ… Build succeeded. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_sim__pid.log + +Next steps: +1. Get built app path in simulator derived data: xcodebuildmcp simulator get-app-path --simulator-name "iPhone 17" --scheme "CalculatorApp" --platform "iOS Simulator" diff --git a/src/snapshot-tests/__fixtures__/simulator/build-and-run--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/simulator/build-and-run--error-wrong-scheme.txt new file mode 100644 index 00000000..13a8d794 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/build-and-run--error-wrong-scheme.txt @@ -0,0 +1,16 @@ + +๐Ÿš€ Build & Run + + Scheme: NONEXISTENT + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS Simulator + Simulator: iPhone 17 + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +Errors (1): + + โœ— The workspace named "CalculatorApp" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the workspace. + +โŒ Build failed. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_sim__pid.log diff --git a/src/snapshot-tests/__fixtures__/simulator/build-and-run--success.txt b/src/snapshot-tests/__fixtures__/simulator/build-and-run--success.txt new file mode 100644 index 00000000..45af2222 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/build-and-run--success.txt @@ -0,0 +1,29 @@ + +๐Ÿš€ Build & Run + + Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS Simulator + Simulator: iPhone 17 + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โ„น๏ธ Resolving app path +โœ… Resolving app path +โ„น๏ธ Booting simulator +โœ… Booting simulator +โ„น๏ธ Installing app +โœ… Installing app +โ„น๏ธ Launching app + +โœ… Build succeeded. (โฑ๏ธ ) +โœ… Build & Run complete + โ”œ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app + โ”œ Bundle ID: io.sentry.calculatorapp + โ”œ Process ID: + โ”œ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_sim__pid.log + โ”œ Runtime Logs: /Library/Developer/XcodeBuildMCP/logs/io.sentry.calculatorapp__pid.log + โ”” OSLog: /Library/Developer/XcodeBuildMCP/logs/io.sentry.calculatorapp_oslog__pid.log + +Next steps: +1. Stop app in simulator: xcodebuildmcp simulator stop --simulator-id "" --bundle-id "io.sentry.calculatorapp" diff --git a/src/snapshot-tests/__fixtures__/simulator/get-app-path--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/simulator/get-app-path--error-wrong-scheme.txt new file mode 100644 index 00000000..202d727e --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/get-app-path--error-wrong-scheme.txt @@ -0,0 +1,14 @@ + +๐Ÿ” Get App Path + + Scheme: NONEXISTENT + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS Simulator + Simulator: iPhone 17 + +Errors (1): + + โœ— The workspace named "CalculatorApp" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the workspace. + +โŒ Failed to get app path diff --git a/src/snapshot-tests/__fixtures__/simulator/get-app-path--success.txt b/src/snapshot-tests/__fixtures__/simulator/get-app-path--success.txt new file mode 100644 index 00000000..24820d4d --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/get-app-path--success.txt @@ -0,0 +1,17 @@ + +๐Ÿ” Get App Path + + Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS Simulator + Simulator: iPhone 17 + +โœ… Get app path successful (โฑ๏ธ ) + โ”” App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app + +Next steps: +1. Get bundle ID: xcodebuildmcp device get-app-bundle-id --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app" +2. Boot simulator: xcodebuildmcp simulator-management boot --simulator-id "SIMULATOR_UUID" +3. Install app: xcodebuildmcp simulator install --simulator-id "SIMULATOR_UUID" --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app" +4. Launch app: xcodebuildmcp simulator launch-app --simulator-id "SIMULATOR_UUID" --bundle-id "BUNDLE_ID" diff --git a/src/snapshot-tests/__fixtures__/simulator/install--error-invalid-app.txt b/src/snapshot-tests/__fixtures__/simulator/install--error-invalid-app.txt new file mode 100644 index 00000000..ed46d6a9 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/install--error-invalid-app.txt @@ -0,0 +1,12 @@ + +๐Ÿ“ฆ Install App + + Simulator: + App Path: /NotAnApp.app + +โŒ Install app in simulator operation failed: An error was encountered processing the command (domain=IXErrorDomain, code=13): +Simulator device failed to install the application. +Missing bundle ID. +Underlying error (domain=IXErrorDomain, code=13): + Failed to get bundle ID from /NotAnApp.app + Missing bundle ID. diff --git a/src/snapshot-tests/__fixtures__/simulator/install--success.txt b/src/snapshot-tests/__fixtures__/simulator/install--success.txt new file mode 100644 index 00000000..ad875981 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/install--success.txt @@ -0,0 +1,11 @@ + +๐Ÿ“ฆ Install App + + Simulator: + App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app + +โœ… App installed successfully + +Next steps: +1. Open the Simulator app: xcodebuildmcp simulator-management open +2. Launch the app: xcodebuildmcp simulator launch-app --simulator-id "" --bundle-id "io.sentry.calculatorapp" diff --git a/src/snapshot-tests/__fixtures__/simulator/launch-app--error-not-installed.txt b/src/snapshot-tests/__fixtures__/simulator/launch-app--error-not-installed.txt new file mode 100644 index 00000000..ebdb9854 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/launch-app--error-not-installed.txt @@ -0,0 +1,7 @@ + +๐Ÿš€ Launch App + + Simulator: + Bundle ID: com.nonexistent.app + +โŒ App is not installed on the simulator. Please use install_app_sim before launching. Workflow: build -> install -> launch. diff --git a/src/snapshot-tests/__fixtures__/simulator/launch-app--success.txt b/src/snapshot-tests/__fixtures__/simulator/launch-app--success.txt new file mode 100644 index 00000000..cd4410ef --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/launch-app--success.txt @@ -0,0 +1,14 @@ + +๐Ÿš€ Launch App + + Simulator: + Bundle ID: io.sentry.calculatorapp + +โœ… App launched successfully + โ”œ Process ID: + โ”œ Runtime Logs: /Library/Developer/XcodeBuildMCP/logs/io.sentry.calculatorapp__pid.log + โ”” OSLog: /Library/Developer/XcodeBuildMCP/logs/io.sentry.calculatorapp_oslog__pid.log + +Next steps: +1. Open Simulator app to see it: xcodebuildmcp simulator-management open +2. Stop app in simulator: xcodebuildmcp simulator stop --simulator-id "" --bundle-id "io.sentry.calculatorapp" diff --git a/src/snapshot-tests/__fixtures__/simulator/list--success.txt b/src/snapshot-tests/__fixtures__/simulator/list--success.txt new file mode 100644 index 00000000..17bcb5e9 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/list--success.txt @@ -0,0 +1,52 @@ + +๐Ÿ“ฑ List Simulators + +iOS Simulators: + + iOS 26.4: + + ๐Ÿ“ฑ [โœ—] iPhone 17 Pro (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone 17 Pro Max (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone 17e (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPhone Air (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ“] iPhone 17 (Booted) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Pro 13-inch (M5) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Pro 11-inch (M5) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad mini (A17 Pro) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Air 13-inch (M4) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad Air 11-inch (M4) (Shutdown) + UDID: + + ๐Ÿ“ฑ [โœ—] iPad (A16) (Shutdown) + UDID: + +โœ… 11 simulators available (11 iOS). + +Hints + Use the simulator ID/UDID from above when required by other tools. + Save a default simulator with session-set-defaults { simulatorId: 'SIMULATOR_UDID' }. + Before running boot/build/run tools, set the desired simulator identifier in session defaults. + +Next steps: +1. Boot a simulator: xcodebuildmcp simulator-management boot --simulator-id "UUID_FROM_ABOVE" +2. Open the simulator UI: xcodebuildmcp simulator-management open +3. Build for simulator: xcodebuildmcp simulator build --scheme "YOUR_SCHEME" --simulator-id "UUID_FROM_ABOVE" +4. Get app path: xcodebuildmcp simulator get-app-path --scheme "YOUR_SCHEME" --platform "iOS Simulator" --simulator-id "UUID_FROM_ABOVE" diff --git a/src/snapshot-tests/__fixtures__/simulator/screenshot--error-invalid-simulator.txt b/src/snapshot-tests/__fixtures__/simulator/screenshot--error-invalid-simulator.txt new file mode 100644 index 00000000..66ce3224 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/screenshot--error-invalid-simulator.txt @@ -0,0 +1,6 @@ + +๐Ÿ“ท Screenshot + + Simulator: + +โŒ System error executing screenshot: Failed to capture screenshot: Invalid device: diff --git a/src/snapshot-tests/__fixtures__/simulator/screenshot--success.txt b/src/snapshot-tests/__fixtures__/simulator/screenshot--success.txt new file mode 100644 index 00000000..48c1e7b4 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/screenshot--success.txt @@ -0,0 +1,9 @@ + +๐Ÿ“ท Screenshot + + Simulator: + +โœ… Screenshot captured + โ”œ Screenshot: /var/folders/_t/2njffz894t57qpp76v1sw__h0000gn/T/screenshot_optimized_.jpg + โ”œ Format: image/jpeg + โ”” Size: 368x800px diff --git a/src/snapshot-tests/__fixtures__/simulator/stop--error-no-app.txt b/src/snapshot-tests/__fixtures__/simulator/stop--error-no-app.txt new file mode 100644 index 00000000..a6c6ba51 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/stop--error-no-app.txt @@ -0,0 +1,12 @@ + +๐Ÿ›‘ Stop App + + Simulator: + Bundle ID: com.nonexistent.app + +โŒ Stop app in simulator operation failed: An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=3): +Simulator device failed to terminate com.nonexistent.app. +found nothing to terminate +Underlying error (domain=NSPOSIXErrorDomain, code=3): + The request to terminate "com.nonexistent.app" failed. found nothing to terminate + found nothing to terminate diff --git a/src/snapshot-tests/__fixtures__/simulator/stop--success.txt b/src/snapshot-tests/__fixtures__/simulator/stop--success.txt new file mode 100644 index 00000000..855e0888 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/stop--success.txt @@ -0,0 +1,7 @@ + +๐Ÿ›‘ Stop App + + Simulator: + Bundle ID: io.sentry.calculatorapp + +โœ… App stopped successfully diff --git a/src/snapshot-tests/__fixtures__/simulator/test--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/simulator/test--error-wrong-scheme.txt new file mode 100644 index 00000000..50619e67 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/test--error-wrong-scheme.txt @@ -0,0 +1,15 @@ + +๐Ÿงช Test + + Scheme: NONEXISTENT + Configuration: Debug + Platform: iOS Simulator + Simulator: iPhone 17 + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +Errors (1): + + โœ— The workspace named "CalculatorApp" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the workspace. + +โŒ Test failed. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/test_sim__pid.log diff --git a/src/snapshot-tests/__fixtures__/simulator/test--failure.txt b/src/snapshot-tests/__fixtures__/simulator/test--failure.txt new file mode 100644 index 00000000..5222708d --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/test--failure.txt @@ -0,0 +1,21 @@ + +๐Ÿงช Test + + Scheme: CalculatorApp + Configuration: Debug + Platform: iOS Simulator + Simulator: iPhone 17 + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +CalculatorAppTests + โœ— testCalculatorServiceFailure: + - XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 + example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:52 + +IntentionalFailureTests + โœ— test: + - XCTAssertTrue failed - This test should fail to verify error reporting + example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift:286 + +โŒ 2 tests failed, 21 passed, 0 skipped (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/test_sim__pid.log diff --git a/src/snapshot-tests/__fixtures__/simulator/test--success.txt b/src/snapshot-tests/__fixtures__/simulator/test--success.txt new file mode 100644 index 00000000..32ec09c3 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/simulator/test--success.txt @@ -0,0 +1,11 @@ + +๐Ÿงช Test + + Scheme: CalculatorApp + Configuration: Debug + Platform: iOS Simulator + Simulator: iPhone 17 + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โœ… 1 test passed, 0 skipped (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/test_sim__pid.log diff --git a/src/snapshot-tests/__fixtures__/swift-package/build--error-bad-path.txt b/src/snapshot-tests/__fixtures__/swift-package/build--error-bad-path.txt new file mode 100644 index 00000000..75cdb71c --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/build--error-bad-path.txt @@ -0,0 +1,11 @@ + +๐Ÿ“ฆ Swift Package Build + + Package: /example_projects/NONEXISTENT + +Errors (1): + + โœ— chdir error: No such file or directory (2): /example_projects/NONEXISTENT + +โŒ Build failed. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_spm__pid.log diff --git a/src/snapshot-tests/__fixtures__/swift-package/build--success.txt b/src/snapshot-tests/__fixtures__/swift-package/build--success.txt new file mode 100644 index 00000000..8d1af4d4 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/build--success.txt @@ -0,0 +1,7 @@ + +๐Ÿ“ฆ Swift Package Build + + Package: /example_projects/spm + +โœ… Build succeeded. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_spm__pid.log diff --git a/src/snapshot-tests/__fixtures__/swift-package/clean--error-bad-path.txt b/src/snapshot-tests/__fixtures__/swift-package/clean--error-bad-path.txt new file mode 100644 index 00000000..ee0fa6bf --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/clean--error-bad-path.txt @@ -0,0 +1,6 @@ + +๐Ÿงน Swift Package Clean + + Package: /example_projects/NONEXISTENT + +โŒ Swift package clean failed: error: chdir error: No such file or directory (2): /example_projects/NONEXISTENT diff --git a/src/snapshot-tests/__fixtures__/swift-package/clean--success.txt b/src/snapshot-tests/__fixtures__/swift-package/clean--success.txt new file mode 100644 index 00000000..a0e316a0 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/clean--success.txt @@ -0,0 +1,6 @@ + +๐Ÿงน Swift Package Clean + + Package: /example_projects/spm + +โœ… Swift package cleaned successfully diff --git a/src/snapshot-tests/__fixtures__/swift-package/list--no-processes.txt b/src/snapshot-tests/__fixtures__/swift-package/list--no-processes.txt new file mode 100644 index 00000000..3d744593 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/list--no-processes.txt @@ -0,0 +1,4 @@ + +๐Ÿ“ฆ Swift Package Processes + +โ„น๏ธ No Swift Package processes currently running. diff --git a/src/snapshot-tests/__fixtures__/swift-package/list--success.txt b/src/snapshot-tests/__fixtures__/swift-package/list--success.txt new file mode 100644 index 00000000..be0969a1 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/list--success.txt @@ -0,0 +1,12 @@ + +๐Ÿ“ฆ Swift Package Processes + +Running Processes (2): + + ๐ŸŸข long-server + PID: | Uptime: + Package: /example_projects/spm + + ๐ŸŸข quick-task + PID: | Uptime: + Package: /example_projects/spm diff --git a/src/snapshot-tests/__fixtures__/swift-package/run--error-bad-executable.txt b/src/snapshot-tests/__fixtures__/swift-package/run--error-bad-executable.txt new file mode 100644 index 00000000..04928338 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/run--error-bad-executable.txt @@ -0,0 +1,11 @@ + +๐Ÿš€ Swift Package Run + + Package: /example_projects/spm + Executable: nonexistent-executable + +Errors (1): + + โœ— no executable product named 'nonexistent-executable' + +โŒ Build failed. (โฑ๏ธ ) diff --git a/src/snapshot-tests/__fixtures__/swift-package/run--success.txt b/src/snapshot-tests/__fixtures__/swift-package/run--success.txt new file mode 100644 index 00000000..8fee095e --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/run--success.txt @@ -0,0 +1,14 @@ + +๐Ÿš€ Swift Package Run + + Package: /example_projects/spm + Executable: spm + +โœ… Build succeeded. (โฑ๏ธ ) +โœ… Build & Run complete + โ”œ App Path: example_projects/spm/.build/arm64-apple-macosx/debug/spm + โ”œ Process ID: + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_spm__pid.log + +Output + Hello, world! diff --git a/src/snapshot-tests/__fixtures__/swift-package/stop--error-no-process.txt b/src/snapshot-tests/__fixtures__/swift-package/stop--error-no-process.txt new file mode 100644 index 00000000..4e59cb21 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/stop--error-no-process.txt @@ -0,0 +1,6 @@ + +๐Ÿ›‘ Swift Package Stop + + PID: + +โŒ No running process found with PID 999999. Use swift_package_list to check active processes. diff --git a/src/snapshot-tests/__fixtures__/swift-package/test--error-bad-path.txt b/src/snapshot-tests/__fixtures__/swift-package/test--error-bad-path.txt new file mode 100644 index 00000000..e6b6b48b --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/test--error-bad-path.txt @@ -0,0 +1,14 @@ + +๐Ÿงช Swift Package Test + + Scheme: NONEXISTENT + Configuration: debug + Platform: Swift Package + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +Errors (1): + + โœ— chdir error: No such file or directory (2): /example_projects/NONEXISTENT + +โŒ Test failed. (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/swift_package_test__pid.log diff --git a/src/snapshot-tests/__fixtures__/swift-package/test--failure.txt b/src/snapshot-tests/__fixtures__/swift-package/test--failure.txt new file mode 100644 index 00000000..6952f3fb --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/test--failure.txt @@ -0,0 +1,21 @@ + +๐Ÿงช Swift Package Test + + Scheme: spm + Configuration: debug + Platform: Swift Package + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +CalculatorAppTests + โœ— testCalculatorServiceFailure: + - XCTAssertEqual failed: ("0") is not equal to ("999") - This test should fail - display should be 0, not 999 + example_projects/spm/Tests/TestLibTests/SimpleTests.swift:49 + +(Unknown Suite) + โœ— test: + - Expectation failed: Bool(false) +Test failed + SimpleTests.swift:57 + +โŒ 2 tests failed, 5 passed, 0 skipped (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/swift_package_test__pid.log diff --git a/src/snapshot-tests/__fixtures__/swift-package/test--success.txt b/src/snapshot-tests/__fixtures__/swift-package/test--success.txt new file mode 100644 index 00000000..a5145e7a --- /dev/null +++ b/src/snapshot-tests/__fixtures__/swift-package/test--success.txt @@ -0,0 +1,10 @@ + +๐Ÿงช Swift Package Test + + Scheme: spm + Configuration: debug + Platform: Swift Package + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + +โœ… 1 test passed, 0 skipped (โฑ๏ธ ) + โ”” Build Logs: /Library/Developer/XcodeBuildMCP/logs/swift_package_test__pid.log diff --git a/src/snapshot-tests/__fixtures__/ui-automation/button--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/button--error-no-simulator.txt new file mode 100644 index 00000000..79190ab0 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/button--error-no-simulator.txt @@ -0,0 +1,9 @@ + +๐Ÿ‘† Button + + Simulator: + +โŒ Failed to press button 'home': axe command 'button' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/button--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/button--success.txt new file mode 100644 index 00000000..58a78296 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/button--success.txt @@ -0,0 +1,6 @@ + +๐Ÿ‘† Button + + Simulator: + +โœ… Hardware button 'home' pressed successfully. diff --git a/src/snapshot-tests/__fixtures__/ui-automation/gesture--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/gesture--error-no-simulator.txt new file mode 100644 index 00000000..3e391377 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/gesture--error-no-simulator.txt @@ -0,0 +1,9 @@ + +๐Ÿ‘† Gesture + + Simulator: + +โŒ Failed to execute gesture 'scroll-down': axe command 'gesture' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/gesture--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/gesture--success.txt new file mode 100644 index 00000000..f7cbf673 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/gesture--success.txt @@ -0,0 +1,6 @@ + +๐Ÿ‘† Gesture + + Simulator: + +โœ… Gesture 'scroll-down' executed successfully. diff --git a/src/snapshot-tests/__fixtures__/ui-automation/key-press--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/key-press--error-no-simulator.txt new file mode 100644 index 00000000..3be3e3c9 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/key-press--error-no-simulator.txt @@ -0,0 +1,9 @@ + +โŒจ๏ธ Key Press + + Simulator: + +โŒ Failed to simulate key press (code: 4): axe command 'key' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/key-press--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/key-press--success.txt new file mode 100644 index 00000000..c687f6b6 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/key-press--success.txt @@ -0,0 +1,6 @@ + +โŒจ๏ธ Key Press + + Simulator: + +โœ… Key press (code: 4) simulated successfully. diff --git a/src/snapshot-tests/__fixtures__/ui-automation/key-sequence--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/key-sequence--error-no-simulator.txt new file mode 100644 index 00000000..3b886b57 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/key-sequence--error-no-simulator.txt @@ -0,0 +1,9 @@ + +โŒจ๏ธ Key Sequence + + Simulator: + +โŒ Failed to execute key sequence: axe command 'key-sequence' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/key-sequence--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/key-sequence--success.txt new file mode 100644 index 00000000..6950454c --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/key-sequence--success.txt @@ -0,0 +1,6 @@ + +โŒจ๏ธ Key Sequence + + Simulator: + +โœ… Key sequence [4,5,6] executed successfully. diff --git a/src/snapshot-tests/__fixtures__/ui-automation/long-press--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/long-press--error-no-simulator.txt new file mode 100644 index 00000000..006987ff --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/long-press--error-no-simulator.txt @@ -0,0 +1,9 @@ + +๐Ÿ‘† Long Press + + Simulator: + +โŒ Failed to simulate long press at (100, 400): axe command 'touch' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/long-press--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/long-press--success.txt new file mode 100644 index 00000000..901c2463 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/long-press--success.txt @@ -0,0 +1,8 @@ + +๐Ÿ‘† Long Press + + Simulator: + +โœ… Long press at (100, 400) for 500ms simulated successfully. + +โš ๏ธ Warning: snapshot_ui has not been called yet. Consider using snapshot_ui for precise coordinates instead of guessing from screenshots. diff --git a/src/snapshot-tests/__fixtures__/ui-automation/snapshot-ui--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/snapshot-ui--error-no-simulator.txt new file mode 100644 index 00000000..f55fe099 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/snapshot-ui--error-no-simulator.txt @@ -0,0 +1,9 @@ + +๐Ÿ“ท Snapshot UI + + Simulator: + +โŒ Failed to get accessibility hierarchy: axe command 'describe-ui' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/snapshot-ui--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/snapshot-ui--success.txt new file mode 100644 index 00000000..feb40b50 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/snapshot-ui--success.txt @@ -0,0 +1,588 @@ + +๐Ÿ“ท Snapshot UI + + Simulator: + +โœ… Accessibility hierarchy retrieved successfully. + +Accessibility Hierarchy + ```json + [ + { + "AXFrame" : "{{0, 0}, {402, 874}}", + "AXUniqueId" : null, + "frame" : { + "y" : 0, + "x" : 0, + "width" : 402, + "height" : 874 + }, + "role_description" : "application", + "AXLabel" : "Calculator", + "content_required" : false, + "type" : "Application", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXApplication", + "children" : [ + { + "AXFrame" : "{{344, 250.5}, {34, 67}}", + "AXUniqueId" : null, + "frame" : { + "y" : 250.5, + "x" : 344, + "width" : 34, + "height" : 67 + }, + "role_description" : "text", + "AXLabel" : "0", + "content_required" : false, + "type" : "StaticText", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXStaticText", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{19.5, 357.5}, {82.666664123535156, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 357.5, + "x" : 19.5, + "width" : 82.7, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "C", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{113.16666412353516, 357.5}, {82.333335876464844, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 357.5, + "x" : 113.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "ยฑ", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{206.5, 357.5}, {82.666656494140625, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 357.5, + "x" : 206.5, + "width" : 82.7, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "%", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{300.16665649414062, 357.5}, {82.333343505859375, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 357.5, + "x" : 300.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "รท", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{19.5, 449.5}, {82.666664123535156, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 449.5, + "x" : 19.5, + "width" : 82.7, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "7", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{113.16666412353516, 449.5}, {82.333335876464844, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 449.5, + "x" : 113.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "8", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{206.5, 449.5}, {82.666656494140625, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 449.5, + "x" : 206.5, + "width" : 82.7, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "9", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{300.16665649414062, 449.5}, {82.333343505859375, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 449.5, + "x" : 300.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "ร—", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{19.5, 541.5}, {82.666664123535156, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 541.5, + "x" : 19.5, + "width" : 82.7, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "4", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{113.16666412353516, 541.5}, {82.333335876464844, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 541.5, + "x" : 113.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "5", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{206.5, 541.5}, {82.666656494140625, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 541.5, + "x" : 206.5, + "width" : 82.7, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "6", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{300.16665649414062, 541.5}, {82.333343505859375, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 541.5, + "x" : 300.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "-", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{19.5, 633.5}, {82.666664123535156, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 633.5, + "x" : 19.5, + "width" : 82.7, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "1", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{113.16666412353516, 633.5}, {82.333335876464844, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 633.5, + "x" : 113.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "2", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{206.5, 633.5}, {82.666656494140625, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 633.5, + "x" : 206.5, + "width" : 82.7, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "3", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{300.16665649414062, 633.5}, {82.333343505859375, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 633.5, + "x" : 300.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "+", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{113.16666412353516, 725.5}, {82.333335876464844, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 725.5, + "x" : 113.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "0", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{206.5, 725.5}, {82.666656494140625, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 725.5, + "x" : 206.5, + "width" : 82.7, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : ".", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + }, + { + "AXFrame" : "{{300.16665649414062, 725.5}, {82.333343505859375, 81}}", + "AXUniqueId" : null, + "frame" : { + "y" : 725.5, + "x" : 300.2, + "width" : 82.3, + "height" : 81 + }, + "role_description" : "button", + "AXLabel" : "=", + "content_required" : false, + "type" : "Button", + "title" : null, + "help" : null, + "custom_actions" : [ + + ], + "AXValue" : null, + "enabled" : true, + "role" : "AXButton", + "children" : [ + + ], + "subrole" : null, + "pid" : + } + ], + "subrole" : null, + "pid" : + } +] + ``` + +Tips + - Use frame coordinates for tap/swipe (center: x+width/2, y+height/2) + - If a debugger is attached, ensure the app is running (not stopped on breakpoints) + - Screenshots are for visual verification only + +Next steps: +1. Refresh after layout changes: xcodebuildmcp simulator snapshot-ui --simulator-id "" +2. Tap on element: xcodebuildmcp ui-automation tap --simulator-id "" --x "0" --y "0" +3. Take screenshot for verification: xcodebuildmcp simulator screenshot --simulator-id "" diff --git a/src/snapshot-tests/__fixtures__/ui-automation/swipe--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/swipe--error-no-simulator.txt new file mode 100644 index 00000000..c7d6bf08 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/swipe--error-no-simulator.txt @@ -0,0 +1,9 @@ + +๐Ÿ‘† Swipe + + Simulator: + +โŒ Failed to simulate swipe: axe command 'swipe' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/swipe--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/swipe--success.txt new file mode 100644 index 00000000..bae0cfea --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/swipe--success.txt @@ -0,0 +1,8 @@ + +๐Ÿ‘† Swipe + + Simulator: + +โœ… Swipe from (200, 400) to (200, 200) simulated successfully. + +โš ๏ธ Warning: snapshot_ui has not been called yet. Consider using snapshot_ui for precise coordinates instead of guessing from screenshots. diff --git a/src/snapshot-tests/__fixtures__/ui-automation/tap--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/tap--error-no-simulator.txt new file mode 100644 index 00000000..62a48049 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/tap--error-no-simulator.txt @@ -0,0 +1,9 @@ + +๐Ÿ‘† Tap + + Simulator: + +โŒ Failed to simulate tap at (100, 100): axe command 'tap' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/tap--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/tap--success.txt new file mode 100644 index 00000000..a3a27d96 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/tap--success.txt @@ -0,0 +1,8 @@ + +๐Ÿ‘† Tap + + Simulator: + +โœ… Tap at (100, 400) simulated successfully. + +โš ๏ธ Warning: snapshot_ui has not been called yet. Consider using snapshot_ui for precise coordinates instead of guessing from screenshots. diff --git a/src/snapshot-tests/__fixtures__/ui-automation/touch--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/touch--error-no-simulator.txt new file mode 100644 index 00000000..b9607fd0 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/touch--error-no-simulator.txt @@ -0,0 +1,9 @@ + +๐Ÿ‘† Touch + + Simulator: + +โŒ Failed to execute touch event: axe command 'touch' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/touch--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/touch--success.txt new file mode 100644 index 00000000..d29ac812 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/touch--success.txt @@ -0,0 +1,8 @@ + +๐Ÿ‘† Touch + + Simulator: + +โœ… Touch event (touch down+up) at (100, 400) executed successfully. + +โš ๏ธ Warning: snapshot_ui has not been called yet. Consider using snapshot_ui for precise coordinates instead of guessing from screenshots. diff --git a/src/snapshot-tests/__fixtures__/ui-automation/type-text--error-no-simulator.txt b/src/snapshot-tests/__fixtures__/ui-automation/type-text--error-no-simulator.txt new file mode 100644 index 00000000..7d305290 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/type-text--error-no-simulator.txt @@ -0,0 +1,9 @@ + +โŒจ๏ธ Type Text + + Simulator: + +โŒ Failed to simulate text typing: axe command 'type' failed. + +Details + Error: CLIError(errorDescription: "Simulator with UDID not found in set.") diff --git a/src/snapshot-tests/__fixtures__/ui-automation/type-text--success.txt b/src/snapshot-tests/__fixtures__/ui-automation/type-text--success.txt new file mode 100644 index 00000000..72a6ac50 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/ui-automation/type-text--success.txt @@ -0,0 +1,6 @@ + +โŒจ๏ธ Type Text + + Simulator: + +โœ… Text typing simulated successfully. diff --git a/src/snapshot-tests/__fixtures__/utilities/clean--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/utilities/clean--error-wrong-scheme.txt new file mode 100644 index 00000000..5bb17c0f --- /dev/null +++ b/src/snapshot-tests/__fixtures__/utilities/clean--error-wrong-scheme.txt @@ -0,0 +1,9 @@ + +๐Ÿงน Clean + + Scheme: NONEXISTENT + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS + +โŒ Clean failed: xcodebuild: error: The workspace named "CalculatorApp" does not contain a scheme named "NONEXISTENT". The "-list" option can be used to find the names of the schemes in the workspace. diff --git a/src/snapshot-tests/__fixtures__/utilities/clean--success.txt b/src/snapshot-tests/__fixtures__/utilities/clean--success.txt new file mode 100644 index 00000000..3e0c7025 --- /dev/null +++ b/src/snapshot-tests/__fixtures__/utilities/clean--success.txt @@ -0,0 +1,9 @@ + +๐Ÿงน Clean + + Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace + Configuration: Debug + Platform: iOS + +โœ… Clean successful diff --git a/src/snapshot-tests/__tests__/coverage.snapshot.test.ts b/src/snapshot-tests/__tests__/coverage.snapshot.test.ts new file mode 100644 index 00000000..5a471139 --- /dev/null +++ b/src/snapshot-tests/__tests__/coverage.snapshot.test.ts @@ -0,0 +1,107 @@ +import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'; +import { execSync } from 'node:child_process'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { createSnapshotHarness, ensureSimulatorBooted } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; + +const WORKSPACE = 'example_projects/iOS_Calculator/CalculatorApp.xcworkspace'; + +describe('coverage workflow', () => { + let harness: SnapshotHarness; + let xcresultPath: string; + let invalidXcresultPath: string; + + beforeAll(async () => { + vi.setConfig({ testTimeout: 120_000 }); + harness = await createSnapshotHarness(); + await ensureSimulatorBooted('iPhone 17'); + + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'coverage-snapshot-')); + xcresultPath = path.join(tmpDir, 'TestResults.xcresult'); + const derivedDataPath = path.join(tmpDir, 'DerivedData'); + + // Create a fake .xcresult directory that passes file-exists validation + // but makes xcrun xccov fail with a real executable error + invalidXcresultPath = path.join(tmpDir, 'invalid.xcresult'); + fs.mkdirSync(invalidXcresultPath); + + // Uses a fresh derived data path to ensure a fully clean build so coverage + // targets are deterministic. The Calculator example app has an intentionally + // failing test, so xcodebuild exits non-zero but the xcresult is still produced. + try { + execSync( + [ + 'xcodebuild test', + `-workspace ${WORKSPACE}`, + '-scheme CalculatorApp', + "-destination 'platform=iOS Simulator,name=iPhone 17'", + '-enableCodeCoverage YES', + `-derivedDataPath ${derivedDataPath}`, + `-resultBundlePath ${xcresultPath}`, + '-quiet', + ].join(' '), + { encoding: 'utf8', timeout: 120_000, stdio: 'pipe' }, + ); + } catch { + // Expected: test suite has an intentional failure + } + + if (!fs.existsSync(xcresultPath)) { + throw new Error(`Failed to generate xcresult at ${xcresultPath}`); + } + }, 120_000); + + afterAll(() => { + harness.cleanup(); + if (xcresultPath) { + const tmpDir = path.dirname(xcresultPath); + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }); + + describe('get-coverage-report', () => { + it('success', async () => { + // Filter to CalculatorAppTests which is always present and deterministic. + // The unfiltered report can include SPM framework targets non-deterministically. + const { text, isError } = await harness.invoke('coverage', 'get-coverage-report', { + xcresultPath, + target: 'CalculatorAppTests', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'get-coverage-report--success'); + }); + + it('error - invalid bundle', async () => { + const { text, isError } = await harness.invoke('coverage', 'get-coverage-report', { + xcresultPath: invalidXcresultPath, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'get-coverage-report--error-invalid-bundle'); + }); + }); + + describe('get-file-coverage', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('coverage', 'get-file-coverage', { + xcresultPath, + file: 'CalculatorService.swift', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'get-file-coverage--success'); + }); + + it('error - invalid bundle', async () => { + const { text, isError } = await harness.invoke('coverage', 'get-file-coverage', { + xcresultPath: invalidXcresultPath, + file: 'SomeFile.swift', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'get-file-coverage--error-invalid-bundle'); + }); + }); +}); diff --git a/src/snapshot-tests/__tests__/debugging.snapshot.test.ts b/src/snapshot-tests/__tests__/debugging.snapshot.test.ts new file mode 100644 index 00000000..6662354d --- /dev/null +++ b/src/snapshot-tests/__tests__/debugging.snapshot.test.ts @@ -0,0 +1,214 @@ +import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'; +import { execSync } from 'node:child_process'; +import { createSnapshotHarness, ensureSimulatorBooted } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; + +const WORKSPACE = 'example_projects/iOS_Calculator/CalculatorApp.xcworkspace'; +const BUNDLE_ID = 'io.sentry.calculatorapp'; + +describe('debugging workflow', () => { + let harness: SnapshotHarness; + + beforeAll(async () => { + harness = await createSnapshotHarness(); + }); + + afterAll(() => { + harness.cleanup(); + }); + + describe('error paths (no session)', () => { + it('continue - error no session', async () => { + const { text, isError } = await harness.invoke('debugging', 'continue', {}); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'continue--error-no-session'); + }, 30_000); + + it('detach - error no session', async () => { + const { text, isError } = await harness.invoke('debugging', 'detach', {}); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'detach--error-no-session'); + }, 30_000); + + it('stack - error no session', async () => { + const { text, isError } = await harness.invoke('debugging', 'stack', {}); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'stack--error-no-session'); + }, 30_000); + + it('variables - error no session', async () => { + const { text, isError } = await harness.invoke('debugging', 'variables', {}); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'variables--error-no-session'); + }, 30_000); + + it('add-breakpoint - error no session', async () => { + const { text, isError } = await harness.invoke('debugging', 'add-breakpoint', { + file: 'test.swift', + line: 1, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'add-breakpoint--error-no-session'); + }, 30_000); + + it('remove-breakpoint - error no session', async () => { + const { text, isError } = await harness.invoke('debugging', 'remove-breakpoint', { + breakpointId: 1, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'remove-breakpoint--error-no-session'); + }, 30_000); + + it('lldb-command - error no session', async () => { + const { text, isError } = await harness.invoke('debugging', 'lldb-command', { + command: 'bt', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'lldb-command--error-no-session'); + }, 30_000); + + it('attach - error no process', async () => { + const { text, isError } = await harness.invoke('debugging', 'attach', { + simulatorId: '00000000-0000-0000-0000-000000000000', + bundleId: 'com.nonexistent.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'attach--error-no-process'); + }, 30_000); + }); + + describe('happy path (live debugger session)', () => { + let simulatorUdid: string; + + beforeAll(async () => { + vi.setConfig({ testTimeout: 120_000 }); + simulatorUdid = await ensureSimulatorBooted('iPhone 17'); + + // Kill any stale lldb-dap processes to ensure a clean attach + try { + execSync('pkill -f lldb-dap', { stdio: 'pipe' }); + await new Promise((resolve) => setTimeout(resolve, 1000)); + } catch { + /* ignore if none running */ + } + + execSync( + [ + 'xcodebuild build', + `-workspace ${WORKSPACE}`, + '-scheme CalculatorApp', + `-destination 'platform=iOS Simulator,id=${simulatorUdid}'`, + '-quiet', + ].join(' '), + { encoding: 'utf8', timeout: 120_000, stdio: 'pipe' }, + ); + + execSync(`xcrun simctl launch --terminate-running-process ${simulatorUdid} ${BUNDLE_ID}`, { + encoding: 'utf8', + stdio: 'pipe', + }); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + }, 120_000); + + afterAll(async () => { + try { + await harness.invoke('debugging', 'detach', {}); + } catch { + // best-effort cleanup + } + }); + + it('attach - success', async () => { + const { text, isError } = await harness.invoke('debugging', 'attach', { + simulatorId: simulatorUdid, + bundleId: BUNDLE_ID, + continueOnAttach: false, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'attach--success'); + }, 30_000); + + it('pause via lldb', async () => { + // Attach with continueOnAttach: false now pauses execution for DAP sessions. + // Keep this step as a semantic checkpoint without issuing a second interrupt. + await new Promise((resolve) => setTimeout(resolve, 250)); + }, 30_000); + + it('stack - success', async () => { + const { text, isError } = await harness.invoke('debugging', 'stack', {}); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'stack--success'); + }, 30_000); + + it('variables - success', async () => { + const { text, isError } = await harness.invoke('debugging', 'variables', {}); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'variables--success'); + }, 30_000); + + it('add-breakpoint - success', async () => { + const { text, isError } = await harness.invoke('debugging', 'add-breakpoint', { + file: 'ContentView.swift', + line: 42, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'add-breakpoint--success'); + }, 30_000); + + it('continue - success', async () => { + const { text, isError } = await harness.invoke('debugging', 'continue', {}); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'continue--success'); + }, 30_000); + + it('lldb-command - success', async () => { + const { text, isError } = await harness.invoke('debugging', 'lldb-command', { + command: 'breakpoint list', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'lldb-command--success'); + }, 30_000); + + it('remove-breakpoint - success', async () => { + const { text, isError } = await harness.invoke('debugging', 'remove-breakpoint', { + breakpointId: 1, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'remove-breakpoint--success'); + }, 30_000); + + it('detach - success', async () => { + const { text, isError } = await harness.invoke('debugging', 'detach', {}); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'detach--success'); + }, 30_000); + + it('attach - success (continue on attach)', async () => { + execSync(`xcrun simctl launch --terminate-running-process ${simulatorUdid} ${BUNDLE_ID}`, { + encoding: 'utf8', + stdio: 'pipe', + }); + await new Promise((resolve) => setTimeout(resolve, 2000)); + + const { text, isError } = await harness.invoke('debugging', 'attach', { + simulatorId: simulatorUdid, + bundleId: BUNDLE_ID, + continueOnAttach: true, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'attach--success-continue'); + }, 30_000); + + it('detach after continue-on-attach', async () => { + const { isError } = await harness.invoke('debugging', 'detach', {}); + expect(isError).toBe(false); + }, 30_000); + }); +}); diff --git a/src/snapshot-tests/__tests__/device.snapshot.test.ts b/src/snapshot-tests/__tests__/device.snapshot.test.ts new file mode 100644 index 00000000..b9fa2359 --- /dev/null +++ b/src/snapshot-tests/__tests__/device.snapshot.test.ts @@ -0,0 +1,206 @@ +import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'; +import { execSync } from 'node:child_process'; +import { createSnapshotHarness } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; + +const WORKSPACE = 'example_projects/iOS_Calculator/CalculatorApp.xcworkspace'; +const BUNDLE_ID = 'io.sentry.calculatorapp'; +const DEVICE_ID = process.env.DEVICE_ID; + +describe('device workflow', () => { + let harness: SnapshotHarness; + + beforeAll(async () => { + vi.setConfig({ testTimeout: 120_000 }); + harness = await createSnapshotHarness(); + }, 120_000); + + afterAll(() => { + harness.cleanup(); + }); + + describe('list', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('device', 'list', {}); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'list--success'); + }); + }); + + describe('build', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('device', 'build', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'build--success'); + }); + + it('error - wrong scheme', async () => { + const { text, isError } = await harness.invoke('device', 'build', { + workspacePath: WORKSPACE, + scheme: 'NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'build--error-wrong-scheme'); + }); + }); + + describe('get-app-path', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('device', 'get-app-path', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'get-app-path--success'); + }); + + it('error - wrong scheme', async () => { + const { text, isError } = await harness.invoke('device', 'get-app-path', { + workspacePath: WORKSPACE, + scheme: 'NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'get-app-path--error-wrong-scheme'); + }); + }); + + describe('install', () => { + it('error - invalid app path', async () => { + const { text, isError } = await harness.invoke('device', 'install', { + deviceId: '00000000-0000-0000-0000-000000000000', + appPath: '/tmp/nonexistent.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'install--error-invalid-app'); + }); + }); + + describe('launch', () => { + it('error - invalid bundle', async () => { + const { text, isError } = await harness.invoke('device', 'launch', { + deviceId: '00000000-0000-0000-0000-000000000000', + bundleId: 'com.nonexistent.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'launch--error-invalid-bundle'); + }); + }); + + describe('stop', () => { + it('error - no app', async () => { + const { text, isError } = await harness.invoke('device', 'stop', { + deviceId: '00000000-0000-0000-0000-000000000000', + processId: 99999, + bundleId: 'com.nonexistent.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'stop--error-no-app'); + }); + }); + + describe.runIf(DEVICE_ID)('build-and-run (requires device)', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('device', 'build-and-run', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + deviceId: DEVICE_ID, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'build-and-run--success'); + }); + }); + + describe.runIf(DEVICE_ID)('install (requires device)', () => { + it('success', async () => { + const appPathOutput = execSync( + [ + 'xcodebuild -workspace', + WORKSPACE, + '-scheme CalculatorApp', + `-destination 'id=${DEVICE_ID}'`, + '-showBuildSettings', + ].join(' '), + { encoding: 'utf8', timeout: 30_000, stdio: 'pipe' }, + ); + const builtProductsDir = appPathOutput + .split('\n') + .find((l) => l.includes('BUILT_PRODUCTS_DIR')) + ?.split('=')[1] + ?.trim(); + const appPath = `${builtProductsDir}/CalculatorApp.app`; + + const { text, isError } = await harness.invoke('device', 'install', { + deviceId: DEVICE_ID, + appPath, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'install--success'); + }, 60_000); + }); + + describe.runIf(DEVICE_ID)('launch (requires device)', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('device', 'launch', { + deviceId: DEVICE_ID, + bundleId: BUNDLE_ID, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'launch--success'); + }, 60_000); + }); + + describe.runIf(DEVICE_ID)('stop (requires device)', () => { + it('success', async () => { + const tmpJson = `/tmp/devicectl-launch-${Date.now()}.json`; + execSync( + `xcrun devicectl device process launch --device ${DEVICE_ID} ${BUNDLE_ID} --json-output ${tmpJson}`, + { encoding: 'utf8', timeout: 30_000, stdio: 'pipe' }, + ); + const launchData = JSON.parse(require('fs').readFileSync(tmpJson, 'utf8')); + require('fs').unlinkSync(tmpJson); + const pid = launchData?.result?.process?.processIdentifier; + expect(pid).toBeGreaterThan(0); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + + const { text, isError } = await harness.invoke('device', 'stop', { + deviceId: DEVICE_ID, + processId: pid, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'stop--success'); + }, 60_000); + }); + + describe.runIf(DEVICE_ID)('test (requires device)', () => { + it('success - targeted passing test', async () => { + const { text, isError } = await harness.invoke('device', 'test', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + deviceId: DEVICE_ID, + extraArgs: ['-only-testing:CalculatorAppTests/CalculatorAppTests/testAddition'], + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'test--success'); + }, 300_000); + + it('failure - intentional test failure', async () => { + const { text, isError } = await harness.invoke('device', 'test', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + deviceId: DEVICE_ID, + }); + expect(isError).toBe(true); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'test--failure'); + }, 300_000); + }); +}); diff --git a/src/snapshot-tests/__tests__/macos.snapshot.test.ts b/src/snapshot-tests/__tests__/macos.snapshot.test.ts new file mode 100644 index 00000000..7bb773f7 --- /dev/null +++ b/src/snapshot-tests/__tests__/macos.snapshot.test.ts @@ -0,0 +1,222 @@ +import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { execSync } from 'node:child_process'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { createSnapshotHarness } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; +import { DERIVED_DATA_DIR } from '../../utils/log-paths.ts'; + +const PROJECT = 'example_projects/macOS/MCPTest.xcodeproj'; + +describe('macos workflow', () => { + let harness: SnapshotHarness; + let tmpDir: string; + let fakeAppPath: string; + let bundleIdAppPath: string; + + beforeAll(async () => { + harness = await createSnapshotHarness(); + + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'macos-snapshot-')); + + fakeAppPath = path.join(tmpDir, 'Fake.app'); + fs.mkdirSync(fakeAppPath); + + bundleIdAppPath = path.join(tmpDir, 'BundleTest.app'); + fs.mkdirSync(bundleIdAppPath); + const contentsDir = path.join(bundleIdAppPath, 'Contents'); + fs.mkdirSync(contentsDir); + fs.writeFileSync( + path.join(contentsDir, 'Info.plist'), + ` + + + + CFBundleIdentifier + com.test.snapshot-macos + +`, + ); + }); + + afterAll(() => { + harness.cleanup(); + if (tmpDir) { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }); + + describe('build', () => { + it('success', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'build', { + projectPath: PROJECT, + scheme: 'MCPTest', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'build--success'); + }); + + it('error - wrong scheme', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'build', { + projectPath: PROJECT, + scheme: 'NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'build--error-wrong-scheme'); + }); + }); + + describe('build-and-run', () => { + it('success', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'build-and-run', { + projectPath: PROJECT, + scheme: 'MCPTest', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'build-and-run--success'); + }); + + it('error - wrong scheme', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'build-and-run', { + projectPath: PROJECT, + scheme: 'NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'build-and-run--error-wrong-scheme'); + }); + }); + + describe('test', () => { + it('success', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'test', { + projectPath: PROJECT, + scheme: 'MCPTest', + extraArgs: [ + '-only-testing:MCPTestTests/MCPTestTests/appNameIsCorrect()', + '-only-testing:MCPTestTests/MCPTestsXCTests/testAppNameIsCorrect', + ], + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'test--success'); + }); + + it('failure - intentional test failure', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'test', { + projectPath: PROJECT, + scheme: 'MCPTest', + }); + expect(isError).toBe(true); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'test--failure'); + }); + + it('error - wrong scheme', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'test', { + projectPath: PROJECT, + scheme: 'NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'test--error-wrong-scheme'); + }); + }); + + describe('get-app-path', () => { + it('success', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'get-app-path', { + projectPath: PROJECT, + scheme: 'MCPTest', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'get-app-path--success'); + }); + + it('error - wrong scheme', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'get-app-path', { + projectPath: PROJECT, + scheme: 'NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'get-app-path--error-wrong-scheme'); + }); + }); + + describe('launch', () => { + it('success', { timeout: 120000 }, async () => { + const settingsOutput = execSync( + `xcodebuild -project ${PROJECT} -scheme MCPTest -showBuildSettings -derivedDataPath '${DERIVED_DATA_DIR}' 2>/dev/null`, + { encoding: 'utf8' }, + ); + const match = settingsOutput.match(/BUILT_PRODUCTS_DIR = (.+)/); + const appPath = `${match![1]!.trim()}/MCPTest.app`; + + const { text, isError } = await harness.invoke('macos', 'launch', { + appPath, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'launch--success'); + }); + + it('error - invalid app', { timeout: 120000 }, async () => { + const nonExistentApp = path.join(tmpDir, 'NonExistent.app'); + const { text, isError } = await harness.invoke('macos', 'launch', { + appPath: nonExistentApp, + }); + expect(isError).toBe(true); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'launch--error-invalid-app'); + }); + }); + + describe('stop', () => { + it('success', { timeout: 120000 }, async () => { + const settingsOutput = execSync( + `xcodebuild -project ${PROJECT} -scheme MCPTest -showBuildSettings -derivedDataPath '${DERIVED_DATA_DIR}' 2>/dev/null`, + { encoding: 'utf8' }, + ); + const match = settingsOutput.match(/BUILT_PRODUCTS_DIR = (.+)/); + const appPath = `${match![1]!.trim()}/MCPTest.app`; + + await harness.invoke('macos', 'launch', { appPath }); + + const { text, isError } = await harness.invoke('macos', 'stop', { + appName: 'MCPTest', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'stop--success'); + }); + + it('error - no app', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'stop', { + processId: 999999, + }); + expect(isError).toBe(true); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'stop--error-no-app'); + }); + }); + + describe('get-macos-bundle-id', () => { + it('success', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'get-macos-bundle-id', { + appPath: bundleIdAppPath, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'get-macos-bundle-id--success'); + }); + + it('error - missing app', { timeout: 120000 }, async () => { + const { text, isError } = await harness.invoke('macos', 'get-macos-bundle-id', { + appPath: '/nonexistent/path/Fake.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'get-macos-bundle-id--error-missing-app'); + }); + }); +}); diff --git a/src/snapshot-tests/__tests__/project-discovery.snapshot.test.ts b/src/snapshot-tests/__tests__/project-discovery.snapshot.test.ts new file mode 100644 index 00000000..bb3e9b77 --- /dev/null +++ b/src/snapshot-tests/__tests__/project-discovery.snapshot.test.ts @@ -0,0 +1,150 @@ +import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { createSnapshotHarness } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; + +const WORKSPACE = 'example_projects/iOS_Calculator/CalculatorApp.xcworkspace'; + +describe('project-discovery workflow', () => { + let harness: SnapshotHarness; + let tmpDir: string; + let bundleIdAppPath: string; + + beforeAll(async () => { + harness = await createSnapshotHarness(); + + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'proj-discovery-')); + bundleIdAppPath = path.join(tmpDir, 'BundleTest.app'); + fs.mkdirSync(bundleIdAppPath); + fs.writeFileSync( + path.join(bundleIdAppPath, 'Info.plist'), + ` + + + + CFBundleIdentifier + com.test.snapshot + +`, + ); + const contentsDir = path.join(bundleIdAppPath, 'Contents'); + fs.mkdirSync(contentsDir); + fs.writeFileSync( + path.join(contentsDir, 'Info.plist'), + ` + + + + CFBundleIdentifier + com.test.snapshot + +`, + ); + }); + + afterAll(() => { + harness.cleanup(); + if (tmpDir) { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }); + + describe('list-schemes', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'list-schemes', { + workspacePath: WORKSPACE, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'list-schemes--success'); + }); + + it('error - invalid workspace', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'list-schemes', { + workspacePath: '/nonexistent/path/Fake.xcworkspace', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'list-schemes--error-invalid-workspace'); + }); + }); + + describe('show-build-settings', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'show-build-settings', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'show-build-settings--success'); + }); + + it('error - wrong scheme', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'show-build-settings', { + workspacePath: WORKSPACE, + scheme: 'NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'show-build-settings--error-wrong-scheme'); + }); + }); + + describe('discover-projs', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'discover-projects', { + workspaceRoot: 'example_projects/iOS_Calculator', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'discover-projs--success'); + }); + + it('error - invalid root', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'discover-projects', { + workspaceRoot: '/nonexistent/path/Fake.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'discover-projs--error-invalid-root'); + }); + }); + + describe('get-app-bundle-id', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'get-app-bundle-id', { + appPath: bundleIdAppPath, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'get-app-bundle-id--success'); + }); + + it('error - missing app', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'get-app-bundle-id', { + appPath: '/nonexistent/path/Fake.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'get-app-bundle-id--error-missing-app'); + }); + }); + + describe('get-macos-bundle-id', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'get-macos-bundle-id', { + appPath: bundleIdAppPath, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'get-macos-bundle-id--success'); + }); + + it('error - missing app', async () => { + const { text, isError } = await harness.invoke('project-discovery', 'get-macos-bundle-id', { + appPath: '/nonexistent/path/Fake.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'get-macos-bundle-id--error-missing-app'); + }); + }); +}); diff --git a/src/snapshot-tests/__tests__/project-scaffolding.snapshot.test.ts b/src/snapshot-tests/__tests__/project-scaffolding.snapshot.test.ts new file mode 100644 index 00000000..235574fb --- /dev/null +++ b/src/snapshot-tests/__tests__/project-scaffolding.snapshot.test.ts @@ -0,0 +1,97 @@ +import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { mkdtempSync, rmSync, mkdirSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { createSnapshotHarness } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; + +function normalizeTmpDir(text: string, tmpDir: string): string { + const escaped = tmpDir.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + return text.replace(new RegExp(escaped, 'g'), ''); +} + +describe('project-scaffolding workflow', () => { + let harness: SnapshotHarness; + let tmpDir: string; + + beforeAll(async () => { + harness = await createSnapshotHarness(); + tmpDir = mkdtempSync(join(tmpdir(), 'xbm-scaffold-')); + }); + + afterAll(() => { + harness.cleanup(); + rmSync(tmpDir, { recursive: true, force: true }); + }); + + describe('scaffold-ios', () => { + it('success', async () => { + const outputPath = join(tmpDir, 'ios'); + const { text, isError } = await harness.invoke('project-scaffolding', 'scaffold-ios', { + projectName: 'SnapshotTestApp', + outputPath, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(normalizeTmpDir(text, tmpDir), __filename, 'scaffold-ios--success'); + }, 120000); + + it('error - existing project', async () => { + const outputPath = join(tmpDir, 'ios-existing'); + mkdirSync(outputPath, { recursive: true }); + + // Scaffold once to create the project files + await harness.invoke('project-scaffolding', 'scaffold-ios', { + projectName: 'SnapshotTestApp', + outputPath, + }); + + // Scaffold again into the same directory to trigger the error + const { text, isError } = await harness.invoke('project-scaffolding', 'scaffold-ios', { + projectName: 'SnapshotTestApp', + outputPath, + }); + expect(isError).toBe(true); + expectMatchesFixture( + normalizeTmpDir(text, tmpDir), + __filename, + 'scaffold-ios--error-existing', + ); + }, 120000); + }); + + describe('scaffold-macos', () => { + it('success', async () => { + const outputPath = join(tmpDir, 'macos'); + const { text, isError } = await harness.invoke('project-scaffolding', 'scaffold-macos', { + projectName: 'SnapshotTestMacApp', + outputPath, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(normalizeTmpDir(text, tmpDir), __filename, 'scaffold-macos--success'); + }, 120000); + + it('error - existing project', async () => { + const outputPath = join(tmpDir, 'macos-existing'); + mkdirSync(outputPath, { recursive: true }); + + await harness.invoke('project-scaffolding', 'scaffold-macos', { + projectName: 'SnapshotTestMacApp', + outputPath, + }); + + const { text, isError } = await harness.invoke('project-scaffolding', 'scaffold-macos', { + projectName: 'SnapshotTestMacApp', + outputPath, + }); + expect(isError).toBe(true); + expectMatchesFixture( + normalizeTmpDir(text, tmpDir), + __filename, + 'scaffold-macos--error-existing', + ); + }, 120000); + }); +}); diff --git a/src/snapshot-tests/__tests__/resources.snapshot.test.ts b/src/snapshot-tests/__tests__/resources.snapshot.test.ts new file mode 100644 index 00000000..dfc2ff69 --- /dev/null +++ b/src/snapshot-tests/__tests__/resources.snapshot.test.ts @@ -0,0 +1,44 @@ +import { describe, it, expect, beforeAll } from 'vitest'; +import { invokeResource } from '../resource-harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import { ensureSimulatorBooted, shutdownAllSimulatorsExcept } from '../harness.ts'; + +describe('resources', () => { + let simulatorUdid: string; + + beforeAll(async () => { + simulatorUdid = await ensureSimulatorBooted('iPhone 17'); + shutdownAllSimulatorsExcept([simulatorUdid]); + }, 30_000); + describe('devices', () => { + it('success', async () => { + const { text } = await invokeResource('devices'); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'devices--success'); + }); + }); + + describe('doctor', () => { + it('success', async () => { + const { text } = await invokeResource('doctor'); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'doctor--success'); + }); + }); + + describe('session-status', () => { + it('success', async () => { + const { text } = await invokeResource('session-status'); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'session-status--success'); + }); + }); + + describe('simulators', () => { + it('success', async () => { + const { text } = await invokeResource('simulators'); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'simulators--success'); + }); + }); +}); diff --git a/src/snapshot-tests/__tests__/session-management.snapshot.test.ts b/src/snapshot-tests/__tests__/session-management.snapshot.test.ts new file mode 100644 index 00000000..fdd18688 --- /dev/null +++ b/src/snapshot-tests/__tests__/session-management.snapshot.test.ts @@ -0,0 +1,83 @@ +import { describe, it, expect, beforeAll, beforeEach, afterAll } from 'vitest'; +import { createSnapshotHarness } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; +import { sessionStore } from '../../utils/session-store.ts'; + +const WORKSPACE = 'example_projects/iOS_Calculator/CalculatorApp.xcworkspace'; + +describe('session-management workflow', () => { + let harness: SnapshotHarness; + + function seedSessionDefaults(): void { + sessionStore.clearAll(); + sessionStore.setDefaults({ + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + }); + sessionStore.setActiveProfile('MyCustomProfile'); + sessionStore.setDefaults({ + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + }); + sessionStore.setActiveProfile(null); + } + + beforeAll(async () => { + harness = await createSnapshotHarness(); + }); + + beforeEach(() => { + seedSessionDefaults(); + }); + + afterAll(() => { + harness.cleanup(); + }); + + describe('session-set-defaults', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('session-management', 'set-defaults', { + scheme: 'CalculatorApp', + workspacePath: WORKSPACE, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'session-set-defaults--success'); + }); + }); + + describe('session-show-defaults', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('session-management', 'show-defaults', {}); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'session-show-defaults--success'); + }); + }); + + describe('session-clear-defaults', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('session-management', 'clear-defaults', {}); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'session-clear-defaults--success'); + }); + }); + + describe('session-use-defaults-profile', () => { + it('success', async () => { + const { text } = await harness.invoke('session-management', 'use-defaults-profile', { + profile: 'MyCustomProfile', + }); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'session-use-defaults-profile--success'); + }); + }); + + describe('session-sync-xcode-defaults', () => { + it('success', async () => { + const { text } = await harness.invoke('session-management', 'sync-xcode-defaults', {}); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'session-sync-xcode-defaults--success'); + }); + }); +}); diff --git a/src/snapshot-tests/__tests__/simulator-management.snapshot.test.ts b/src/snapshot-tests/__tests__/simulator-management.snapshot.test.ts new file mode 100644 index 00000000..ba02c182 --- /dev/null +++ b/src/snapshot-tests/__tests__/simulator-management.snapshot.test.ts @@ -0,0 +1,284 @@ +import { execSync } from 'node:child_process'; +import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { createSnapshotHarness, ensureSimulatorBooted } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; +import { list_simsLogic } from '../../mcp/tools/simulator/list_sims.ts'; +import { normalizeSnapshotOutput } from '../normalize.ts'; +import { loadManifest } from '../../core/manifest/load-manifest.ts'; +import { getEffectiveCliName } from '../../core/manifest/schema.ts'; +import { createToolCatalog } from '../../runtime/tool-catalog.ts'; +import { postProcessSession } from '../../runtime/tool-invoker.ts'; +import type { ToolDefinition } from '../../runtime/types.ts'; +import { createRenderSession } from '../../rendering/render.ts'; +import type { ToolHandlerContext } from '../../rendering/types.ts'; +import { handlerContextStorage } from '../../utils/typed-tool-factory.ts'; + +const FIXTURE_SIMCTL_TEXT = `== Devices == +-- iOS 26.4 -- + iPhone 17 Pro (11111111-1111-1111-1111-111111111111) (Shutdown) + iPhone 17 Pro Max (22222222-2222-2222-2222-222222222222) (Shutdown) + iPhone 17e (33333333-3333-3333-3333-333333333333) (Shutdown) + iPhone Air (44444444-4444-4444-4444-444444444444) (Shutdown) + iPhone 17 (55555555-5555-5555-5555-555555555555) (Booted) + iPad Pro 13-inch (M5) (66666666-6666-6666-6666-666666666666) (Shutdown) + iPad Pro 11-inch (M5) (77777777-7777-7777-7777-777777777777) (Shutdown) + iPad mini (A17 Pro) (88888888-8888-8888-8888-888888888888) (Shutdown) + iPad Air 13-inch (M4) (99999999-9999-9999-9999-999999999999) (Shutdown) + iPad Air 11-inch (M4) (AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA) (Shutdown) + iPad (A16) (BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB) (Shutdown) +-- iOS 26.2 -- + iPhone 17 Pro (CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC) (Shutdown) + iPhone 17 Pro Max (DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD) (Shutdown) + iPhone Air (EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE) (Shutdown) + iPhone 17 (FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF) (Shutdown) + iPhone 16e (12121212-1212-1212-1212-121212121212) (Shutdown) + iPad Pro 13-inch (M5) (13131313-1313-1313-1313-131313131313) (Shutdown) + iPad Pro 11-inch (M5) (14141414-1414-1414-1414-141414141414) (Shutdown) + iPad mini (A17 Pro) (15151515-1515-1515-1515-151515151515) (Shutdown) + iPad (A16) (16161616-1616-1616-1616-161616161616) (Shutdown) + iPad Air 13-inch (M3) (17171717-1717-1717-1717-171717171717) (Shutdown) + iPad Air 11-inch (M3) (18181818-1818-1818-1818-181818181818) (Shutdown) +-- xrOS 26.2 -- + Apple Vision Pro (19191919-1919-1919-1919-191919191919) (Shutdown) +-- watchOS 26.2 -- + Apple Watch Series 11 (46mm) (20202020-2020-2020-2020-202020202020) (Shutdown) + Apple Watch Series 11 (42mm) (21212121-2121-2121-2121-212121212121) (Shutdown) + Apple Watch Ultra 3 (49mm) (23232323-2323-2323-2323-232323232323) (Shutdown) + Apple Watch SE 3 (44mm) (24242424-2424-2424-2424-242424242424) (Shutdown) + Apple Watch SE 3 (40mm) (25252525-2525-2525-2525-252525252525) (Shutdown) +-- tvOS 26.2 -- + Apple TV 4K (3rd generation) (26262626-2626-2626-2626-262626262626) (Shutdown) + Apple TV 4K (3rd generation) (at 1080p) (27272727-2727-2727-2727-272727272727) (Shutdown) + Apple TV (28282828-2828-2828-2828-282828282828) (Shutdown)`; + +function buildCatalogForTool(toolId: string, handler: ToolDefinition['handler']) { + const manifest = loadManifest(); + const manifestEntry = manifest.tools.get(toolId); + if (!manifestEntry) { + throw new Error(`Tool manifest not found: ${toolId}`); + } + + const noopHandler: ToolDefinition['handler'] = async () => {}; + const allTools: ToolDefinition[] = Array.from(manifest.tools.values()).map((toolEntry) => ({ + id: toolEntry.id, + cliName: getEffectiveCliName(toolEntry), + mcpName: toolEntry.names.mcp, + workflow: '', + description: toolEntry.description, + nextStepTemplates: toolEntry.nextSteps, + mcpSchema: {} as ToolDefinition['mcpSchema'], + cliSchema: {} as ToolDefinition['cliSchema'], + stateful: toolEntry.routing?.stateful ?? false, + handler: toolEntry.id === manifestEntry.id ? handler : noopHandler, + })); + + const catalog = createToolCatalog(allTools); + const tool = catalog.getByToolId(toolId); + if (!tool) { + throw new Error(`Tool catalog entry not found: ${toolId}`); + } + + return { tool, catalog }; +} + +async function invokeDeterministicSimulatorList(): Promise<{ text: string; isError: boolean }> { + const executor = async (command: string[]) => { + if (command.includes('--json')) { + return { + success: true, + output: 'not-json', + error: undefined, + process: { pid: 0 } as never, + }; + } + + return { + success: true, + output: FIXTURE_SIMCTL_TEXT, + error: undefined, + process: { pid: 0 } as never, + }; + }; + + const session = createRenderSession('text'); + const ctx: ToolHandlerContext = { + emit: (event) => session.emit(event), + attach: () => {}, + }; + await handlerContextStorage.run(ctx, () => list_simsLogic({ enabled: true }, executor)); + + const { tool, catalog } = buildCatalogForTool( + 'list_sims', + list_simsLogic as unknown as ToolDefinition['handler'], + ); + postProcessSession({ + tool, + session, + ctx, + catalog, + runtime: 'mcp', + applyTemplateNextSteps: false, + }); + + const rawText = session.finalize() + '\n'; + const text = normalizeSnapshotOutput(rawText).replace( + /\n(โœ… \d+ simulators available)/, + '\n\n$1', + ); + + return { + text, + isError: session.isError(), + }; +} + +describe('simulator-management workflow', () => { + let harness: SnapshotHarness; + let simulatorUdid: string; + + beforeAll(async () => { + simulatorUdid = await ensureSimulatorBooted('iPhone 17'); + harness = await createSnapshotHarness(); + }); + + afterAll(() => { + harness.cleanup(); + }); + + describe('list', () => { + it('success', async () => { + const { text, isError } = await invokeDeterministicSimulatorList(); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'list--success'); + }); + }); + + describe('boot', () => { + it('error - invalid id', async () => { + const { text } = await harness.invoke('simulator-management', 'boot', { + simulatorId: '00000000-0000-0000-0000-000000000000', + }); + expectMatchesFixture(text, __filename, 'boot--error-invalid-id'); + }); + }); + + describe('open', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'open', {}); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'open--success'); + }); + }); + + describe('set-appearance', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'set-appearance', { + simulatorId: simulatorUdid, + mode: 'dark', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'set-appearance--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'set-appearance', { + simulatorId: '00000000-0000-0000-0000-000000000000', + mode: 'dark', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'set-appearance--error-invalid-simulator'); + }); + }); + + describe('set-location', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'set-location', { + simulatorId: simulatorUdid, + latitude: 37.7749, + longitude: -122.4194, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'set-location--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'set-location', { + simulatorId: '00000000-0000-0000-0000-000000000000', + latitude: 37.7749, + longitude: -122.4194, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'set-location--error-invalid-simulator'); + }); + }); + + describe('reset-location', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'reset-location', { + simulatorId: simulatorUdid, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'reset-location--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'reset-location', { + simulatorId: '00000000-0000-0000-0000-000000000000', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'reset-location--error-invalid-simulator'); + }); + }); + + describe('statusbar', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'statusbar', { + simulatorId: simulatorUdid, + dataNetwork: 'wifi', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'statusbar--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'statusbar', { + simulatorId: '00000000-0000-0000-0000-000000000000', + dataNetwork: 'wifi', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'statusbar--error-invalid-simulator'); + }); + }); + + describe('erase', () => { + it('error - invalid id', async () => { + const { text, isError } = await harness.invoke('simulator-management', 'erase', { + simulatorId: '00000000-0000-0000-0000-000000000000', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'erase--error-invalid-id'); + }); + + it('success', async () => { + const throwawayUdid = execSync('xcrun simctl create "SnapshotTestThrowaway" "iPhone 16"', { + encoding: 'utf8', + }).trim(); + + try { + const { text, isError } = await harness.invoke('simulator-management', 'erase', { + simulatorId: throwawayUdid, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'erase--success'); + } finally { + try { + execSync(`xcrun simctl delete ${throwawayUdid}`); + } catch { + // Simulator may already be deleted + } + } + }, 60_000); + }); +}); diff --git a/src/snapshot-tests/__tests__/simulator.snapshot.test.ts b/src/snapshot-tests/__tests__/simulator.snapshot.test.ts new file mode 100644 index 00000000..6ddce2e7 --- /dev/null +++ b/src/snapshot-tests/__tests__/simulator.snapshot.test.ts @@ -0,0 +1,245 @@ +import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'; +import { execSync } from 'node:child_process'; +import { + createSnapshotHarness, + ensureSimulatorBooted, + shutdownAllSimulatorsExcept, +} from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; +import { DERIVED_DATA_DIR } from '../../utils/log-paths.ts'; + +const WORKSPACE = 'example_projects/iOS_Calculator/CalculatorApp.xcworkspace'; + +describe('simulator workflow', () => { + let harness: SnapshotHarness; + let simulatorUdid: string; + + beforeAll(async () => { + vi.setConfig({ testTimeout: 120_000 }); + harness = await createSnapshotHarness(); + simulatorUdid = await ensureSimulatorBooted('iPhone 17'); + }, 120_000); + + afterAll(() => { + harness.cleanup(); + }); + + describe('build', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator', 'build', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + simulatorName: 'iPhone 17', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'build--success'); + }, 120_000); + + it('error - wrong scheme', async () => { + const { text, isError } = await harness.invoke('simulator', 'build', { + workspacePath: WORKSPACE, + scheme: 'NONEXISTENT', + simulatorName: 'iPhone 17', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'build--error-wrong-scheme'); + }, 120_000); + }); + + describe('build-and-run', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator', 'build-and-run', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + simulatorName: 'iPhone 17', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'build-and-run--success'); + }, 120_000); + + it('error - wrong scheme', async () => { + const { text, isError } = await harness.invoke('simulator', 'build-and-run', { + workspacePath: WORKSPACE, + scheme: 'NONEXISTENT', + simulatorName: 'iPhone 17', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'build-and-run--error-wrong-scheme'); + }, 120_000); + }); + + describe('test', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator', 'test', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + simulatorName: 'iPhone 17', + extraArgs: ['-only-testing:CalculatorAppTests/CalculatorAppTests/testAddition'], + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'test--success'); + }, 120_000); + + it('failure - intentional test failure', async () => { + const { text, isError } = await harness.invoke('simulator', 'test', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + simulatorName: 'iPhone 17', + }); + expect(isError).toBe(true); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'test--failure'); + }, 120_000); + + it('error - wrong scheme', async () => { + const { text, isError } = await harness.invoke('simulator', 'test', { + workspacePath: WORKSPACE, + scheme: 'NONEXISTENT', + simulatorName: 'iPhone 17', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'test--error-wrong-scheme'); + }, 120_000); + }); + + describe('get-app-path', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator', 'get-app-path', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + platform: 'iOS Simulator', + simulatorName: 'iPhone 17', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'get-app-path--success'); + }, 120_000); + + it('error - wrong scheme', async () => { + const { text, isError } = await harness.invoke('simulator', 'get-app-path', { + workspacePath: WORKSPACE, + scheme: 'NONEXISTENT', + platform: 'iOS Simulator', + simulatorName: 'iPhone 17', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'get-app-path--error-wrong-scheme'); + }, 120_000); + }); + + describe('list', () => { + it('success', async () => { + shutdownAllSimulatorsExcept([simulatorUdid]); + const { text, isError } = await harness.invoke('simulator', 'list', {}); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'list--success'); + }, 120_000); + }); + + describe('install', () => { + it('success', async () => { + const settingsOutput = execSync( + `xcodebuild -workspace ${WORKSPACE} -scheme CalculatorApp -showBuildSettings -derivedDataPath '${DERIVED_DATA_DIR}' -destination 'platform=iOS Simulator,name=iPhone 17' 2>/dev/null`, + { encoding: 'utf8' }, + ); + const match = settingsOutput.match(/BUILT_PRODUCTS_DIR = (.+)/); + const appPath = `${match![1]!.trim()}/CalculatorApp.app`; + + const { text, isError } = await harness.invoke('simulator', 'install', { + simulatorId: simulatorUdid, + appPath, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'install--success'); + }, 120_000); + + it('error - invalid app', async () => { + const fs = await import('node:fs'); + const os = await import('node:os'); + const path = await import('node:path'); + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'sim-install-')); + const fakeApp = path.join(tmpDir, 'NotAnApp.app'); + fs.mkdirSync(fakeApp); + try { + const { text } = await harness.invoke('simulator', 'install', { + simulatorId: simulatorUdid, + appPath: fakeApp, + }); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'install--error-invalid-app'); + } finally { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }, 120_000); + }); + + describe('launch-app', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator', 'launch-app', { + simulatorId: simulatorUdid, + bundleId: 'io.sentry.calculatorapp', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'launch-app--success'); + }, 120_000); + + it('error - not installed', async () => { + const { text, isError } = await harness.invoke('simulator', 'launch-app', { + simulatorId: simulatorUdid, + bundleId: 'com.nonexistent.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'launch-app--error-not-installed'); + }, 120_000); + }); + + describe('screenshot', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('simulator', 'screenshot', { + simulatorId: simulatorUdid, + returnFormat: 'path', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'screenshot--success'); + }, 120_000); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('simulator', 'screenshot', { + simulatorId: '00000000-0000-0000-0000-000000000000', + returnFormat: 'path', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'screenshot--error-invalid-simulator'); + }, 120_000); + }); + + describe('stop', () => { + it('success', async () => { + await harness.invoke('simulator', 'launch-app', { + simulatorId: simulatorUdid, + bundleId: 'io.sentry.calculatorapp', + }); + + const { text, isError } = await harness.invoke('simulator', 'stop', { + simulatorId: simulatorUdid, + bundleId: 'io.sentry.calculatorapp', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'stop--success'); + }, 120_000); + + it('error - no app', async () => { + const { text, isError } = await harness.invoke('simulator', 'stop', { + simulatorId: simulatorUdid, + bundleId: 'com.nonexistent.app', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'stop--error-no-app'); + }, 120_000); + }); +}); diff --git a/src/snapshot-tests/__tests__/swift-package.snapshot.test.ts b/src/snapshot-tests/__tests__/swift-package.snapshot.test.ts new file mode 100644 index 00000000..4d5f3646 --- /dev/null +++ b/src/snapshot-tests/__tests__/swift-package.snapshot.test.ts @@ -0,0 +1,152 @@ +import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'; +import path from 'node:path'; +import { createSnapshotHarness } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; +import { addProcess, removeProcess } from '../../mcp/tools/swift-package/active-processes.ts'; + +const PACKAGE_PATH = 'example_projects/spm'; + +describe('swift-package workflow', () => { + let harness: SnapshotHarness; + + beforeAll(async () => { + vi.setConfig({ testTimeout: 120_000 }); + harness = await createSnapshotHarness(); + }, 120_000); + + afterAll(() => { + harness.cleanup(); + }); + + describe('build', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('swift-package', 'build', { + packagePath: PACKAGE_PATH, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'build--success'); + }, 120_000); + + it('error - bad path', async () => { + const { text, isError } = await harness.invoke('swift-package', 'build', { + packagePath: 'example_projects/NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'build--error-bad-path'); + }); + }); + + describe('test', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('swift-package', 'test', { + packagePath: PACKAGE_PATH, + filter: 'basicTruthTest', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'test--success'); + }, 120_000); + + it('failure - intentional test failure', async () => { + const { text, isError } = await harness.invoke('swift-package', 'test', { + packagePath: PACKAGE_PATH, + }); + expect(isError).toBe(true); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'test--failure'); + }, 120_000); + + it('error - bad path', async () => { + const { text, isError } = await harness.invoke('swift-package', 'test', { + packagePath: 'example_projects/NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'test--error-bad-path'); + }); + }); + + describe('clean', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('swift-package', 'clean', { + packagePath: PACKAGE_PATH, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'clean--success'); + }); + + it('error - bad path', async () => { + const { text, isError } = await harness.invoke('swift-package', 'clean', { + packagePath: 'example_projects/NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'clean--error-bad-path'); + }); + }); + + describe('run', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('swift-package', 'run', { + packagePath: PACKAGE_PATH, + executableName: 'spm', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(0); + expectMatchesFixture(text, __filename, 'run--success'); + }, 120_000); + + it('error - bad executable', async () => { + const { text, isError } = await harness.invoke('swift-package', 'run', { + packagePath: PACKAGE_PATH, + executableName: 'nonexistent-executable', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'run--error-bad-executable'); + }, 120_000); + }); + + describe('list', () => { + it('success', async () => { + const resolvedPkg = path.resolve('example_projects/spm'); + const mockNow = Date.now(); + const mockProcess = { + kill: () => {}, + on: () => {}, + pid: 12345, + }; + + addProcess(12345, { + process: mockProcess, + startedAt: new Date(mockNow - 10_000), + executableName: 'long-server', + packagePath: resolvedPkg, + }); + addProcess(12346, { + process: { ...mockProcess, pid: 12346 }, + startedAt: new Date(mockNow - 3_000), + executableName: 'quick-task', + packagePath: resolvedPkg, + }); + + try { + const { text, isError } = await harness.invoke('swift-package', 'list', {}); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'list--success'); + } finally { + removeProcess(12345); + removeProcess(12346); + } + }); + }); + + describe('stop', () => { + it('error - no process', async () => { + const { text, isError } = await harness.invoke('swift-package', 'stop', { + pid: 999999, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'stop--error-no-process'); + }); + }); +}); diff --git a/src/snapshot-tests/__tests__/ui-automation.snapshot.test.ts b/src/snapshot-tests/__tests__/ui-automation.snapshot.test.ts new file mode 100644 index 00000000..97f3a8fe --- /dev/null +++ b/src/snapshot-tests/__tests__/ui-automation.snapshot.test.ts @@ -0,0 +1,254 @@ +import { execSync } from 'node:child_process'; +import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'; +import { createSnapshotHarness, ensureSimulatorBooted } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; + +const WORKSPACE = 'example_projects/iOS_Calculator/CalculatorApp.xcworkspace'; +const BUNDLE_ID = 'io.sentry.calculatorapp'; +const INVALID_SIMULATOR_ID = '00000000-0000-0000-0000-000000000000'; + +describe('ui-automation workflow', () => { + let harness: SnapshotHarness; + let simulatorUdid: string; + + beforeAll(async () => { + vi.setConfig({ testTimeout: 120_000 }); + simulatorUdid = await ensureSimulatorBooted('iPhone 17'); + harness = await createSnapshotHarness(); + + await harness.invoke('simulator', 'build-and-run', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + simulatorName: 'iPhone 17', + }); + + try { + execSync(`xcrun simctl launch ${simulatorUdid} ${BUNDLE_ID}`, { encoding: 'utf8' }); + } catch { + // App may already be running + } + await new Promise((resolve) => setTimeout(resolve, 3000)); + }); + + afterAll(() => { + harness.cleanup(); + }); + + describe('snapshot-ui', () => { + it('success - calculator app', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'snapshot-ui', { + simulatorId: simulatorUdid, + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(100); + expectMatchesFixture(text, __filename, 'snapshot-ui--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'snapshot-ui', { + simulatorId: INVALID_SIMULATOR_ID, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'snapshot-ui--error-no-simulator'); + }); + }); + + describe('tap', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'tap', { + simulatorId: simulatorUdid, + x: 100, + y: 400, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'tap--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'tap', { + simulatorId: INVALID_SIMULATOR_ID, + x: 100, + y: 100, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'tap--error-no-simulator'); + }); + }); + + describe('touch', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'touch', { + simulatorId: simulatorUdid, + x: 100, + y: 400, + down: true, + up: true, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'touch--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'touch', { + simulatorId: INVALID_SIMULATOR_ID, + x: 100, + y: 400, + down: true, + up: true, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'touch--error-no-simulator'); + }); + }); + + describe('long-press', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'long-press', { + simulatorId: simulatorUdid, + x: 100, + y: 400, + duration: 500, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'long-press--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'long-press', { + simulatorId: INVALID_SIMULATOR_ID, + x: 100, + y: 400, + duration: 500, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'long-press--error-no-simulator'); + }); + }); + + describe('swipe', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'swipe', { + simulatorId: simulatorUdid, + x1: 200, + y1: 400, + x2: 200, + y2: 200, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'swipe--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'swipe', { + simulatorId: INVALID_SIMULATOR_ID, + x1: 200, + y1: 400, + x2: 200, + y2: 200, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'swipe--error-no-simulator'); + }); + }); + + describe('gesture', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'gesture', { + simulatorId: simulatorUdid, + preset: 'scroll-down', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'gesture--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'gesture', { + simulatorId: INVALID_SIMULATOR_ID, + preset: 'scroll-down', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'gesture--error-no-simulator'); + }); + }); + + describe('button', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'button', { + simulatorId: simulatorUdid, + buttonType: 'home', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'button--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'button', { + simulatorId: INVALID_SIMULATOR_ID, + buttonType: 'home', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'button--error-no-simulator'); + }); + }); + + describe('key-press', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'key-press', { + simulatorId: simulatorUdid, + keyCode: 4, + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'key-press--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'key-press', { + simulatorId: INVALID_SIMULATOR_ID, + keyCode: 4, + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'key-press--error-no-simulator'); + }); + }); + + describe('key-sequence', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'key-sequence', { + simulatorId: simulatorUdid, + keyCodes: [4, 5, 6], + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'key-sequence--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'key-sequence', { + simulatorId: INVALID_SIMULATOR_ID, + keyCodes: [4, 5, 6], + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'key-sequence--error-no-simulator'); + }); + }); + + describe('type-text', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'type-text', { + simulatorId: simulatorUdid, + text: 'hello', + }); + expect(isError).toBe(false); + expectMatchesFixture(text, __filename, 'type-text--success'); + }); + + it('error - invalid simulator', async () => { + const { text, isError } = await harness.invoke('ui-automation', 'type-text', { + simulatorId: INVALID_SIMULATOR_ID, + text: 'hello', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'type-text--error-no-simulator'); + }); + }); +}); diff --git a/src/snapshot-tests/__tests__/utilities.snapshot.test.ts b/src/snapshot-tests/__tests__/utilities.snapshot.test.ts new file mode 100644 index 00000000..e05b5e21 --- /dev/null +++ b/src/snapshot-tests/__tests__/utilities.snapshot.test.ts @@ -0,0 +1,39 @@ +import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { createSnapshotHarness } from '../harness.ts'; +import { expectMatchesFixture } from '../fixture-io.ts'; +import type { SnapshotHarness } from '../harness.ts'; + +const WORKSPACE = 'example_projects/iOS_Calculator/CalculatorApp.xcworkspace'; + +describe('utilities workflow', () => { + let harness: SnapshotHarness; + + beforeAll(async () => { + harness = await createSnapshotHarness(); + }); + + afterAll(() => { + harness.cleanup(); + }); + + describe('clean', () => { + it('success', async () => { + const { text, isError } = await harness.invoke('utilities', 'clean', { + workspacePath: WORKSPACE, + scheme: 'CalculatorApp', + }); + expect(isError).toBe(false); + expect(text.length).toBeGreaterThan(10); + expectMatchesFixture(text, __filename, 'clean--success'); + }, 120000); + + it('error - wrong scheme', async () => { + const { text, isError } = await harness.invoke('utilities', 'clean', { + workspacePath: WORKSPACE, + scheme: 'NONEXISTENT', + }); + expect(isError).toBe(true); + expectMatchesFixture(text, __filename, 'clean--error-wrong-scheme'); + }, 120000); + }); +}); diff --git a/src/snapshot-tests/capture-debug-output.mjs b/src/snapshot-tests/capture-debug-output.mjs new file mode 100644 index 00000000..0a40c1cb --- /dev/null +++ b/src/snapshot-tests/capture-debug-output.mjs @@ -0,0 +1,51 @@ +/** + * Script to capture actual output from debugging tools for fixture comparison. + * Run with: node --experimental-vm-modules src/snapshot-tests/capture-debug-output.mjs + */ +import { execSync } from 'node:child_process'; +import { createRequire } from 'node:module'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; +import fs from 'node:fs'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const projectRoot = path.resolve(__dirname, '../..'); + +const WORKSPACE = 'example_projects/iOS_Calculator/CalculatorApp.xcworkspace'; +const BUNDLE_ID = 'io.sentry.calculatorapp'; + +// Find simulator +const listOutput = execSync('xcrun simctl list devices available --json', { encoding: 'utf8' }); +const data = JSON.parse(listOutput); +let simulatorUdid = null; +for (const runtime of Object.values(data.devices)) { + for (const device of runtime) { + if (device.name === 'iPhone 17') { + if (device.state !== 'Booted') { + execSync(`xcrun simctl boot ${device.udid}`, { encoding: 'utf8' }); + } + simulatorUdid = device.udid; + break; + } + } + if (simulatorUdid) break; +} + +console.log('Simulator UDID:', simulatorUdid); +console.log('Launching app...'); + +execSync(`xcrun simctl launch --terminate-running-process ${simulatorUdid} ${BUNDLE_ID}`, { + encoding: 'utf8', + stdio: 'pipe', +}); + +await new Promise((r) => setTimeout(r, 2000)); + +// Now dynamically import the tool modules +const { importToolModule } = await import(`${projectRoot}/build/core/manifest/import-tool-module.js`); +const { normalizeSnapshotOutput } = await import(`${projectRoot}/build/snapshot-tests/normalize.js`).catch(() => { + // If not in build, use the project normalize + return import(`${projectRoot}/src/snapshot-tests/normalize.ts`); +}); + +console.log('Modules loaded'); diff --git a/src/snapshot-tests/fixture-io.ts b/src/snapshot-tests/fixture-io.ts new file mode 100644 index 00000000..7f0b6cb6 --- /dev/null +++ b/src/snapshot-tests/fixture-io.ts @@ -0,0 +1,35 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { expect } from 'vitest'; + +const FIXTURES_DIR = path.resolve(process.cwd(), 'src/snapshot-tests/__fixtures__'); + +function shouldUpdateSnapshots(): boolean { + return process.env.UPDATE_SNAPSHOTS === '1' || process.env.UPDATE_SNAPSHOTS === 'true'; +} + +export function fixturePathFor(testFilePath: string, scenario: string): string { + const workflow = path.basename(testFilePath, '.snapshot.test.ts'); + return path.join(FIXTURES_DIR, workflow, `${scenario}.txt`); +} + +export function expectMatchesFixture(actual: string, testFilePath: string, scenario: string): void { + const fixturePath = fixturePathFor(testFilePath, scenario); + + if (shouldUpdateSnapshots()) { + const dir = path.dirname(fixturePath); + fs.mkdirSync(dir, { recursive: true }); + fs.writeFileSync(fixturePath, actual, 'utf8'); + return; + } + + if (!fs.existsSync(fixturePath)) { + throw new Error( + `Fixture missing: ${path.relative(process.cwd(), fixturePath)}\n` + + 'Run with UPDATE_SNAPSHOTS=1 to generate it.', + ); + } + + const expected = fs.readFileSync(fixturePath, 'utf8'); + expect(actual).toBe(expected); +} diff --git a/src/snapshot-tests/flowdeck-fixture-io.ts b/src/snapshot-tests/flowdeck-fixture-io.ts new file mode 100644 index 00000000..68f1ca7d --- /dev/null +++ b/src/snapshot-tests/flowdeck-fixture-io.ts @@ -0,0 +1,16 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +const FIXTURES_DIR = path.resolve(process.cwd(), 'src/snapshot-tests/__flowdeck_fixtures__'); + +export function writeFlowdeckFixture( + testFilePath: string, + scenario: string, + content: string, +): void { + const workflow = path.basename(testFilePath, '.flowdeck.test.ts'); + const fixturePath = path.join(FIXTURES_DIR, workflow, `${scenario}.txt`); + const dir = path.dirname(fixturePath); + fs.mkdirSync(dir, { recursive: true }); + fs.writeFileSync(fixturePath, content, 'utf8'); +} diff --git a/src/snapshot-tests/flowdeck-pty.py b/src/snapshot-tests/flowdeck-pty.py new file mode 100644 index 00000000..db7bfcc1 --- /dev/null +++ b/src/snapshot-tests/flowdeck-pty.py @@ -0,0 +1,36 @@ +"""Spawn flowdeck inside a PTY so it emits full ANSI colour sequences.""" +import os +import pty +import subprocess +import sys + +def main(): + master, slave = pty.openpty() + env = dict(os.environ, TERM="xterm-256color", COLUMNS="120", LINES="50") + p = subprocess.Popen( + ["flowdeck"] + sys.argv[1:], + stdout=slave, + stderr=slave, + stdin=slave, + env=env, + close_fds=True, + ) + os.close(slave) + + output = b"" + while True: + try: + data = os.read(master, 4096) + if not data: + break + output += data + except OSError: + break + + os.close(master) + rc = p.wait() + sys.stdout.buffer.write(output) + sys.exit(rc) + +if __name__ == "__main__": + main() diff --git a/src/snapshot-tests/harness.ts b/src/snapshot-tests/harness.ts new file mode 100644 index 00000000..c9de8331 --- /dev/null +++ b/src/snapshot-tests/harness.ts @@ -0,0 +1,226 @@ +import { spawnSync, execSync } from 'node:child_process'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { normalizeSnapshotOutput } from './normalize.ts'; +import { loadManifest } from '../core/manifest/load-manifest.ts'; +import { getEffectiveCliName } from '../core/manifest/schema.ts'; +import { importToolModule } from '../core/manifest/import-tool-module.ts'; +import type { ToolManifestEntry } from '../core/manifest/schema.ts'; +import { postProcessSession } from '../runtime/tool-invoker.ts'; +import { createToolCatalog } from '../runtime/tool-catalog.ts'; +import type { ToolDefinition } from '../runtime/types.ts'; +import type { ToolHandlerContext } from '../rendering/types.ts'; +import { createRenderSession } from '../rendering/render.ts'; + +const CLI_PATH = path.resolve(process.cwd(), 'build/cli.js'); + +export interface SnapshotHarness { + invoke( + workflow: string, + cliToolName: string, + args: Record, + ): Promise; + cleanup(): void; +} + +export interface SnapshotResult { + text: string; + rawText: string; + isError: boolean; +} + +function resolveToolManifest( + workflowId: string, + cliToolName: string, +): { + toolModulePath: string; + isMcpOnly: boolean; + isStateful: boolean; + manifestEntry: ToolManifestEntry; +} | null { + const manifest = loadManifest(); + const workflow = manifest.workflows.get(workflowId); + if (!workflow) return null; + + const isMcpOnly = !workflow.availability.cli; + + for (const toolId of workflow.tools) { + const tool = manifest.tools.get(toolId); + if (!tool) continue; + if (getEffectiveCliName(tool) === cliToolName) { + return { + toolModulePath: tool.module, + isMcpOnly, + isStateful: tool.routing?.stateful === true, + manifestEntry: tool, + }; + } + } + + return null; +} + +function buildMinimalToolCatalog( + manifestEntry: ToolManifestEntry, + handler: ToolDefinition['handler'], +): { tool: ToolDefinition; catalog: ReturnType } { + const manifest = loadManifest(); + const noopHandler: ToolDefinition['handler'] = async () => {}; + + const allTools: ToolDefinition[] = Array.from(manifest.tools.values()).map((toolEntry) => ({ + id: toolEntry.id, + cliName: getEffectiveCliName(toolEntry), + mcpName: toolEntry.names.mcp, + workflow: '', + description: toolEntry.description, + nextStepTemplates: toolEntry.nextSteps, + mcpSchema: {} as ToolDefinition['mcpSchema'], + cliSchema: {} as ToolDefinition['cliSchema'], + stateful: toolEntry.routing?.stateful ?? false, + handler: toolEntry.id === manifestEntry.id ? handler : noopHandler, + })); + + const catalog = createToolCatalog(allTools); + const tool = catalog.getByToolId(manifestEntry.id) ?? allTools[0]!; + return { tool, catalog }; +} + +async function importSnapshotToolModule(toolModulePath: string) { + const sourceModulePath = path.resolve(process.cwd(), 'src', `${toolModulePath}.ts`); + const sourceModuleUrl = pathToFileURL(sourceModulePath).href; + + try { + return (await import(sourceModuleUrl)) as { + handler: (params: Record, ctx?: ToolHandlerContext) => Promise; + }; + } catch { + return importToolModule(toolModulePath); + } +} + +export async function createSnapshotHarness(): Promise { + async function invoke( + workflow: string, + cliToolName: string, + args: Record, + ): Promise { + const resolved = resolveToolManifest(workflow, cliToolName); + + if (resolved?.isMcpOnly || resolved?.isStateful) { + return invokeDirect(resolved.toolModulePath, resolved.manifestEntry, args); + } + + return invokeCli(workflow, cliToolName, args); + } + + async function invokeCli( + workflow: string, + cliToolName: string, + args: Record, + ): Promise { + const jsonArg = JSON.stringify(args); + const { VITEST, NODE_ENV, ...cleanEnv } = process.env; + const result = spawnSync('node', [CLI_PATH, workflow, cliToolName, '--json', jsonArg], { + encoding: 'utf8', + timeout: 120000, + cwd: process.cwd(), + env: cleanEnv, + }); + + const stdout = result.stdout ?? ''; + return { + text: normalizeSnapshotOutput(stdout), + rawText: stdout, + isError: result.status !== 0, + }; + } + + async function invokeDirect( + toolModulePath: string, + manifestEntry: ToolManifestEntry, + args: Record, + ): Promise { + const toolModule = await importSnapshotToolModule(toolModulePath); + const session = createRenderSession('text'); + const ctx: ToolHandlerContext = { + emit: (event) => { + session.emit(event); + }, + attach: (image) => { + session.attach(image); + }, + }; + await toolModule.handler(args, ctx); + + const { tool, catalog } = buildMinimalToolCatalog( + manifestEntry, + toolModule.handler as ToolDefinition['handler'], + ); + postProcessSession({ + tool, + session, + ctx, + catalog, + runtime: 'mcp', + applyTemplateNextSteps: ctx.nextStepParams != null, + }); + + const rawText = session.finalize() + '\n'; + return { + text: normalizeSnapshotOutput(rawText), + rawText, + isError: session.isError(), + }; + } + + function cleanup(): void {} + + return { invoke, cleanup }; +} + +/** + * Shut down all booted simulators except those in the keep list. + * Use before list/resource tests to guarantee a deterministic simulator state. + */ +export function shutdownAllSimulatorsExcept(keepUdids: string[] = []): void { + const listOutput = execSync('xcrun simctl list devices available --json', { + encoding: 'utf8', + }); + const data = JSON.parse(listOutput) as { + devices: Record>; + }; + const keepSet = new Set(keepUdids); + for (const runtime of Object.values(data.devices)) { + for (const device of runtime) { + if (device.state === 'Booted' && !keepSet.has(device.udid)) { + try { + execSync(`xcrun simctl shutdown ${device.udid}`, { encoding: 'utf8' }); + } catch { + // Ignore shutdown failures (device may already be shutting down). + } + } + } + } +} + +export async function ensureSimulatorBooted(simulatorName: string): Promise { + const listOutput = execSync('xcrun simctl list devices available --json', { + encoding: 'utf8', + }); + const data = JSON.parse(listOutput) as { + devices: Record>; + }; + + for (const runtime of Object.values(data.devices)) { + for (const device of runtime) { + if (device.name === simulatorName) { + if (device.state !== 'Booted') { + execSync(`xcrun simctl boot ${device.udid}`, { encoding: 'utf8' }); + } + return device.udid; + } + } + } + + throw new Error(`Simulator "${simulatorName}" not found`); +} diff --git a/src/snapshot-tests/normalize.ts b/src/snapshot-tests/normalize.ts new file mode 100644 index 00000000..202b86c2 --- /dev/null +++ b/src/snapshot-tests/normalize.ts @@ -0,0 +1,189 @@ +import os from 'node:os'; +import path from 'node:path'; + +const ANSI_REGEX = /\x1B\[[0-9;]*[mK]/g; +const ISO_TIMESTAMP_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?Z/g; +const LOG_FILENAME_TIMESTAMP_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z/g; +const APPLE_DEVICE_UDID_REGEX = /[0-9A-Fa-f]{8}-[0-9A-Fa-f]{16}/g; +const UUID_REGEX = /[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}/g; +const DURATION_REGEX = /\d+\.\d+s\b/g; +const PID_NUMBER_REGEX = /(pid:\s*)\d+/gi; +const PID_FILENAME_SUFFIX_REGEX = /_pid\d+\.log/g; +const PID_JSON_REGEX = /"pid"\s*:\s*\d+/g; +const PROCESS_ID_REGEX = /Process ID: \d+/g; +const PROCESS_INLINE_PID_REGEX = /process \d+/g; +const CLI_PROCESS_ID_ARG_REGEX = /--process-id "\d+"/g; +const THREAD_ID_REGEX = /Thread \d{5,}/g; +const HEX_ADDRESS_REGEX = /0x[0-9a-fA-F]{8,}/g; + +const LLDB_FRAME_OFFSET_REGEX = /(`[^`\n]+):(\d+)$/gm; +const LLDB_SYS_FRAME_FUNC_REGEX = + /(frame #\d+: )\S+( at (?:\/usr\/lib\/|\/Library\/Developer\/CoreSimulator\/)[^`\n]*`)[^:\n]+(:)/gm; +const LLDB_LOWER_FRAMES_REGEX = /( frame #\d+: (?: at [^\n]*|(?: at [^\n]*)?)\n)+/g; +const LLDB_FRAME_NUMBER_REGEX = / frame #\d+:/g; +const LLDB_BREAKPOINT_LOCATIONS_REGEX = /locations = .+$/gm; +const LLDB_BREAKPOINT_SUB_LOCATION_REGEX = /^\s+\d+\.\d+: where = [^\n]+\n?/gm; +const DERIVED_DATA_HASH_REGEX = /(DerivedData\/[A-Za-z0-9_]+)-[a-z]{28}\b/g; +const PROGRESS_LINE_REGEX = /^โ€บ.*\n*/gm; +const WARNINGS_BLOCK_REGEX = /Warnings \(\d+\):\n(?:\n? *โš [^\n]*\n?)*/g; +const XCODE_INFRA_ERRORS_REGEX = + /Compiler Errors \(\d+\):\n(?:\n? *โœ— (?:unable to rename temporary|failed to emit precompiled|accessing build database)[^\n]*\n?(?:\n? {4}[^\n]*\n?)*)*/g; +const SPM_STEP_LINE_REGEX = /^\[\d+\/\d+\] .+\n?/gm; +const SPM_PLANNING_LINE_REGEX = /^Building for (?:debugging|release)\.\.\.\n?/gm; +const LOCAL_TIMESTAMP_REGEX = /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}/g; +const XCTEST_PARENS_DURATION_REGEX = /\(\d+\.\d+\) seconds/g; +const SWIFT_TESTING_DURATION_REGEX = /after \d+\.\d+ seconds/g; +const TEST_SUMMARY_COUNTS_REGEX = + /\(Total: \d+(?:, Passed: \d+)?(?:, Failed: \d+)?(?:, Skipped: \d+)?, /g; +const COVERAGE_CALL_COUNT_REGEX = /called \d+x\)/g; +const DEVICE_LABEL_REGEX = /Device: .+ \(\)/g; +const UPTIME_REGEX = /Uptime: \d+s/g; +const RESULT_BUNDLE_LINE_REGEX = /\S+\[\d+:\d+\] Writing error result bundle to \S+/g; +const DEVICE_TRANSPORT_TYPE_REGEX = /\b(wired|localNetwork)\b/g; +const TARGET_DEVICE_IDENTIFIER_REGEX = /(TARGET_DEVICE_IDENTIFIER = )([0-9A-Fa-f]{24,40})/g; +const CODEX_ARG0_PATH_REGEX = /\/\.codex\/tmp\/arg0\/codex-arg0[A-Za-z0-9]+/g; +const CODEX_WORKTREE_NODE_MODULES_REGEX = + /\/\.codex\/worktrees\/[^/:]+\/node_modules\/\.bin/g; +const ACQUIRED_USAGE_ASSERTION_TIME_REGEX = + /(^\s*)\d{2}:\d{2}:\d{2}( {2}Acquired usage assertion\.)$/gm; +const BUILD_SETTINGS_PATH_REGEX = /^( {6}PATH = ).+$/gm; +const TRAILING_WHITESPACE_REGEX = /[ \t]+$/gm; + +function sortLinesInBlock(text: string, marker: RegExp): string { + const lines = text.split('\n'); + const blocks: { start: number; end: number }[] = []; + let blockStart = -1; + for (let i = 0; i < lines.length; i++) { + if (marker.test(lines[i]!)) { + if (blockStart === -1) blockStart = i; + } else if (blockStart !== -1) { + blocks.push({ start: blockStart, end: i }); + blockStart = -1; + } + } + if (blockStart !== -1) blocks.push({ start: blockStart, end: lines.length }); + for (const block of blocks) { + const slice = lines.slice(block.start, block.end); + slice.sort(); + lines.splice(block.start, block.end - block.start, ...slice); + } + return lines.join('\n'); +} + +function escapeRegex(str: string): string { + return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +export function normalizeSnapshotOutput(text: string): string { + let normalized = text; + + normalized = normalized.replace(ANSI_REGEX, ''); + + const projectRoot = path.resolve(process.cwd()); + normalized = normalized.replace(new RegExp(escapeRegex(projectRoot), 'g'), ''); + + const home = os.homedir(); + normalized = normalized.replace(new RegExp(escapeRegex(home), 'g'), ''); + normalized = normalized.replace(/~\//g, '/'); + normalized = normalized.replace(/(?<=\s|:)~(?=\s|$)/gm, ''); + + const tmpDir = os.tmpdir(); + normalized = normalized.replace( + new RegExp(escapeRegex(tmpDir) + '/[A-Za-z0-9._-]+/', 'g'), + '/', + ); + + normalized = normalized.replace(DERIVED_DATA_HASH_REGEX, '$1-'); + normalized = normalized.replace(ISO_TIMESTAMP_REGEX, ''); + normalized = normalized.replace(LOG_FILENAME_TIMESTAMP_REGEX, ''); + normalized = normalized.replace(APPLE_DEVICE_UDID_REGEX, ''); + normalized = normalized.replace(UUID_REGEX, ''); + normalized = normalized.replace(DEVICE_LABEL_REGEX, 'Device: ()'); + normalized = normalized.replace(DEVICE_TRANSPORT_TYPE_REGEX, ''); + normalized = normalized.replace(DURATION_REGEX, ''); + normalized = normalized.replace(PID_NUMBER_REGEX, '$1'); + normalized = normalized.replace(PID_FILENAME_SUFFIX_REGEX, '_pid.log'); + normalized = normalized.replace(PID_JSON_REGEX, '"pid" : '); + normalized = normalized.replace(PROCESS_ID_REGEX, 'Process ID: '); + normalized = normalized.replace(PROCESS_INLINE_PID_REGEX, 'process '); + normalized = normalized.replace(CLI_PROCESS_ID_ARG_REGEX, '--process-id ""'); + normalized = normalized.replace(UPTIME_REGEX, 'Uptime: '); + normalized = normalized.replace(THREAD_ID_REGEX, 'Thread '); + normalized = normalized.replace(HEX_ADDRESS_REGEX, ''); + normalized = normalized.replace(LLDB_FRAME_OFFSET_REGEX, '$1:'); + normalized = normalized.replace(LLDB_SYS_FRAME_FUNC_REGEX, '$1$2$3'); + normalized = normalized.replace(LLDB_LOWER_FRAMES_REGEX, ' \n'); + normalized = normalized.replace(LLDB_FRAME_NUMBER_REGEX, ' frame #:'); + normalized = normalized.replace(LLDB_BREAKPOINT_LOCATIONS_REGEX, 'locations = '); + normalized = normalized.replace(LLDB_BREAKPOINT_SUB_LOCATION_REGEX, ''); + normalized = normalized.replace(RESULT_BUNDLE_LINE_REGEX, ''); + normalized = normalized.replace(PROGRESS_LINE_REGEX, ''); + normalized = normalized.replace(WARNINGS_BLOCK_REGEX, ''); + normalized = normalized.replace(XCODE_INFRA_ERRORS_REGEX, ''); + + normalized = normalized.replace(SPM_STEP_LINE_REGEX, ''); + normalized = normalized.replace(SPM_PLANNING_LINE_REGEX, ''); + normalized = normalized.replace(LOCAL_TIMESTAMP_REGEX, ''); + normalized = normalized.replace(XCTEST_PARENS_DURATION_REGEX, '() seconds'); + normalized = normalized.replace(SWIFT_TESTING_DURATION_REGEX, 'after seconds'); + normalized = normalized.replace(TEST_SUMMARY_COUNTS_REGEX, '(, '); + + normalized = normalized.replace(TARGET_DEVICE_IDENTIFIER_REGEX, '$1'); + normalized = normalized.replace(BUILD_SETTINGS_PATH_REGEX, '$1'); + normalized = normalized.replace(CODEX_ARG0_PATH_REGEX, '/.codex/tmp/arg0/codex-arg0'); + normalized = normalized.replace(ACQUIRED_USAGE_ASSERTION_TIME_REGEX, '$1