User guide — Full Testing Web (FTW)
This guide explains how to use Full Testing Web, the web control panel that orchestrates the Full Testing AI automation framework against the demo application Banco Americano. It is written for the QA team: what each screen does, how tests are authored with AI, the exact decision rules of the natural-language automation and the self-healing, and where every artifact lives.
The same guide exists in Spanish (user-guide.es.md) and can be read inside
the app itself on the User Guide page in the sidebar.
1. What FTW is and how it fits into the ecosystem
FTW is a FastAPI + Jinja + htmx application running locally
(http://localhost:9000). It does not execute tests itself: it coordinates
three pieces:
┌──────────────────────────────────────────────┐
│ FPD — Full Project Director (port 8000) │
│ · Serves the app under test: Banco Americano│
│ (/playground/banco-americano) │
reads test cases │ · Test-case API (GET /api/tcs) │
(GET /api/tcs) │ · LLM gateway │
┌──────────────────┐ │ (POST /api/ai/complete, task=generation) │
│ │ ─▶ └──────────────────────────────────────────────┘
│ Full Testing │ ▲
│ Web (FTW) │ ───────────────┘ every AI call goes through FPD
│ port 9000 │ LLM calls with the FTW_FPD_TOKEN
│ │
│ FastAPI + htmx │ ┌──────────────────────────────────────────────┐
│ │ │ Full Testing AI (framework, separate repo) │
│ Spawns Maven │ ─▶│ Java 21 · Maven · JUnit 5 · Playwright │
│ processes and │ │ POM + Flow Objects pattern │
│ reads results │ │ Portable toolchain: ../.tools/jdk, │
└───────┬──────────┘ │ ../.tools/maven │
│ └───────────────┬──────────────────────────────┘
│ push to main only when │ push (always a human decision)
│ a human hits Publish ▼
│ ┌──────────────────┐
└────────────────────▶│ GitHub (repo │
│ full-testing-ai, │
│ Actions CI) │
└──────────────────┘
- FPD (Full Project Director) — the host application. It serves Banco
Americano (the app under test), the test-case (TC) read API, and the
only gateway to the LLM:
POST /api/ai/completewithtask: "generation". FTW never talks to the AI provider directly. - Full Testing AI (FTA) — the test framework, an independent repo in
Java 21 / Maven / JUnit 5 / Playwright with a hybrid POM + Flow Objects
pattern (three layers: page objects with locators and atomic actions; flow
objects with reusable business flows like login; tests with orchestration
and assertions). Executed tests are deterministic code: AI only takes
part in authoring and healing, never inside
mvn test. - GitHub — the
JulioCOropeza/full-testing-airepo with GitHub Actions (tests.yml, manualworkflow_dispatch). Nothing runs on private servers.
The publish philosophy (golden rule)
The framework repo is treated as read-only. FTW reads files (coverage registry, sources, surefire reports) and runs the framework's own Maven commands, but it never writes to the repo until a human hits a publish button:
- Push to main on a scaffold or a verified automation.
- Apply & push to main on a finished refactor.
- In self-healing, main is never touched: the fix is pushed to a
heal/...branch and a PR is suggested for human review.
On top of that, publish buttons only version exactly the files that job
generated (never git add -A): unrelated changes you may have in the
framework working tree are never touched. The one deliberate exception: a
dirty coverage/coverage.json (regenerated by the verification run) rides
along in the publish commit, so the @Covers registration reaches main
together with the code.
Verification gates: nothing reaches main unverified. The NL automation
path only enables Push to main at status verified (green headless run);
the refactor path has the same gate since 2026-08-04 — Apply & push to
main stays locked until Verify before publish goes green, and the
server refuses the publish otherwise (HTTP 409).
Closing the loop: after a successful push, FTW immediately posts the
coverage registry to FPD (POST /api/tcs/automations/coverage), so FPD's
"Run automated" button knows about the new automation right away — no
GitHub Actions run needed. The sync is soft-fail: it never blocks a
publish.
Rollback: every publish is recorded (see Publishes on the Run page)
and can be undone with one click. Rollback is a git revert --no-edit +
push — history keeps both the publish and its revert, never a reset or
force-push — followed by the same coverage sync, so FPD ends consistent
with the reverted state. If the revert conflicts (later commits touched
those files), it is aborted and reported for manual resolution;
nothing is forced.
2. Getting started
Prerequisites: Python 3.12+, the full-testing-ai repo checked out with its
portable toolchain (TestProjects/.tools/jdk and .tools/maven), and FPD
running on port 8000.
cd /c/Users/JulioAI/TestProjects/full-testing-web
.venv/Scripts/python -m uvicorn app.main:app --port 9000
To enable the TC Explorer and every AI feature you need an FPD API token (in
FPD: Profile → API tokens, starts with fpd_). Configure it with the
FTW_FPD_TOKEN environment variable or in the .env file (see
.env.example). Without a token the app still starts, but the TC Explorer is
disabled and the AI features cannot reach the LLM.
3. Screen tour
3.1 Dashboard (/)
Environment health panel:
- Framework: whether the
full-testing-aidirectory exists and containscoverage/coverage.json(the coverage registry). - Banco Americano: whether the app under test answers (GET on the bank login page).
- FPD API: whether
GET /api/tcsanswers (an anonymous 401 already counts as "up"). - Coverage: how many TC keys are in the registry and, with a token configured, how many FPD TCs are automated vs. not automated.
- Discovered test classes: table of every
*Test.javaclass found in the framework with its@Covers("TC-KEY")annotations (abstract base classes are skipped).
3.2 TC Explorer (/tcs)
Lists the FPD test cases (GET /api/tcs, with server-side q search). Each
row shows:
- Key, title and folder of the TC.
- Coverage state: green badge Automated → Class#method (the TC key is
in the framework's
coverage/coverage.jsonregistry as committed on origin/main), amber badge Automated (unpublished) when the coverage entry exists only in the local registry — generated by a local verify run and not pushed to main yet (tooltip: "generated locally, not pushed to main yet") — or amber badge Not automated. The comparison readsgit show origin/main:coverage/coverage.json(falling back toHEAD, and to plain local behavior when git fails). - Expand: loads the full TC spec (precondition + action → expected steps
table) and two AI authoring buttons: Scaffold test and
Automate with AI (with a
headlesscheckbox). If the TC is already covered, an amberalready covered by ...warning appears to prevent duplicate coverage. When the TC is Automated (unpublished), a Push to main button also appears: it commits and pushes exactly the files generated for that TC (recovered from the persisted automation records — the automation job pages are in-memory and gone after a restart) plus the dirty local coverage registry, and re-syncs coverage to FPD — the recovery path when the push was not done at automation time.
Both buttons are explained in detail in section 4.
3.3 Run (/run)
Launches the framework suite as a background job (mvn -B test).
The form offers:
- Scope:
All tests,Bank UI only(TransferFlowTest + DepositVariationsTest),FPD API only(FpdTcsApiTest), or a single discovered class. - Headless browser: windowless browser (passed as
FTA_HEADLESS). - Auto-heal with AI on failure: automatic self-healing for this run — checked by default; it is the per-run opt-out (see section 5).
- Device: emulation profile (Desktop, iPhone 13, Pixel 7, iPad; passed as
FTA_DEVICEwith viewport, user-agent and touch). - Base URL: which server to run against (passed as
FTA_BASE_URL; defaults to the local FPD).
While running, the job page (/run/{id}) refreshes itself every 2
seconds (htmx) showing the live Maven log. When finished it shows:
- Summary cards: tests, passed, failures, errors, skipped and time.
- Per failure: class#method, message, stack trace, inline screenshot and
a link to the page HTML captured at failure time (artifacts served from
the framework's
target/artifacts/). - Allure report button: generates (or regenerates) the static Allure
site for that run from its stored results and opens it at a permanent
per-run URL (
/reports/allure/<run-id>/index.html) — every run keeps its own report, not the latest generated one. - The self-healing sections (see section 5): the automatic-heal list with its classifications, and the manual Heal ... with AI buttons, one per failed class.
Run pages are persistent: every run is recorded in
recordings/runs.json (scope, options, status, summary and self-healing
decisions) and its page keeps rendering after an FTW restart (the live Maven
log itself is memory-only). A run that was in flight when FTW restarted
comes back as interrupted (server restarted mid-run).
Below the form, the Recent runs section lists the latest persisted runs (newest first: start time, scope, status badge, passed/total and any auto-heal classifications), each linking to its run page.
Below the form, the Publishes section lists the pushes to origin main
made from this panel (newest first: short sha, source — scaffold / refactor
/ automate — TC key, message and timestamp). Each entry that is still live
offers a Rollback button: git revert --no-edit + push (history keeps
both commits — never a reset or force-push) followed by a coverage re-sync
to FPD, so the reverted state is consistent everywhere. A revert that
conflicts with later commits is aborted and reported as "conflict —
resolve manually". Already-rolled-back entries show a gray badge with their
revert commit.
Known limitations of this screen:
- The live Maven log is not retained across restarts: past run pages show the summary, failures and Allure, but not the log.
- Lists rendered at page load (like the Record & Play recordings list) do not refresh themselves: press F5 to see new entries.
3.4 Record & Play (/record)
Records a manual flow and turns it into raw Playwright Java code:
- Pick the TC: an FPD-backed select (with coverage badge) when a token is configured, or a free-text key field otherwise.
- System under test: a dropdown fed by the Systems registry
(
config/apps.json, see §3.5) shown asname — start_url; the recording starts at the app's configured URL. A Custom URL… option reveals the old free-text field as an escape hatch — only http(s) URLs without&or spaces (shell-safety whitelist), and every URL, configured or custom, passes the same whitelist before reaching the command line. - Device: recording viewport (full emulation applies later at run time
via
FTA_DEVICE). - Start recording: a real browser window opens on this machine
(Playwright codegen via
mvn exec:java). Perform the flow normally; the code is flushed to the output file as you record. - To finish, close the browser window: it is the clean way and keeps
everything recorded. The Stop button kills the session
(
taskkill /T /F) and may lose the last actions not yet flushed — the UI itself warns about this.
The job page shows the codegen log and the captured Java. When done,
the file is saved to recordings/<tc-key>-<yyyymmdd-HHMMSS>.java (a
git-ignored folder) and appears in the Saved recordings panel on the
right. Recordings are grouped by TC key (parsed from the file name; files
whose names don't match the pattern fall under Other), each group a
collapsible section showing its recording count and latest saved date, with
the newest recordings first inside. Actions per recording:
View / Download / Refactor / Delete — Delete is permanent (no trash) and
asks for confirmation first. The list is rendered when the page loads: if you
finish a recording with the page open, press F5 to see it.
3.5 Systems (/systems)
The systems under test registry — the panel for config/apps.json:
- List: every configured app with its key, name,
start_urland user role names (credentials are never displayed). - Add / Edit / Delete: name and
start_urlare required; the URL must be http(s) and pass the same shell-safety whitelist as Record & Play. The key of a new system is derived from its name (lowercase slug, suffixed if it collides). Edit keeps the app'susersblock untouched — manage credentials by editingconfig/apps.jsondirectly. - No restart: the file is hot-reloaded, so changes apply immediately.
The page writes the file back as canonical 2-space-indented JSON,
preserving its structure (
{key: {name, start_url, users{role: creds}}}).
This registry is shared: the Record & Play dropdown lists it (§3.4) and Automate with AI reads the same entry for its start URL and login credentials (§4.3).
4. AI authoring
The three authoring features share the same model: the AI generates code following the framework's live conventions, the result is saved outside the repo for review, and only a human publishes it with a button.
4.1 Scaffold test (from a TC)
What it does: runs the framework's TestScaffolder tool
(mvn -q test-compile exec:java) to create the skeleton of a test class from
the TC key.
Steps: TC Explorer → TC row → Expand → Scaffold test button (it may take a minute: it is Maven).
What gets written where: a new *.java file under the app's tests
directory in the framework repo, with @Covers("<key>"), the spec title as
javadoc, and a single @Disabled method with one
// TODO(step n): <action> -> <expected> comment per TC step. It compiles
but does not run until implemented. It never overwrites an existing file.
Decision rules:
- The dedup check runs first: if the key is already in
coverage/coverage.json, nothing is written and an amberALREADY COVERED by ...box is shown (extend the existing test instead of creating a new one). - Conflict (the file already exists): aborts without writing.
Publishing: the result offers a Push to main button that commits and
pushes to origin main only the generated file (plus a dirty
coverage/coverage.json, if one exists). After the push, FTW syncs the
coverage registry to FPD immediately and the result page offers a
Rollback button (revert + push, never a reset). Once published, the
button renders disabled with an Already pushed (\<short sha>) tooltip
(a rollback unlocks it). You can also review it
in the repo and delete it if unwanted.
4.2 Refactor with AI (on a recording)
What it does: rewrites raw Playwright codegen Java into the framework's conventions (POM + Flow Objects, Allure, DataFactory) using FPD's LLM.
Steps: Record & Play → finish a recording → Refactor button (on the finished job page or in the saved-recordings list). The refactor page refreshes itself every 2 seconds while the AI works.
How it works: the raw Java is sent to POST {FPD}/api/ai/complete with a
prompt enriched with the framework's real conventions: an inventory of
existing pages/flows (scanned from bank/pages and bank/flows), the
scaffolder's own templates, a real test as style anchor, and the TC's
coverage state. The AI answers strict JSON
{files: [{kind, class_name, package, code}], notes} which is
shape-validated (max 8 files, 60,000 chars per file, valid class and package
names).
What gets written where: the validated files are saved to
recordings/<base>.refactored/ for review — the framework repo stays
untouched.
Verify before publish (the gate): a finished refactor cannot be
published directly. The Verify before publish button applies the files
into the framework checkout (all-or-nothing, same semantics as publish) and
runs the produced test class headless (mvn test -Dtest=<Class>); the page
polls itself while the run executes. On green, the job shows a Verified
badge with the run summary and the publish button unlocks. On failure, the
page shows the failure summary (compilation errors or failed cases with
screenshot / page HTML links), nothing is committed or pushed, and the
publish button stays locked: fix the code in the framework checkout and
hit Re-verify — the re-run tests the checkout as-is, so your manual
fixes are what gets verified. The server enforces the same rule: publishing
an unverified refactor is refused with HTTP 409.
Publishing: Apply & push to main on a verified job commits the
checkout state of the generated files (what was verified green, manual
fixes included) — pages and flows live under src/main/java, tests under
src/test/java — plus the regenerated coverage/coverage.json, and pushes
to origin main. If any target already exists with different content,
the whole publish aborts (nothing is overwritten): reconcile by hand in
the repo. After the push, FTW immediately syncs the coverage registry to
FPD (soft-fail) and the result page offers a Rollback button.
4.3 Automate with AI (natural-language automation)
What it does: turns a manual FPD test case (natural-language steps + expected results) into a deterministic Java test, green and verified, in one click.
Steps: TC Explorer → TC row → Expand → Automate with AI button
(headless checkbox on by default). The job page opens, refreshing every 2
seconds, and automatically chains every stage:
discovery → generating → applied → verifying ⇄ healing → verified.
Stage 1 — Discovery
An agent drives a real Chromium browser through native Python Playwright (no Node.js: the original plan called for Playwright MCP, but the host has no Node; the technique is the same — aria snapshot + refs — and the owner accepted the deviation after checking that every acceptance failure was in Java codegen, never in browser driving).
On each iteration the loop:
- Tags visible interactive elements with
data-fta-refattributes (max 80 refs) and takes an aria snapshot of the page (max 12,000 chars). - Sends to FPD (
/api/ai/complete, taskgeneration) the TC spec (steps and expected results), the app config (start URL and users/roles fromconfig/apps.json), the snapshot, the ref table, and the action history. - Receives one strict-JSON action
(
click | fill | press | navigate | assert_text | assert_visible | done | fail), executes it in the browser, and records the outcome. Errors are fed back into the next prompt, so the loop self-corrects online.
The result is an action log: ordered steps with concrete locator
strategies (priority data-testid > role+name > css > text), typed values,
and per-step success. It is persisted to
recordings/automations/<TC>-<timestamp>.json.
Discovery guardrails: max 40 steps by default (cap 200), 15-minute wall
clock, 8 s page timeout, and abort after 3 consecutive LLM call failures
(endpoint down or bad token). The model declares done only when it executed
every step and verified every expected result; fail when the case cannot be
completed.
Stage 2 — Generating (Java conversion)
The action log is converted to Java reusing the Refactor with AI profile
plus hardening rules learned from acceptance runs: exact
DataFactory/Money signatures, the admin-precondition pattern, substring
assertions (never exact-string equality for assert_text), a preference for
composing Flow classes, the correct TestConfig package, annotations in the
right place (@Covers/@Feature/@Story at class level; @Description/@Test
on the method), and no invented assertions beyond what the discovery
observed. Complete, compilable files are generated under the POM + Flows
conventions (pages in bank/pages, flows in bank/flows, test in
bank/tests) and staged in recordings/automations/<stem>.generated/.
Stage 3 — Applied (writing into the framework)
The staged files are written into the framework checkout with an all-or-nothing policy: if any target exists with different content, the stage fails without writing anything and must be reconciled by hand (the UI explains this and offers a pipeline re-run).
Stage 4 — Verifying (and auto-repair)
mvn test -Dtest=<GeneratedClass> runs headless. "Verified" means
exactly: the run finished cleanly, the surefire report for that class
exists, and it has 0 failures and 0 errors.
On failure, the auto-repair loop kicks in (orange healing badge), up to
2 rounds:
- Failure evidence is distilled (javac/surefire
[ERROR]lines or failed case details, capped at ~6–8k chars) together with the current file contents. - The LLM proposes corrected files (same class names).
- They are re-applied with a strict guard: only files this very job generated may be overwritten.
- Headless re-verify. If still red, a second and final round.
Publishing — Push to main
The Push to main button is only enabled at status verified. It is a
human decision: it commits only the files the job applied (message
NL automation of <TC> into POM/Flows (job <id>), plus the regenerated
coverage/coverage.json when the verify run left it dirty) and pushes them
to origin main. Right after the push, FTW posts the coverage registry to
FPD (soft-fail), so the TC flips to automated in FPD without waiting for
a GitHub Actions run, and the publish outcome offers a Rollback button
(revert + push, never a reset). From that point the button renders
disabled with an Already pushed (\<short sha>) tooltip — FTW records
every publish and locks the button against double-pushing; a rollback
unlocks it again.
The owner's economic goal: the first pass pays for discovery and
generation; every rerun afterwards is plain mvn test — zero AI cost,
fully deterministic.
Exact decision rules, summarized:
| Question | Rule |
|---|---|
| When does discovery retry an action? | When the action fails or the reply is not valid JSON, the error is fed back into the next prompt (each attempt consumes 1 step of the budget). |
| When does discovery abort? | 3 consecutive LLM failures, 40 steps exhausted (cap 200), 15-minute wall clock, or the model declares fail. |
| How many repair rounds? | At most 2 (MAX_REPAIR_ROUNDS), each re-verified. |
| What is "verified"? | A finished mvn run + a surefire report for the generated class with 0 failures and 0 errors. |
| When does it push to main? | Never automatically: only when a human hits Push to main at status verified. |
| What if apply hits a conflict? | All-or-nothing: nothing is written; the human reconciles in the repo and re-runs the pipeline. |
5. Self-healing — the full rule set
Self-healing fixes tests that fail on rerun because the application changed (typically a locator), and proposes the fix as a PR for human review. It is the piece with the strictest rules in the module.
5.1 Auto-trigger on ANY failed run
Healing fires automatically when any run finishes with failures (a runner hook), as long as two conditions hold:
- the master switch
FTW_AUTO_HEAL(on by default), and - the per-run Auto-heal with AI on failure checkbox in the Run form (checked by default — uncheck it to exclude that run, e.g. in demos).
The Heal ... with AI button on the results page is only the manual path; it is never the only mechanism. The automation pipeline's internal verification runs never trigger healing (they have their own repair loop).
5.2 Failure classifier
Each failed case is classified with the framework's FailureAnalyzer
heuristics (same precedence order), using the failure message and the visible
text of the captured page HTML:
| Category | Signature | Auto-healed? |
|---|---|---|
LOCATOR_DRIFT |
TimeoutError / "timeout" / "waiting for ..." in the output (the element no longer appears) |
Yes — the only eligible category |
BEHAVIOR_MISMATCH |
Assertion failure (AssertionFailedError, expected...) — the app responds but not as the spec says |
No, never: it is a candidate real bug and gets reported |
APP_ERROR |
The captured page is a 5xx (internal server error, bad gateway, etc.) | No, never: an application bug, gets reported |
UNKNOWN |
None of the above | Only if it still carries a timeout/"waiting for" signature; otherwise no |
Fundamental rule: BEHAVIOR_MISMATCH and APP_ERROR are never auto-healed —
that would mask real application bugs. On the results page each failure shows
its classification and, when not healable, the note
not online-healable — review as a likely app bug.
5.3 Guards and limits
- Max 2 heal rounds per test class (
HEAL_ROUNDS = 2), each verified before the next is attempted. - Max 3 auto-heals per run (
MAX_AUTO_HEALS_PER_RUN = 3); from the fourth eligible failure on, the entry is notedauto-heal cap reached — use the manual button. - One heal job per class+method at a time (duplicates in flight are refused).
- Per-run opt-out via the form checkbox (default ON) plus the
FTW_AUTO_HEALmaster switch.
5.4 What a heal job does
- Evidence (max 8,000 chars): from the class's newest surefire XML, the stack trace and the locator line that timed out ("waiting for ..."); plus the newest captured HTML snapshot of the failing step (title and visible text of the current page).
- Context: current content of the test class and the pages/flows it imports.
- LLM (same
/api/ai/completechannel, 600 s timeout): HEAL-mode prompt — minimal diff, fix only what the evidence points at (typically a stale locator in a page object), never weaken assertions, rename, or create classes; it may only return corrected versions of the given files. A page-object-only fix is valid. - Apply with the strictest guard: overwrite only existing files
directly under
bank/tests|pages|flows, all-or-nothing, keeping the previous content of every file. - Headless re-verify (
mvn test -Dtest=<Class>). If still red, a second and final round with the new evidence. There is one extra retry within the same round on transport errors (e.g. a read timeout does not burn a round).
5.5 Possible outcomes
- Healed and verified (green): a
heal/<Class>-<timestamp>branch is created, only the healed files are committed and pushed, and the UI shows the compare link to open the PR (/compare/main...<branch>). The merge is always human — nothing is ever committed tomain. The checkout returns tomainwhen done. - Green but empty diff vs main (the "failure" came from uncommitted local
edits, not real drift): no branch is created and the job carries the note
healed — no diff vs main, nothing to PR. - Failure (out of rounds or error): full revert — every overwritten file is restored to its pre-heal content; the framework tree is never left dirty.
- If the PR suggestion fails (e.g. git without credentials) but the fix
verified, the job stays
healedwith the error recorded (pr_error) — the fix remains in the working tree.
You can follow any heal live on its page (/heal/{id}, refreshes every 2 s)
with attempt details, evidence, changed files, branch and PR link.
5.6 Known operational caveat
Heal LLM calls can hit FPD's ~240 s AI upstream ceiling when the provider
is degraded (observed: 28 s even for one-word replies, and 502 on full-file
generations), even though the heal channel waits up to 600 s. Typical
symptom: heal jobs failing with ReadTimeout/502 on degraded days. It is not
an FTW bug. On the backlog: shrinking the heal prompt (mapping the failing
locator to the file containing it, so only the test + matching files are
sent) and, on the FPD side, a wider AI upstream timeout or a dedicated
cheaper/faster model for heals.
6. Configuration reference
All settings are environment variables with defaults matching the local
demo layout (see app/config.py). A .env file at the project root is also
supported (copy from .env.example; real environment variables take
precedence).
| Variable | Default | Meaning |
|---|---|---|
FTW_FRAMEWORK_DIR |
C:\Users\JulioAI\TestProjects\full-testing-ai |
Framework repo root (read-only except publish) |
FTW_JAVA_HOME |
C:\Users\JulioAI\TestProjects\.tools\jdk |
Portable JDK (Temurin 21) for Maven subprocesses |
FTW_MVN |
C:\Users\JulioAI\TestProjects\.tools\maven\bin\mvn.cmd |
Portable Maven launcher (3.9.16) |
FTW_FPD_BASE_URL |
http://localhost:8000 |
FPD server (bank app + TC API + LLM gateway) |
FTW_FPD_TOKEN |
(empty) | FPD Bearer token; empty = TC Explorer and AI disabled |
FTW_PORT |
9000 |
Port for this app |
FTW_AUTO_HEAL |
true |
Master switch for automatic self-healing |
Additional configuration:
config/apps.json— the systems-under-test registry:start_urland users/roles with credentials per app. Editable by hand or from the Systems page (§3.5); hot-reloaded, no restart needed. It feeds the Record & Play dropdown and the NL automation alike. Today it only definesbanco-americano.- Code constants (not environment variables): pipeline repair rounds
MAX_REPAIR_ROUNDS = 2and discovery budgets (40 steps, 15 min) inapp/services/automate_service.py; heal roundsHEAL_ROUNDS = 2and heal LLM timeoutHEAL_LLM_TIMEOUT = 600 sinapp/services/heal_service.py; auto-heals per runMAX_AUTO_HEALS_PER_RUN = 3inapp/config.py. - Portable toolchain: no system Java/Maven needed; FTW passes
JAVA_HOMEand the portablemvn.cmdto every subprocess, wrapping calls incmd.exe /c(Windows cannot exec batch files directly) with strict validation of everything that reaches the command line.
7. Troubleshooting & FAQ
The TC Explorer says "FPD token required".
Create a token in FPD (Profile → API tokens, starts with fpd_) and start
FTW with FTW_FPD_TOKEN=fpd_... or put it in .env.
A run queues but nothing happens.
While executing, run jobs are in-memory threads: if FTW restarted mid-run,
the job died and its page shows the interrupted status (finished runs do
survive the restart with their summary and Allure). Check the FTW log (the
uvicorn output; in the current nohup setup,
/tmp/ftw-9000.log), that the framework exists at FTW_FRAMEWORK_DIR, and
that the portable toolchain is under .tools/. Large Maven runs take a
while: the pipeline's internal verification waits up to 15 minutes before
declaring a timeout.
Symptoms of AI provider degradation.
Slow replies (tens of seconds for any call), 502 from FPD's upstream (~240 s
ceiling), discovery aborting with "LLM endpoint failed 3 times in a row",
refactors/automations failing at the LLM call, heals dying with
ReadTimeout. It is not an FTW bug: wait for the provider to recover and
retry (failed pipelines can be re-run from their page).
Where are the logs and artifacts?
| What | Where |
|---|---|
| Surefire reports (XML) | full-testing-ai/target/surefire-reports/ |
| Failure screenshots and HTML | full-testing-ai/target/artifacts/<Class>/ |
| Allure results | full-testing-ai/target/allure-results/ (site: target/site/allure-maven-plugin/) |
| Run registry (Recent runs) | full-testing-web/recordings/runs.json |
| Per-run Allure results + sites | full-testing-web/recordings/runs/<run-id>/{results,report}/ |
| Framework triage report | full-testing-ai/target/triage/triage-report.md |
| Recordings | full-testing-web/recordings/ |
| Discovery results (action logs) | full-testing-web/recordings/automations/*.json |
| Generated Java (staging) | full-testing-web/recordings/automations/<stem>.generated/ |
| Refactor outputs | full-testing-web/recordings/<base>.refactored/ |
| Heal staging | full-testing-web/recordings/heals/ |
| FTW log | uvicorn output (currently /tmp/ftw-9000.log) |
How do I keep self-healing out of a demo?
Uncheck Auto-heal with AI on failure in the Run form for that run (the
per-run opt-out), or start FTW with FTW_AUTO_HEAL=false to turn the master
switch off.
An automation failed at the applied stage with a conflict.
Someone already created those files in the repo with different content.
Reconcile by hand in full-testing-ai (keep the repo version or replace it
with the staged one the UI points to) and hit Re-run pipeline on the job
page.
The automation generated an odd class name (e.g. ...DiscoveryTest).
It is harmless and known (on the polish backlog). The test is valid as is.
Does AI get involved when rerunning already-automated tests?
No. Reruns are deterministic mvn test, with zero AI cost. The only
exception is self-healing: it fires only if the run fails, only for
LOCATOR_DRIFT failures, within the limits of section 5, and its fix reaches
main only after human PR review.
Record & Play lost the last actions when stopping. Known: the Stop button kills the process and may lose what was not flushed. Close the browser window to finish cleanly (the file is written as you record).
8. Further reading
full-testing-web/README.md— technical architecture, Windows notes, and the read-only/publish philosophy.full-testing-ai/docs/decisions.md— living register of approved decisions and guard rails (the authoritative specification of the rules).full-testing-ai/docs/ai-authoring.md— the authoring loop inside the framework repo (scaffolder, triage, coverage).
Source: docs/user-guide.en.md — rendered at request time.