Skip to content

fix(recording): support prepared physical iOS captures#120

Merged
drown0315 merged 11 commits into
mainfrom
fix/bugs
Jul 13, 2026
Merged

fix(recording): support prepared physical iOS captures#120
drown0315 merged 11 commits into
mainfrom
fix/bugs

Conversation

@drown0315

Copy link
Copy Markdown
Owner

Intent

The developer wanted to diagnose why iOS real-device runs with recording enabled in a test YAML produced no video artifact, then fix the underlying issue. They confirmed a solution that separates the app target device identifier from the recording device identifier, pairs iOS physical devices by exact name when IDs differ, and uses the recorder’s actual device selector for video capture while keeping Flutter/app launch on the Flutter UDID. They then requested implementation with staged commits, including a prepared iOS capture lifecycle where recording hardware is opened before app launch and the video segment starts only after the runtime is ready. After the fix was committed in phases, they asked for a standalone document teaching another AI the iOS “preheated recording” solution, and explicitly required that the document not include project-specific code context or terminology.

What Changed

  • Added prepared screen-capture support so physical iOS recording can open the device recorder before app launch, start the video segment after runtime readiness, and clean up prepared/active captures without dropping ownership on failures.
  • Split target app device selection from recording device selection, including exact-name pairing for physical iOS devices whose Flutter and recorder identifiers differ.
  • Updated recording and scenario documentation, design notes, and tests around prepared capture lifecycle, device matching, and cleanup behavior.

Risk Assessment

⚠️ Medium: The main ownership and cleanup risks from prior rounds appear addressed, but the new long-running helper protocol still has a concrete external-process error-normalization gap.

Testing

I inspected the recording-focused change, ran the targeted Flutter Pilot and screen_recorder Dart tests successfully, attempted a real prepared physical-iOS recording for end-user video evidence, and captured the setup-level failure showing the iPhone is visible to Flutter/xctrace but unavailable to screen_recorder discovery; no linters, formatters, or static analysis were run.

Evidence: Flutter Pilot targeted recording tests transcript
00:00 +0: loading test/target/target_device_resolver_test.dart
00:00 +0: test/target/target_device_resolver_test.dart: TargetDeviceResolver returns null when no selector is provided and recording is not required
00:00 +1: test/target/target_device_resolver_test.dart: TargetDeviceResolver resolves a selector by id, exact name, or unique prefix
00:00 +2: test/target/target_device_resolver_test.dart: TargetDeviceResolver rejects empty, ambiguous, unsupported, and missing selectors
00:00 +3: test/target/target_device_resolver_test.dart: TargetDeviceResolver pairs a Recording Device by exact id before exact name
00:00 +4: test/target/target_device_resolver_test.dart: TargetDeviceResolver pairs a Recording Device by a unique exact name
00:00 +5: test/target/target_device_resolver_test.dart: TargetDeviceResolver rejects duplicate exact Recording Device names as ambiguous
00:00 +6: test/target/target_device_resolver_test.dart: TargetDeviceResolver rejects an unmatched recording-required Target Device
00:00 +7: test/target/target_device_resolver_test.dart: TargetDeviceResolver auto-selects only one recordable supported Flutter Device
00:00 +8: test/target/target_device_resolver_test.dart: TargetDeviceResolver parses Flutter devices machine output
00:00 +9: test/execution/test_command_executor_test.dart: default executor launches app, runs scenario, and cleans up
00:00 +10: test/execution/test_execution_session_test.dart: starts without Target Device discovery when Flutter default is allowed
00:00 +11: test/recording/screen_recorder_recording_controller_test.dart: starts and stops a screen_recorder Recording Session
00:00 +12: test/recording/screen_recorder_recording_controller_test.dart: starts and stops a screen_recorder Recording Session
00:00 +13: test/recording/screen_recorder_recording_controller_test.dart: starts and stops a screen_recorder Recording Session
00:00 +14: test/recording/screen_recorder_recording_controller_test.dart: starts and stops a screen_recorder Recording Session
00:00 +15: test/recording/screen_recorder_recording_controller_test.dart: starts and stops a screen_recorder Recording Session
00:00 +16: test/recording/screen_recorder_recording_controller_test.dart: starts and stops a screen_recorder Recording Session
00:00 +17: test/recording/screen_recorder_recording_controller_test.dart: starts and stops a screen_recorder Recording Session
00:00 +18: test/recording/screen_recorder_recording_controller_test.dart: starts and stops a screen_recorder Recording Session
00:00 +19: test/execution/test_command_executor_test.dart: default executor reports invalid hidden runtime switch values
00:00 +20: test/execution/test_command_executor_test.dart: default executor reports invalid hidden runtime switch values
00:00 +21: test/execution/test_command_executor_test.dart: default executor reports invalid hidden runtime switch values
00:00 +22: test/execution/test_command_executor_test.dart: default executor reports invalid hidden runtime switch values
00:02 +23: test/execution/test_command_executor_test.dart: default executor forwards Step progress events to the runner
00:02 +24: test/execution/test_command_executor_test.dart: default executor emits launch progress before Step progress
00:02 +25: test/execution/test_command_executor_test.dart: default executor resolves recordable Target Device before launch
00:02 +26: test/execution/test_command_executor_test.dart: default executor reports explicit Target Device launch choices
00:02 +27: test/execution/test_command_executor_test.dart: default executor reports recording auto-selected launch choices
00:02 +28: test/execution/test_command_executor_test.dart: default executor reports flavor and entrypoint launch choices
00:02 +29: test/execution/test_command_executor_test.dart: default executor emits launch failure progress with stderr tail
00:02 +30: test/execution/test_command_executor_test.dart: default executor emits non-interactive launch heartbeat until success
00:02 +31: test/execution/test_command_executor_test.dart: default executor cleans up launched app when interrupted
00:04 +32: All tests passed!
Evidence: screen_recorder prepared capture tests transcript
00:00 +0: loading packages/screen_recorder/test/ios_physical_recorder_test.dart
00:00 +0: packages/screen_recorder/test/ios_physical_recorder_test.dart: Physical iOS ScreenRecorder lists physical iOS Recording Devices from helper output
00:00 +1: packages/screen_recorder/test/ios_physical_recorder_test.dart: Physical iOS ScreenRecorder lists physical iOS Recording Devices from helper output
00:00 +2: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +3: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +4: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +5: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +6: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +7: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +8: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +9: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +10: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +11: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +12: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +13: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +14: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +15: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +16: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +17: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +18: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +19: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +20: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +21: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +22: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +23: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +24: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +25: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +26: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +27: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +28: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +29: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:00 +30: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder resolves simulators by UDID, name, and name prefix
00:03 +31: packages/screen_recorder/test/android_recorder_test.dart: Android ScreenRecorder resolves Android devices by id, name, and name prefix
00:03 +32: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder prefers exact simulator names before prefix matches
00:04 +33: packages/screen_recorder/test/android_recorder_test.dart: Android ScreenRecorder records Android devices through scrcpy when available
00:04 +34: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder stops simulator recordVideo and returns a finalized mov result
00:05 +35: packages/screen_recorder/test/android_recorder_test.dart: Android ScreenRecorder prepared capture does not start Android recording until segment start
00:05 +36: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder prepared capture does not start simulator recording until segment start
00:06 +37: packages/screen_recorder/test/android_recorder_test.dart: Android ScreenRecorder prepared capture disposal discards an active Android session
00:06 +38: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder discards simulator recording and removes local output
00:06 +39: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder discards simulator recording and removes local output
00:06 +40: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder discards simulator recording and removes local output
00:07 +41: packages/screen_recorder/test/android_recorder_test.dart: Android ScreenRecorder discards Android screenrecord without pulling a local file
00:07 +42: packages/screen_recorder/test/android_recorder_test.dart: Android ScreenRecorder discards Android screenrecord without pulling a local file
00:07 +43: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder reports stop failure when simulator output is missing
00:07 +44: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder reports stop failure when simulator output is missing
00:07 +45: packages/screen_recorder/test/ios_simulator_recorder_test.dart: iOS Simulator ScreenRecorder reports stop failure when simulator output is missing
00:08 +46: All tests passed!
Evidence: Physical iOS recorder focused tests transcript
00:00 +0: loading packages/screen_recorder/test/ios_physical_recorder_test.dart
00:00 +0: Physical iOS ScreenRecorder lists physical iOS Recording Devices from helper output
00:00 +1: Physical iOS ScreenRecorder excludes xctrace-only devices from Recording Devices
00:00 +2: Physical iOS ScreenRecorder resolves physical iOS devices by id, name, and name prefix
00:00 +3: Physical iOS ScreenRecorder stops physical iOS helper and returns a finalized mov result
00:00 +4: Physical iOS ScreenRecorder reports missing Swift toolchain with missing-dependency code and raw output
00:00 +5: Physical iOS ScreenRecorder reports helper list failures with permission-denied code and raw output
00:00 +6: Physical iOS ScreenRecorder reports helper immediate exit as a start failure
00:00 +7: Physical iOS ScreenRecorder cleans up standalone helper when segment start fails
00:00 +8: Physical iOS ScreenRecorder cleans up helper when prepared capture readiness fails
00:00 +9: Physical iOS ScreenRecorder keeps standalone helper owned when stop fails
00:00 +10: Physical iOS ScreenRecorder keeps standalone helper owned when discard fails
00:00 +11: Physical iOS ScreenRecorder process boundary exposes streamed stdout and stdin lines
00:00 +12: Physical iOS ScreenRecorder prepared capture reuses one serve helper across segments
00:00 +13: Physical iOS ScreenRecorder prepared capture rejects segment start after disposal
00:00 +14: Physical iOS ScreenRecorder prepared capture rejects concurrent segments
00:00 +15: Physical iOS ScreenRecorder prepared capture disposal is idempotent
00:00 +16: Physical iOS ScreenRecorder reports stop failure when physical iOS output is missing
00:00 +17: All tests passed!
Evidence: Live physical iOS prepared recording attempt
--- xcrun xctrace list devices ---
== Devices ==
drown的MacBook Pro (413457E0-CF99-52D4-A082-30349AC884F5)
钟惠彬的 iPhone (15.8.8) (269bfd1ccaa634d5f2250efe6a22016b18fd16da)

== Devices Offline ==
Unknown (6FC56E18-825D-5F44-909F-43C55FBB2A12)

== Simulators ==
Apple Watch SE 3 (40mm) Simulator (26.4) (8DDD220E-7966-43E6-8ECA-A56B9A1EF652)
Apple Watch SE 3 (44mm) Simulator (26.4) (0846F274-4077-44B8-9116-2E6D4D5B9CBC)
iPad (A16) Simulator (26.4) (980CEDAF-3522-413C-A2E4-5AFD52663278)
iPad Air 11-inch (M4) Simulator (26.4) (C2E0EC27-67CC-49E4-8BF8-70A8F702D135)
iPad Air 13-inch (M4) Simulator (26.4) (708E00B0-DE5F-4D81-A3D1-86B2800F455D)
iPad Pro 11-inch (M5) Simulator (26.4) (B6563B9C-843D-4234-A0E2-7B93C5B3C904)
iPad Pro 13-inch (M5) Simulator (26.4) (BD3FDB23-982C-4608-ABB4-AA2A2B1BF387)
iPad mini (A17 Pro) Simulator (26.4) (AF678D17-0D4F-4C3C-A57F-E1BDFB34100D)
iPhone 17 Simulator (26.4) (58CC29EF-4758-4E4E-A79A-398E4A26C91F)
iPhone 17 Simulator (26.4) + Apple Watch Ultra 3 (49mm) (26.4) (A23FF228-13CF-4527-A421-B28FC00918B6)
iPhone 17 Pro Simulator (26.4) (A17ABBDC-1A2F-416B-B593-00913319C721)
iPhone 17 Pro Max Simulator (26.4) (0F93D027-DCBF-487E-BD61-290188B10A0B)
iPhone 17 Pro Max Simulator (26.4) + Apple Watch Series 11 (46mm) (26.4) (6226BBCC-7F8E-4604-8549-345B4D981C59)
iPhone 17e Simulator (26.4) (74A67FAF-1691-402D-A345-B23D3FF357F5)
iPhone Air Simulator (26.4) (96A17804-A8DC-435C-AB40-90EAB4DEBF2F)
iPhone Air Simulator (26.4) + Apple Watch Series 11 (42mm) (26.4) (CEE34FD7-3A60-4346-8FCB-39D231FD2DC8)

--- flutter devices --machine ---
[
  {
    "name": "Pixel 6",
    "id": "19271FDF6007TY",
    "isSupported": true,
    "targetPlatform": "android-arm64",
    "emulator": false,
    "sdk": "Android 14 (API 34)",
    "capabilities": {
      "hotReload": true,
      "hotRestart": true,
      "screenshot": true,
      "flutterExit": true,
      "hardwareRendering": false,
      "startPaused": true
    }
  },
  {
    "name": "钟惠彬的 iPhone",
    "id": "269bfd1ccaa634d5f2250efe6a22016b18fd16da",
    "isSupported": true,
    "targetPlatform": "ios",
    "emulator": false,
    "sdk": "iOS 15.8.8 19H422",
    "capabilities": {
      "hotReload": true,
      "hotRestart": true,
      "screenshot": true,
      "flutterExit": true,
      "hardwareRendering": false,
      "startPaused": false
    }
  },
  {
    "name": "macOS",
    "id": "macos",
    "isSupported": true,
    "targetPlatform": "darwin",
    "emulator": false,
    "sdk": "macOS 26.2 25C56 darwin-arm64",
    "capabilities": {
      "hotReload": true,
      "hotRestart": true,
      "screenshot": false,
      "flutterExit": true,
      "hardwareRendering": false,
      "startPaused": true
    }
  },
  {
    "name": "Chrome",
    "id": "chrome",
    "isSupported": true,
    "targetPlatform": "web-javascript",
    "emulator": false,
    "sdk": "Google Chrome 150.0.7871.114",
    "capabilities": {
      "hotReload": true,
      "hotRestart": true,
      "screenshot": false,
      "flutterExit": false,
      "hardwareRendering": false,
      "startPaused": true
    }
  }
]

--- physical iOS prepared recording attempt ---
Recording devices:
Unhandled exception:
ScreenRecorderException(ScreenRecorderErrorCode.deviceNotFound): No physical iOS Recording Device matched selector: 钟惠彬的 iPhone
#0      IosPhysicalRecordingBackend.resolveDevice (package:screen_recorder/src/backend/ios_physical_recording_backend.dart:59:5)
<asynchronous suspension>
#1      ScreenRecorderService.prepare (package:screen_recorder/src/service/screen_recorder_service.dart:118:36)
<asynchronous suspension>
#2      main (file:///var/folders/1b/xbh8qb0d0j11fzyfm0qs0pf40000gn/T/no-mistakes-evidence/01KXD3BTQY6R7BHSD5M5939HBF/physical_ios_preheated_recording.dart:16:35)
<asynchronous suspension>
- Outcome: ⏭️ skipped across 1 run (6m17s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⏭️ **Review** - skipped
  • 🚨 packages/screen_recorder/lib/src/service/screen_recorder_service.dart:243 - dispose() drops a prepared capture without handling an active session. For backends that return backendPrepared == false (Android and iOS simulator through the composite prepared path), a session started from that prepared capture is a normal backend recording, so cleanup during interruption or early session close can leave the recording process/device capture running and the output untracked. Dispose should stop/discard any activeSessionId before removing the prepared state, or the controller should discard its active _session before disposing the capture.
  • 🚨 packages/screen_recorder/lib/src/backend/ios_physical_recording_backend.dart:116 - If the physical iOS helper starts but never emits the expected ready event, prepare() leaves the process in _preparedCaptures and rethrows. ScreenRecorderService.prepare() only records the capture after backend prepare succeeds, so the caller has no handle to dispose and the helper can keep the device capture open. Wrap the readiness wait with cleanup that removes the state and terminates/drains the helper before rethrowing.

🔧 Fix: Fix prepared recording cleanup leaks
2 issues (1 error, 1 warning) still open:

  • 🚨 packages/screen_recorder/lib/src/backend/ios_physical_recording_backend.dart:77 - Standalone physical iOS startRecord can leak the prepared helper when startRecord(capture, session, ...) fails after prepare(capture) succeeds. The service rolls back the active session, but the caller never receives a session or capture handle, while _standaloneCaptures / _preparedCaptures still own the serve process. Wrap this call in cleanup that removes the standalone mapping and disposes the capture before rethrowing; apply the same ownership-preserving cleanup pattern to standalone stop/discard failures where the mapping is removed before the helper is shut down.
  • ⚠️ lib/src/execution/test_execution_session.dart:350 - close() now lets RecordingException from recordingController.dispose() escape directly. In DefaultTestCommandExecutor and DefaultProjectRunExecutor, this runs from finally, so a dispose failure can mask a successful run, hide the original launch/scenario failure, and bypass the existing TestCommandException / environment-failure rendering paths. Convert dispose failures to TestExecutionRecordingException or suppress/report them without overriding the primary result.

🔧 Fix: Preserve recording cleanup ownership
3 issues (2 errors, 1 warning) still open:

  • 🚨 packages/screen_recorder/lib/src/service/screen_recorder_service.dart:264 - dispose() marks the capture disposed and removes it from _preparedCaptures before backend shutdown succeeds. If physical iOS helper shutdown throws or times out, the public capture handle can no longer be retried through this service, leaving backend-owned capture state/processes orphaned. Keep the prepared state owned until backend dispose succeeds, and apply the same remove-after-success ownership rule in the composite backend.
  • 🚨 lib/src/recording/screen_recorder_recording_controller.dart:105 - The recording controller clears _capture and sets _disposed before _recorder.dispose(capture) succeeds. A close-time dispose failure therefore makes subsequent cleanup attempts no-op at the controller layer, which is especially risky for prepared iOS helpers. Only clear the capture / mark disposed after the recorder dispose completes successfully.
  • ⚠️ lib/src/execution/test_command_executor.dart:108 - completedNormally is set for any returned ScenarioRunReport, including failed reports, so a recording dispose failure in finally still replaces the Scenario failure with a TestCommandException. Match the project-run behavior by only reporting close/dispose failure when the returned report passed; failed Scenario reports should remain the primary result.

🔧 Fix: Preserve recording cleanup ownership
1 warning still open:

  • ⚠️ packages/screen_recorder/lib/src/backend/ios_physical_recording_backend.dart:390 - _waitForEvent() decodes the helper protocol line before entering the existing unexpected-event error path. If the helper writes any non-JSON stdout line while serving, this leaks a raw FormatException out of startRecord/stopRecord instead of a ScreenRecorderException, which breaks the backend contract and bypasses the existing user-facing diagnostics. Catch JSON parse failures here and convert them to the same failureCode with the raw line attached.
⏭️ **Test** - skipped
  • ⚠️ Missing live video artifact evidence: this Mac sees the physical iPhone in both xcrun xctrace list devices and flutter devices --machine, but the screen_recorder physical-iOS discovery returned no Recording Devices, so prepared capture failed with ScreenRecorderErrorCode.deviceNotFound before a movie could be recorded. The fake-command tests cover the intended ID/name pairing and preheated lifecycle, but a reviewer still needs either a retry on hardware where the physical-iOS capture helper lists the device or explicit acceptance of the simulated evidence for this validation pass.
  • dart test test/target/target_device_resolver_test.dart test/execution/test_command_executor_test.dart test/execution/test_execution_session_test.dart test/recording/screen_recorder_recording_controller_test.dart --reporter expanded
  • dart test packages/screen_recorder/test/ios_physical_recorder_test.dart packages/screen_recorder/test/ios_simulator_recorder_test.dart packages/screen_recorder/test/android_recorder_test.dart packages/screen_recorder/test/screen_recorder_test.dart --reporter expanded
  • dart test packages/screen_recorder/test/ios_physical_recorder_test.dart --reporter expanded
  • xcrun xctrace list devices
  • flutter devices --machine
  • dart --packages=.dart_tool/package_config.json /var/folders/1b/xbh8qb0d0j11fzyfm0qs0pf40000gn/T/no-mistakes-evidence/01KXD3BTQY6R7BHSD5M5939HBF/physical_ios_preheated_recording.dart
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@drown0315
drown0315 merged commit fc830e4 into main Jul 13, 2026
2 checks passed
@drown0315
drown0315 deleted the fix/bugs branch July 13, 2026 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant