Free Test Cases (freeTestCases) - sebiboga/testlink-upgraded GitHub Wiki
The Free Test Cases report lists test cases in a project that are not assigned to any test plan. The modern implementation (Dashio-based) provides a DataTables view with columns for Test Suite, Test Case (with external ID and name), and optionally Priority. Each test case row includes an edit/design link to open the test case in a new window.
Key features:
- Filters by project (
tproject_id) - Shows priority column if project has priority enabled
- Provides edit link per row (pencil icon) to open
tcView.html?tcase_id=<id>&tproject_id=<id>in a new window
Refs: #1263
The report grid now reproduces the full legacy tlExtTable presentation (legacy refs:
lib/results/freeTestCases.php:110-118, getColumnsDefinition():138-150,
lib/functions/exttable.class.php:50-60,525-537,588-591, gui/templates/dashio/include/inc_ext_table.tpl):
-
Collapsible group-by-Test-Suite headers —
Test Suite: <path> (N Items)per suite (DataTables RowGroup plugin), the grouped Test Suite column hidden from the grid exactly like legacyhideGroupedColumn=true; click a header to collapse/expand that group. - 6-button grid toolbar — Expand/Collapse Groups (toggles all), Show all Columns (reveals the grouped column + its filter cell), Reset to Default State (filters, groups, multi-sort, order), Refresh (ajax reload), Reset Filters (auto-appears only while a filter is active), MultiSort.
-
Per-column filters in the table footer — text inputs for Test Suite / Test Case and a
ListSimpleMatchlist selectAll / Low / Medium / Highfor Importance (legacyfilterOptions=[urgency_low, medium, high]; labels reusesearch.*Importance). -
Legacy default sort — suite ASC, importance DESC (High first) inside each group; test-case
DESC when priority management is off (
setSortByColumnName(...)+sortDirection='DESC'). -
MultiSort — drag a column header onto the MultiSort bar to add a DESC chip; click the chip to
toggle direction, X/shift+click to remove, drag chips to reorder,
Clear sortsrestores the default (legacyExt.ux.ToolbarDroppableworkflow).
No BFF change: GET /api/reports/index.php?action=free_testcases already returns suite_path,
importance and priority_enabled — grouping/sorting/filtering is entirely client-side.
i18n: 20 new ftc.* keys (toolbar, group header template ftc.groupHeader/groupItem(s),
MultiSort strings, filter strings, toasts) translated in ALL 10 locale bundles; importance filter
options reuse search.lowImportance/search.mediumImportance/search.highImportance.
Verification: 16/16 scripted browser checks (fixture FTC1262, 2 suites x 2 free cases, mixed
importance), Romanian locale pass with zero raw keys on screen, Event Viewer clean,
ai/verify_i18n_coverage.sh 9/9 bundles 0 missing.

Refs: #1262
The Importance badge now renders the localized label instead of the raw canonical value.
Discovered while verifying #1262 (the badge cells showed high/low/medium in every locale,
even though the column header Importanță and the footer filter Scăzută/Medie/Ridicată were
translated — a legacy-parity gap versus lib/results/freeTestCases.php:53-62, which rendered via
lang_get()).
Root cause: the BFF (api/reports/index.php) intentionally ships the canonical tokens
high|medium|low — the client ranks them for sorting and the footer LIST filter regex-matches
^high$ against the orthogonal filter datum — but priorityBadge() used the token as the visible
text too. The localized labels already existed (search.lowImportance|mediumImportance|highImportance,
same keys the footer filter uses) and were simply never wired into the badge.
Fix (client-side only, no BFF/i18n change): in gui/templates/results/freeTestCases.html
priorityBadge() the token now only selects the CSS class; the text maps through the existing keys:
if (level === 'high') { cls = 'priority-high'; label = t('search.highImportance', 'High'); }
else if (level === 'medium') { cls = 'priority-medium'; label = t('search.mediumImportance', 'Medium'); }
else if (level === 'low') { label = t('search.lowImportance', 'Low'); }Sorting (impRank rank branch) and the ^low|medium|high$ footer filter were deliberately left
reading the raw token.
Verification (fixture FTC1262): EN cells High/Low/High/Medium with unchanged badge
colors (red/green/red/amber); RO (&locale=ro) cells Ridicată/Scăzută/Ridicată/Medie;
LIST filter low still selects only the low row; Expand/Collapse + Refresh re-render localized;
default sort (suite ASC, importance DESC) unchanged; console clean; Event Viewer unchanged.
Out-of-scope sibling with the identical raw pattern: casesWithoutTester.html (filed separately).

Pre-fix raw state: issue-1874-freetestcases-importance-raw-en.png / -raw-ro.png.
Refs: #1874