- leaga_skills.ps1: expune skill-urile in ~/.claude/skills prin symlink (citit si de Claude Code, si de opencode), fara copiere - rutare zona->skill in reguli_lucru pct. 7, README, AGENTS.md; skill-ul devine proprietarul procedurii, docurile raman referinta conditionata - rec_skills.md: decizia, inventarul si cum se adauga un skill nou
110 lines
7.9 KiB
Markdown
110 lines
7.9 KiB
Markdown
---
|
|
name: roa-vfp-headless-test
|
|
description: Ruleaza si depaneaza teste VFP 9 fara IDE (headless) cu vfp9.exe -A -T "<script.prg>" <param> 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 <n>, '<mesaj>'`, la final `DO HarnessDone WITH 'done'`. Apoi
|
|
`vfp_ui_harness.ps1 -TestPrg <test.prg> -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_<n>_<eticheta>.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 <test.prg> -Steps @('pas0','pas1')`.
|
|
- `D:\ROA\ROAFACTURARE\COMUN\utile\Teste\watchdog_vfp.ps1` - dialoguri native:
|
|
`powershell -File watchdog_vfp.ps1 -Script <test.prg> -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 "<script.prg>" <param>`, 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`.
|