Test Cases with Custom Fields Report Modernized - sebiboga/testlink-upgraded GitHub Wiki
Modernization of Test Cases with Custom Fields (lib/results/testCasesWithCF.php)
โ GitHub issue #737.
The legacy Smarty screen is replaced by a standalone Dashio page
(gui/templates/results/tcasesWithCF.html) backed by a plain-PHP REST BFF
action inside api/reports/index.php (action=tcases_with_cf). The ASIDE
Reports โ Test Cases with Custom Fields entry now points to the new HTML
screen when a test plan is selected.
Path: Reports โ Test Cases with Custom Fields
URL: gui/templates/results/tcasesWithCF.html?tproject_id=<id>&tplan_id=<id>
BFF API: api/reports/index.php?action=tcases_with_cf&tproject_id=<id>&tplan_id=<id>
Right: report_view enforced server-side (same as legacy).
| Feature | Legacy behavior | Modern implementation |
|---|---|---|
| Page load |
testCasesWithCF.php loads CF definitions via cfield_mgr::get_linked_cfields_at_execution()
|
BFF action fetches same CF definitions, returns them as cfinfo array |
| Filter toolbar | Test Suite dropdown, Test Case dropdown, Build dropdown, Show button | identical: three comboboxes + Show button; cascading refresh on selection |
| Empty state | Table shown with "No custom fields" warning | Info panel with translated message, no table rendered |
| Results table | Static HTML table with dynamic columns for each CF | DataTables with sort, search, pagination; columns: Test Suite, Test Case, Version, Build, Tester, Date, Status, Execution Notes + one column per CF |
| CF values | Rendered from executions.rows[].cfields array |
Same data shape; cfinfo drives column headers |
| Status badges | Plain text with color spans | Bootstrap badges with status-based coloring |
| Locale | Server-side Smarty lang
|
Client-side TLi18n module; 18 locale switcher |
All routes require an authenticated session; callers without report_view get 403.
Returns test case execution results with custom field values.
Query parameters:
| Parameter | Required | Description |
|---|---|---|
tproject_id |
Yes | Test project ID |
tplan_id |
Yes | Test plan ID |
tcase_id |
No | Filter to specific test case |
build_id |
No | Filter to specific build |
Response:
{
"status": "ok",
"cfinfo": [
{ "field_id": 6, "name": "CF_Environment", "label": "Environment" }
],
"gui": {
"testsuite": "Test Suite",
"testcase": "Test Case",
"build": "Build",
"status": "Status"
},
"executions": {
"header": [
"Test Suite", "Test Case", "Version", "Build",
"Tester", "Date", "Status", "Execution Notes"
],
"rows": [
{
"testsuite_name": "Suite A",
"tc_external_id": 1,
"tcase_name": "TC with CF",
"version": 1,
"build_name": "Build 1",
"login": "admin",
"execution_ts": "2026-08-25 19:58:13",
"status": "failed",
"notes": "Failed - regression",
"cfields": { "Environment": "Staging" }
}
]
}
}- CF definitions fetched via same
cfield_mgr::get_linked_cfields_at_execution()path - Execution rows built from same DB query (executions + tcversions + builds + cfield_values)
-
getPathLayered()null guard added to handle missing CF definitions gracefully - Test Suite / Test Case / Build cascading filter mirrors legacy dropdown behavior
- Status coloring uses same hex values as legacy Smarty template
All strings use TLi18n keys; no hardcoded text.
| Key | English value |
|---|---|
tcwcf.title |
Test Cases with Custom Fields |
tcwcf.subtitle |
for test plan |
tcwcf.noCF |
No custom fields defined for test cases or executions |
tcwcf.showBtn |
Show |
tcwcf.matchCount |
Match count: |
testsuite |
Test Suite |
testcase |
Test Case |
build |
Build |
status |
Status |
common.filter |
Filter: |
common.showEntries |
Show |
common.entries |
entries |
common.pageInfo |
Showing %s to %s of %s entries |
common.prev |
Previous |
common.next |
Next |
common.errorLoading |
Error loading data |
Keys present in all 11 locale bundles (en, ro, de, fr, es, it, ja, pt, ru, zh, plus the base en).
- Session-based authentication enforced at BFF entry point
-
report_viewright checked server-side before any DB query -
tproject_idvalidated against user's allowed projects - All output escaped via
htmlspecialchars()in DataTables rendering
Test suite #37 in tmp/TLU_Test_Cases.md โ 15 test cases covering:
- Screen load without PHP warnings
- Empty state when no CFs defined
- Filter dropdown population and cascading
- Results table columns and data correctness
- Custom field value display
- DataTable pagination and search
- Locale switcher translation
- Aside menu link target
- API data response format
- API 401 without session
- Event Viewer cleanliness
- View-only user permissions
A parity pass against the legacy controller closed the last two behavioural gaps of this report and retired the legacy renderer.
Legacy openExecutionWindow(tcase_id, tcversion_id, builds_id, tplan_id, platform_id)
always appended setting_build and setting_platform. The modern Execute icon now does
the same (gui/templates/results/tcasesWithCF.html), so the Set Results popup opens on the
build/platform the report row was recorded on instead of falling back to the plan default:
/gui/templates/execute/execSetResults.html?tcase_id=4&tcversion_id=5&tproject_id=1&tplan_id=2&setting_build=1&setting_platform=0
The italic legacy note ("This Report shows all test cases with any custom field set on test
execution. In addition the execution notes are shown for applicable test cases.") and the
Generated on <timestamp> โ Elapsed: Ns line are back at the bottom of the report. The BFF
api/reports/index.php?action=tcases_with_cf now returns a generated_on field on both
success payloads (the linked-TC list and the no-linked-TC early return).
New i18n keys: tcwcf.infoText, tcwcf.generatedOn (all 10 bundles).
-
lib/results/testCasesWithCF.phpis now a session-guarded, non-mutating launcher (same pattern aslib/results/keywordBarChart.php):- authenticated browser
GET/HEADโ302togui/templates/results/tcasesWithCF.html, withtproject_id/tplan_idpreserved (and the legacy session fallback); - write verbs and XHR / non-document callers โ
405JSONmodern_endpoint_only; - anonymous callers โ
login.php?note=expired(the legacytestlinkInitPage()contract).
- authenticated browser
-
gui/templates/dashio/results/testCasesWithCF.tplremoved. -
cfg/reports.cfg.phptcases_with_cfurl repointed to the modern HTML (the ASIDE menu already overrode the link).
Correction to ยง5: this BFF enforces the
testplan_metricsright (on the owning test project and plan), the same right the legacy controller used โ notreport_view.


Fixture tmp/fixtures_tcwcf.php; suite Issue #1207/#1208/#1209 in tmp/TLU_Test_Cases.md
โ 24/24 PASS (BFF payload, Execute URL, footer, all four shim branches, array-param safety,
events clean).