iOS E2E은(는) 무엇을 하나요?
체크아웃 루트에서 작업합니다. 로컬 .mobilebuildmcp/config.yaml(설정)에 프로젝트, 스킴 및 DerivedData가 제공되므로 mobilebuildmcp 명령어에 프로젝트 플래그가 필요하지 않습니다.
두 개의 값이 반복 사용됩니다:
$sim: 시뮬레이터 UDID (pnpm ios:sim:pair가 출력합니다). 모든mobilebuildmcp호출에--simulator-id "$sim"을 전달하세요; 이 값이 없으면 구성 기본값이iPhone 17이라는 시뮬레이터를 대상으로 합니다.$bundle: 번들 ID로, 서명 팀에 따라 달라집니다. 빌드에서 읽어옵니다:bundle=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' apps/ios/build/DerivedData/Build/Products/Debug-iphonesimulator/OpenClaw.app/Info.plist).
빌드 및 실행
-
빌드:
mobilebuildmcp simulator build.apps/ios/project.yml을 편집한 후 먼저pnpm ios:gen을 실행하세요. -
simctl로 설치 및 실행합니다. 이 명령어는 실행 인수를 받습니다 (pnpm ios:run은 인수를 받지 않음):xcrun simctl install "$sim" apps/ios/build/DerivedData/Build/Products/Debug-iphonesimulator/OpenClaw.app xcrun simctl launch --terminate-running-process "$sim" "$bundle" --openclaw-reset-onboardingmobilebuildmcp simulator build-and-run및launch-app은 종료되지 않는 로그 캡처를 연결합니다. -
디버그 실행 인수 확인:
grep -rhoE '"--openclaw-[a-z-]+"' apps/ios/Sources | sort -u.--openclaw-screenshot-mode와--openclaw-*-fixture플래그를 함께 사용하면 Gateway 없이 픽스처 화면을 표시합니다;-AppleLanguages "(de)" -AppleLocale de_DE는 다른 언어로 실행합니다. 디버그 URL 스킴은openclaw-debug://입니다.
UI 구동
mobilebuildmcp ui-automation snapshot-ui --style minimal은 탭 가능한 대상을ref|action|role|label|value|id형식으로 나열합니다. 컨트롤이 아닌 텍스트(채팅 버블, 행 제목)는--output json을 사용할 때만 표시됩니다.- ref에 대해
tap,type-text,long-press(--duration은 밀리초),swipe또는gesture로 동작을 수행합니다.wait-for-ui로 대기합니다: 요소의 경우--predicate exists --label '…' --role button, 텍스트의 경우--predicate textContains --text '…'. 여러 요소와 일치하는 대기 선택자는 실패합니다;--role또는--identifier를 추가하세요.--timeout-ms를 30000 미만으로 유지하세요: 데몬은 30초 후에 모든 요청을DAEMON_TRANSPORT_FAILED로 종료합니다; 더 오래 대기하려면 반복하세요. - ref는 하나의 스냅샷에 속합니다; 화면이 변경될 때마다 새 스냅샷을 찍으세요.
- 화면 보기:
mobilebuildmcp simulator screenshot, 그런 다음 출력된 JPEG를 읽으세요.
주의사항:
- 온보딩 및 시트는 그 뒤에 있는 화면도 함께 나열합니다; 레이블이나 id로 일치시키고 마지막 일치 항목을 선택하세요.
- iPhone에서 사이드바가 콘텐츠를 덮습니다: 행 앞에
RootTabs.Sidebar.Show를 탭하세요. xcrun simctl openurl은 호출당 시스템 "OpenClaw에서 열기?" 알림을 큐에 넣습니다; 각 알림에 대해Open또는Cancel을 탭하세요.- 앱 프로세스 외부의 시스템 UI(사진 선택기, 공유 시트)는 스냅샷에서 누락됩니다. MobileBuildMCP에 번들된 AXe 바이너리로 좌표를 사용하여 탭하세요:
"$(brew --prefix mobilebuildmcp)/libexec/bundled/axe" tap -x <x> -y <y> --udid "$sim". 좌표는 포인트입니다: 스크린샷 픽셀 × 화면 너비(포인트) ÷ 스크린샷 너비.
로그 및 크래시
먼저 동작을 수행한 다음, 제한된 시간 창을 읽으세요:
xcrun simctl spawn "$sim" log show --last 2m --style compact --predicate 'subsystem BEGINSWITH "ai.openclaw"'
크래시는 ~/Library/Logs/DiagnosticReports/OpenClaw-*.ips에 저장됩니다; triggered 스레드의 첫 번째 OpenClaw 프레임이 원인을 식별합니다. 앱 환경설정 및 데이터베이스는 앱 컨테이너에 있습니다 (xcrun simctl get_app_container "$sim" "$bundle" data); simctl spawn … defaults read로는 볼 수 없습니다. LLDB 및 xctrace: DEBUG.md.
테스트
- 수정된 스위트 실행:
pnpm ios:test <Suite>(선택자 및IOS_SIM:apps/ios/README.md). - 기준(base)에서 회귀 테스트가 실패함을 증명: 변경 사항을 커밋하고, 변경된 소스 파일의 기준 버전을 체크아웃 (
git checkout <base> -- <paths>), 스위트 실행, 그런 다음git checkout HEAD -- <paths>.
완료 조건: 수정된 스위트가 통과하고, 각 새로운 회귀 테스트가 기준에서 실패합니다.
변경 사항 종단 간 증명
- 격리된 Gateway 시작 (일회성 프로필, 설정 참조)을 장기 실행 서비스로:
node scripts/run-node.mjs --profile ios-sim gateway --bind loopback. 운영자의 Gateway나~/.openclaw에 영향을 주지 않습니다. 실행 중인 동안 CLI를node openclaw.mjs --profile ios-sim …으로 호출하세요;run-node는 실행 중인 Gateway 아래에서 재빌드하지 않습니다. - 실제 온보딩 UI를 통해 새 시뮬레이터 페어링:
sim=$(pnpm --silent ios:sim:pair | tail -1)(--app로 다른 빌드,--profile로 다른 프로필 지정). - 보이는 컨트롤을 통해 변경 사항을 실행합니다. 채팅 왕복:
chat-message-input에 입력,chat-send-message탭, 그런 다음 응답에만 포함된 단어를 기다립니다. - 빌드 비교:
main브랜치와 변경 사항에서 각각 새 시뮬레이터에서 동일한 단계를 수행하고, 일치하는 스크린샷을 찍습니다. - Gateway 중지 및 시뮬레이터 삭제.
노드 명령어, 권한, 인증 실패, 중단, 전송 거부, 업그레이드 및 iPad 레이아웃: PROOF.md. 여기에는 실제 기기에서만 증명할 수 있는 항목도 나열되어 있습니다.
완료 조건: 스크린샷 또는 기록된 출력이 변경 사항에서의 동작과 main에서의 부재를 보여주며, Gateway 포트가 닫혀 있고 openclaw-pair-* 시뮬레이터가 남아 있지 않습니다.
설정
기기당 한 번만 수행; 각 단계는 확인으로 끝납니다.
-
Xcode, 시뮬레이터 런타임,
xcodegen및 Watch Rust 툴체인:apps/ios/README.md필수 조건. 확인:xcrun simctl list devices available에iPhone 17이 표시됩니다. -
SwiftFormat 및 SwiftLint를 저장소 핀 버전으로:
scripts/install-swift-tools.sh <PATH의 디렉토리>. 확인:scripts/check-swift-tools.sh가 0으로 종료됩니다. -
MobileBuildMCP, Sentry의 XcodeBuildMCP CLI:
brew tap getsentry/xcodebuildmcp && brew install getsentry/xcodebuildmcp/mobilebuildmcp. 이 단계는 2.7.1 버전 기준으로 작성되었습니다. 확인:mobilebuildmcp --version. -
체크아웃:
pnpm install --frozen-lockfile, 그런 다음pnpm ios:gen(Xcode 프로젝트는 생성되며 커밋되지 않음). 그런 다음.mobilebuildmcp/config.yaml을 생성하고/.mobilebuildmcp/를.git/info/exclude에 추가하세요:schemaVersion: 1 enabledWorkflows: [simulator, simulator-management, ui-automation, debugging] sentryDisabled: true sessionDefaults: projectPath: ./apps/ios/OpenClaw.xcodeproj scheme: OpenClaw configuration: Debug platform: iOS simulatorName: iPhone 17 derivedDataPath: ./apps/ios/build/DerivedData # pnpm ios:run과 공유확인:
mobilebuildmcp simulator list-schemes에OpenClaw가 나열되고,mobilebuildmcp simulator build가 성공합니다. -
ios-simGateway 프로필, Gateway는 중지된 상태 (oc=node openclaw.mjs --profile ios-sim):oc config set gateway.mode local,oc config set gateway.port 19031,oc config set gateway.auth.mode token,oc config set gateway.auth.token "$(openssl rand -hex 24)". 채팅 응답에는main에이전트용 모델이 필요합니다:oc models auth login또는 테스트 자격 증명으로add. 확인: Gateway가 시작되고,pnpm ios:sim:pair가 채팅 화면에서 끝납니다.