{% import "macros.html" as m %} {% if not data.catalog %} {{ m.empty('∅', 'No catalog', 'This project hasn’t generated a test catalog yet. Run `testctl catalog` in the project root to publish the gated, freshness-checked test tree.') }} {% elif not data.catalog.categories %} {{ m.empty('∅', 'No tests collected', 'The catalog is present but empty — `pytest --collect-only` found no tests. Add tests, then re-run `testctl catalog`.') }} {% else %}

The real test tree, generated from the project’s runners and freshness-gated — what you see is provably the actual suite. Configs are hidden by default; expand to view or edit (edits ride with this run only, never changing committed defaults).

{% if data.staleness and data.staleness.stale %}
This catalog was generated at {{ data.staleness.generated_commit }}, but the repo is now at {{ data.staleness.current_commit }} — the test list may be out of date. Run testctl catalog to refresh.
{% endif %} {% for cat in data.catalog.categories %}
{{ cat.label }} {% for group in cat.groups %}
{{ group.label }}
{% for test in group.tests %} {% set running = test.id in data.running_ids %}
{{ test.id }} {{ m.status_chip(test.last_status, running=running) }} {{ test.label }} {{ test.runner }} {% if test.independent %}independent{% endif %} {% for tag in test.tags %}{{ tag }}{% endfor %}
{% if test.config_schema %}
config · {{ test.config_schema|length }} field(s)
⚙ config · {{ test.id }} · per-run overlay
{% for field in test.config_schema %} {% set val = test.config.get(field.name, field.default) %}
{% if field.type == 'bool' %} {% elif field.type == 'enum' %} {% else %} {% endif %}
{% endfor %}
overlay rides with this run only · committed defaults stay read-only
{% endif %}
{% endfor %} {% endfor %}
{% endfor %} {% endif %}