feat(runner): 테스트 완료까지 앱 전면 유지 안내 — 백그라운드 suspend 연쇄 실패 예방 (#766)#803
Merged
Conversation
2026-07-08 실기기 관측(46/8/6 부분 run vs 78/0/13 클린 완주)으로 원인이 확정된 background-suspend 연쇄(iOS WebView JS suspend → evaluate 60s 타임아웃 → relay WS 사망 → 잔여 파일 전연쇄 실패)에 대한 사전 안내 한 줄을 두 사람-대면 표면에 추가한다. 원인이 사용자 행동이므로 suspend 감지/재개 로직이 아니라 안내로 대응한다 — Page visibility 신호가 relay 죽음과 동시에 끊겨 감지가 구조적으로 불가능하다. - QR 대시보드(attach 페이지) 스캔 절차 마지막 단계: attach.sandbox.step4 (env 2) / attach.intoss.step5 (env 3), ko/en 양쪽. 빌드타임 precompile 산출물(dashboard.generated.ts)도 함께 재생성. - devtools-test CLI 러너 터미널 출력(scan-wait 배너): attach-orchestrator.ts 의 공유 header에 한 줄 추가 — start_attach MCP 도구 결과와 CLI stdout 양쪽에 동일하게 실린다. - (선택) relay-worker.ts의 이중 타임아웃 최종 에러 메시지에 진단 힌트 추가 — 사후 진단을 빠르게. Closes #766.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
배경
2026-07-08 env3(실기기) 테스트 run 중 스캔 기기에서 토스 앱을 백그라운드로 전환하면 iOS가 WebView JS를 suspend → 진행 중이던 파일 evaluate가 60s timeout → relay WebSocket 사망 → 잔여 파일 전연쇄 실패. 전면 유지 재실행에서는 동일 슈트가 완주(46/8/6 부분 run vs 78/0/13 클린 완주) — 원인이 SDK/러너가 아니라 사용자 행동임이 확정됐다.
Out of scope (issue에서 명시)
suspend 자동 감지/재개 로직은 추가하지 않는다 — Page visibility 신호가 relay 죽음과 동시에 끊기므로 사전 안내가 유일하게 실효적인 해법이다.
변경 사항 — 두 사람-대면 표면 + 선택 진단 힌트
1. QR 대시보드 (attach 페이지,
qr-http-server— 스캔 절차 블록)각 family(sandbox=env2, intoss=env3)의 스캔 절차 마지막 단계로 추가.
src/i18n/ko.ts/en.ts에 키 추가 →scripts/build-dashboard-html.ts에서steps배열에 반영 →src/mcp/dashboard.generated.ts재생성(pnpm build:dashboard-html).intoss (env 3) — before/after
<strong>테스트가 끝날 때까지 토스 앱을 화면 앞에 유지하세요</strong> — 백그라운드로 전환하면 디버그 세션이 끊어집니다.<strong>Keep the Toss app in the foreground until the test run finishes</strong> — backgrounding it will drop the debug session.sandbox (env 2) — before/after
<strong>테스트가 끝날 때까지 앱을 화면 앞에 유지하세요</strong> — 백그라운드로 전환하면 디버그 세션이 끊어집니다.<strong>Keep the app in the foreground until the test run finishes</strong> — backgrounding it will drop the debug session.env2(sandbox/launcher PWA)도 동일한 CDP relay evaluate 경로를 타므로 env3와 함께 추가했다 — 표면·메커니즘은 동일, iOS가 backgrounded PWA도 WebView JS를 suspend할 수 있다.
2. 러너 터미널 출력 (scan-wait 배너)
devtools-testCLI와start_attachMCP 도구가 공유하는src/mcp/attach-orchestrator.ts의renderAndMaybeWait가 4개 렌더 경로(headless / browser-opened / browser-open-failed / no-http-server) 전부에서 공통으로 쓰는header상수에 한 줄 추가 — 단일 지점 수정으로 모든 경로 + 양쪽 호출자(CLI stdout, MCP tool result)에 동일하게 실린다."This tool result is shown to the user directly — ... (Ctrl+O to expand if collapsed)."\n\n+"테스트가 끝날 때까지 앱을 화면 앞에 유지하세요 — 백그라운드로 전환하면 디버그 세션이 끊어집니다."이 텍스트는 기존에도 이 함수 안에서 i18n 없이 한국어 단독으로 쓰이는 사람-대면 문구(예: "브라우저에서 QR을 열었습니다. 폰 카메라로 스캔하세요.")와 같은 패턴이라 별도 en 버전은 두지 않았다.
3. (선택, issue에서 권장) evaluate 타임아웃 에러에 진단 힌트
src/test-runner/relay-worker.ts— 재시도까지 실패한 파일의 최종 에러 메시지(EVALUATE_TIMEOUT_MARKER ... (after retry))에 힌트를 덧붙였다. 이 지점이 유일하게 사용자에게 보이는 최종 에러 문자열이라(첫 타임아웃은 항상 재시도로 넘어가고 절대 그대로 노출되지 않음) surgical 1-line 추가로 충분했다.`rpc: evaluate timed out after ${timeoutMs}ms (after retry)``rpc: evaluate timed out after ${timeoutMs}ms (after retry) — the device's app may have been backgrounded`EVALUATE_TIMEOUT_MARKER/"(after retry)"substring을 그대로 유지해relay-worker.test.ts의 기존.toContain(...)검증이 그대로 통과한다(재시도 로직·에러 흐름은 건드리지 않음).왜 사전 안내가 "그" 해법인가
issue의 out-of-scope 그대로: relay가 죽는 순간 Page visibility 신호도 함께 끊기므로, 백그라운드 전환을 사후에 감지해 자동 재개하는 경로는 구조적으로 없다. 따라서 유일하게 실효적인 개입은 사람이 백그라운드로 보내기 전에 읽는 표면(스캔 직후 QR 대시보드, 스캔을 기다리는 동안의 터미널 출력)에 안내를 두는 것이다.
검증
pnpm typecheck— green (4개 tsconfig 라인 전부)pnpm test— green (111 files, 2501 passed, 1 todo — pre-existing)pnpm lint(Biome,noExplicitAny: error) — greenpnpm check:dashboard-html-fresh— green (재생성 후 diff 없음)src/mcp/__tests__/qr-browser.test.ts의 기존 substring assertion(toContain)과 충돌하지 않는다(전체 스위트 green으로 확인).Changeset
.changeset/env3-foreground-guidance-766.md(patch,@ait-co/devtools)Closes #766