--- name: roa-vfp-headless-test description: Ruleaza si depaneaza teste VFP 9 fara IDE (headless) cu vfp9.exe -A -T "" din PowerShell, plus testele UI cu formular real, harness si screenshots. Foloseste skill-ul cand utilizatorul cere sa "ruleaza testul headless", sa "reproduca bug-ul", sa "scrie un test UI pentru formularul X", sa "depaneze eroarea la runtime", sa vada "de ce s-a agatat testul", sa interpreteze log.txt sau sa verifice ca testul chiar a rulat dupa un fix. Acopera lantul complet: init mediu auto, precompilare izolata, rulare cu timeout, watchdog pentru dialoguri native, raport de rezultate. Nu re-descoperi capcanele deja platite (SAFETY ON sub -A, .FXP/.ERR stale, INKEY(0) blocant, mock-uri in fisierul testat, DO...WITH prin referinta, dialog "View Parameter") - sunt distilate aici, iar sursa canonica e in COMUN\docs. --- # Rulare si depanare teste VFP headless (fara IDE) Distinge "headless" (script .prg, fara UI vizibil) de testul UI cu formular real si screenshots. Ambele se lanseaza de aici; ambele au aceleasi capcane de baza. Fara log/png, testul nu exista. ## Cand se foloseste - "ruleaza testul headless", "ruleaza testul", "de ce s-a agatat testul". - "reproduce bug-ul", "depaneaza eroarea la runtime", "am eroare in log.txt". - "scrie un test UI pentru formularul X", "fa screenshots la pasul Y". - Orice VFP care pare blocat: proces viu, CPU ~0, niciun rand nou in log. - NU pentru editare de .vcx/.scx pe text sau cautare in binare - alte skill-uri. ## Pasi 1. Alege harness-ul de mediu dupa PROIECT: `test_init_env_auto_roafacturare.prg` aici, variantele `_roacont`/`_roagest`/`_acnpro`/`_roadef` pentru celelalte produse. Init gresit incarca alt working copy si valideaza cod vechi, silentios. 2. Scrie scriptul: prima linie `SET SAFETY OFF` + `SET TALK OFF`, apoi PATH/CLASSLIB/PROCEDURE ca in aplicatie, apoi `ON ERROR` care logheaza `ERROR()`, `MESSAGE()`, `PROGRAM()`, `LINENO()` cu STRTOFILE si continua (fara WAIT WINDOW - headless nu are consola). `QUIT` obligatoriu la final. 3. Replica doar liniile relevante din Show; pentru forme modale pune `WindowType = 0`. 4. Precompileaza izolat, in proces copil: `_precompile.ps1`. Fara asta `vfp9 -A test.prg` deschide intermitent editorul in loc sa ruleze (log gol). 5. Ruleaza cu timeout (comanda in `## Scripturi`). Pentru dialoguri native, watchdog-ul. 6. Citeste DOAR esecurile din raportul de teste, nu logurile brute. 7. Test UI: `.prg` cu `PUBLIC gcUILog, gcSyncDir`, dummy-uri reale pe INFRASTRUCTURA (goExecutor, goApp, poAct, cursoarele cerute de Init), `WindowType=0`, `Show()`, pe fiecare pas `DO HarnessStep WITH , ''`, la final `DO HarnessDone WITH 'done'`. Apoi `vfp_ui_harness.ps1 -TestPrg -Steps @('pas0',...)`; ruleaza-l in background sau cu timeout 300-600s si NU porni VFP separat (orchestratorul il lanseaza singur). 8. Inainte de orice asertiune, dovedeste ca noul cod e incarcat (`ClassLibrary` = calea asteptata, `CREATEOBJECT` pe clasa noua intr-un TRY) - altfel validezi alt working copy. ## Capcane Condensat; fiecare are istoric scump in `COMUN\docs\depanare_testare_vfp.md` (sec. 6-7) si `COMUN\docs\testare-ui-vfp.md`. Consulta-le inainte sa schimbi scriptul sau sa invinuiesti codul. - `-A` si `-T` sunt obligatorii amandoua: fara `-T` procesul sta pe splash, simptom identic cu o eroare de compilare. `-A` ignora config.fpw si porneste SAFETY ON. - SAFETY ON sub `-A`: primul `STRTOFILE`/`COMPILE` peste fisier existent scoate dialogul modal "overwrite?" si agata pana la timeout (proces viu, pare agatat). `SET SAFETY OFF` prima linie; logheaza `SET("SAFETY")` si `SET("RESOURCE")` la start. - ON ERROR: dupa RETURN executia CONTINUA => o singura cauza produce CASCADA. PRIMA eroare din secventa e cea reala; 1940/1939 pe WITH/ENDWITH e zgomot. Erorile din TRY/CATCH nu ajung in log. - `.FXP`/`.ERR` stale agata reluarea chiar dupa fix, sub ACELASI nume (CPU=0, Responding=True, nimic in log; seamana cu blocaj de retea). Sterge-le la fiecare reluare sau da nume nou. Verifica daca `.ERR` e de la rularea asta, nu de la una anterioara. - `INKEY(0, ...)` nu e poll, e asteptare NELIMITATA: timerii VFP nu se declanseaza, nimic nu poate debloca din interiorul procesului. Foloseste `INKEY(0.01, 'H')`. - Mock in ACELASI fisier cu functia apelata NU e prins de `SET PROCEDURE ... ADDITIVE`: pune mock-ul pe functia pe care o apeleaza codul TESTAT, nu pe capatul lantului; proba ca mock-ul a castigat, INAINTE de actiunea care poate deschide dialog. - `DO ... WITH` paseaza PRIN REFERINTA si variabila devine invizibila sub numele ei => dialog nativ "View Parameter" blocant, fara log si fara eroare. Paranteze: `DO proc WITH (gnAn), (gnLuna)`. - Hung vs slow: proces viu + CPU ~0 + niciun rand nou in log = asteapta un dialog sau un fisier (exista `.ERR`?; enumera ferestrele cu `EnumWindows`/`GetWindowThreadProcessId`; `-SyncDir` nepasat => semafoare asteptate in alt folder). CPU mare = inca ruleaza. Urmareste mtime-ul log-ului, nu "log ne-gol" (un vfp9 zombi tine log stale). - Timeout: rulari intermediare ~90s/test, pauza 0.5s intre pasi; retry NUMAI la "start ratat", nu la "start lent" (la rece, zeci de classlib-uri). Fara suite in paralel - harness-ul omoara instantele vfp9 proprii, filtrate pe linia de comanda. - Alte capcane UI, pe scurt: fara `SELECT-SQL` pe cursorul legat de grid; `ZAP` (nu `DELETE ALL`) pe cursorii ceruti de Init; cursorii cu EXACT indecsii fluxului real; `ALLTRIM(camp) == 'lit'`; variabile care nu colizioneaza cu functii built-in (`loCk` -> `LOCK()`); assert pe starea de DUPA resincronizarea formularului; `_SCREEN.ActiveForm` nu merge headless, foloseste `_SCREEN.Forms`. - Testele exerseaza fluxul REAL al utilizatorului; popularea directa a cursoarelor da PASS fals. - Nu injecta input real (`keybd_event`/`SendInput`) - masina e partajata; dismiss-ul se face doar cu mesaje Windows tintite pe handle (watchdog `-AutoDismiss`). ## Criterii de acceptare si dovada Fara dovada, testul NU s-a rulat. "Gata" nu se accepta pe baza ca procesul a terminat. - Headless: log-ul arata numarul de PASS/FAIL si PRIMA eroare reala (nu cascada), plus `SET("SAFETY")`/`SET("RESOURCE")` la start si `QUIT` la final. Dovada = calea log-ului + extractul de esecuri din `raport_teste.ps1`. - UI: PNG-uri `screenshots\step__.png` pentru fiecare pas si semaforul final/done.txt; `ClassLibrary` dovedeste ca s-a incarcat codul corect. - Un test care "trece" dar valideaza alt working copy, sau care populeaza direct cursorii in loc sa treaca prin fluxul real, e PASS fals - echivalent cu un esec. - Bug: dovada e log-ul cu eroarea + linia, INAINTE de fix; dupa fix, exact aceeasi comanda da PASS. Fara ambele rulari, bug-ul nu e inchis. ## Scripturi Toate in `D:\ROA\ROAFACTURARE\COMUN\utile\Teste\`: - `D:\ROA\ROAFACTURARE\COMUN\utile\Teste\vfp_ui_harness.ps1` - orchestrator UI: `powershell -File vfp_ui_harness.ps1 -TestPrg -Steps @('pas0','pas1')`. - `D:\ROA\ROAFACTURARE\COMUN\utile\Teste\watchdog_vfp.ps1` - dialoguri native: `powershell -File watchdog_vfp.ps1 -Script -AutoDismiss` (captura PNG + text). - `D:\ROA\ROAFACTURARE\COMUN\utile\Teste\_precompile.ps1` - precompilare izolata, rulata in proces copil (`Start-Process -Wait`). - `D:\ROA\ROAFACTURARE\COMUN\utile\Teste\raport_teste.ps1` - sumar PASS/FAIL din loguri. - Comanda headless, lansata din PowerShell cu timeout: `vfp9.exe -A -T "" `, cu `$p.WaitForExit(120000)` si `$p.Kill()` daca nu iese. - Mediu: `D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg`. - Handshake UI: `ui_harness.prg`, `mock_amessagebox.prg` (incarcate cu `SET PROCEDURE ... ADDITIVE`). ## Referinta (doar la nevoie) - Doar daca depanezi headless sau lucrezi la harness UI, citeste `COMUN\docs\depanare_testare_vfp.md` (sec. 6-7) si `COMUN\docs\testare-ui-vfp.md`.