217 Commits

Author SHA1 Message Date
9171abc3ba docs: note Flatpak host-open of log paths and F1 location under 0.3.2
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
v0.3.2
2026-06-17 15:14:49 +02:00
4a72fe019e feat(gui): open log line via configurable editor command (template {file}/{line})
refactor(settings): defaults carried by SettingsItem, getters/setters via _pref
refactor(pref-win): declarative Field table + _FIELD bridge + merged file pickers

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 14:44:23 +02:00
b5b8198c29 fix(gui): host-open clicked log paths in Flatpak (text_log)
fix(gui): host-open the sequence file location in Flatpak; drop double-open

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 12:15:19 +02:00
c313e1431b fix(gui): Flatpak Show Results opens the log via host xdg-open
fix(gui): keep Show Results enabled during a run

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:54:11 +02:00
7edfc25a1f docs: note F1 variable filter under 0.3.2
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 23:38:45 +02:00
7a732c0d04 feat(gui): filter variables in the F1 window (name, optional value)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 23:36:57 +02:00
f62ea10d24 test(validation): make immediate read_until deterministic (drop prompt race)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 23:17:14 +02:00
51068c881f chore(release): 0.3.2
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:53:30 +02:00
83475dd215 docs: run item capture + batch param
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:53:30 +02:00
4fe23518a0 test(validation): run capture via store_result
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:53:30 +02:00
87e62a7f2e feat(run): capture sub-instance output, add batch param
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:53:30 +02:00
5b5792a296 Merge branch 'main' of ssh://cahute.beafrancois.fr:8327/v-and-v/testium v0.3.1 2026-06-15 14:40:50 +02:00
087aa93a16 chore(release): 0.3.1
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 14:40:36 +02:00
7abd8c07a6 test(validation): negative load-error checks; keep run logs out of the repo
load_errors_check.py loads deliberately broken .tum fixtures in batch on the
build under test (like lsp_check.py) and asserts each fails with its specific
located message and without a raw traceback. Wired into run.sh just before the
main suite, so it runs for every channel.

The run validation items now point their sub-instance log at the gitignored
report dir, so a GUI run no longer litters the tree with sub_*.log files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 14:40:24 +02:00
1ea360e5a5 fix(load): report every test-load error with file, item path and cause
A structural mistake in a .tum (unknown item or action, a step holding two
items, a missing 'steps:' list, a scalar where a mapping is expected, ...)
used to surface as a bare Python traceback. At worst the unknown-action
formatter itself crashed with "'dict_keys' object is not subscriptable"
(action.keys()[0]), masking the real cause and leaving only the generic
"test process crashed for any reason".

The load path now validates each step and funnels every failure through a
located TUM file syntax error: the file, a breadcrumb to the item, the
offending value and the list of valid names. A problem inside an !include-d
file points to that file. A last-resort net in __loadTestTree turns any
unforeseen exception into a located error too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 14:40:15 +02:00
d5154348f6 Midified the package for windows (not a monolitic bin). And added the option to remove older versions in the setup. 2026-06-15 09:08:28 +02:00
6dc473de41 test(validation): --gui option to run the suite in the GUI
Adds `--gui` to test/validation/run.sh: drops `-b` so testium opens the GUI
with the validation suite loaded instead of running headless. The run is
started manually and the window stays open — handy to inspect the test
tree, try the Ctrl+F search, etc. Works with any --mode.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 00:25:53 +02:00
cf5db9e112 docs: release note for the GUI test-tree search
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
v0.3
2026-06-15 00:18:38 +02:00
f56125ced3 docs: test-tree search (GUI)
Document the Ctrl+F find bar: field checkboxes, the blockSignals pass that
avoids the on_testChecked controller storm, and the flag-driven
_refresh_highlight (run > search > default) that keeps the run and search
highlight layers from clobbering each other.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 00:15:11 +02:00
a4377d691f feat(gui): search the test tree (Ctrl+F)
Find bar over the test tree: highlight matches and navigate them
(Enter / ◂ ▸), with Name/Type/Doc checkboxes to choose the searched
fields. Ctrl+F toggles the bar (clearing the highlight); Esc / ✕ close.

- QTestTreeItem: matches_search(needle, fields) + a search highlight that
  shares one _refresh_highlight() with the green run highlight, recomputed
  from state flags (run > search > default) so the two layers never leave a
  stale/permanent colour. Amber bg + forced black text → readable in any
  theme.
- QTestTree.search()/clear_search(): single signal-blocked pass (setBackground
  fires itemChanged → on_testChecked, a controller storm otherwise); expands
  ancestors of matches; returns matches in visual order.
- MainWindow: the find bar widget + Ctrl+F shortcut + navigation; search is
  reset when a new test file is loaded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 23:57:02 +02:00
72b207aab6 feat(gui): pytest sub-items use the pytest icon
"pytest step" children now show the pytest logo (pytest.png), matching the
parent "pytest" item, instead of the generic document icon. Icon already
embedded in the compiled resources — no rcc regen needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 23:24:15 +02:00
f579599f1d release 0.3 preparation
- version 0.3 (the pytest item release)
- release note: 0.3 entry (user-facing)
- regenerated user manual (0.3 stamp + pytest item section)
- DESIGN: "Graceful item load" section

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 23:21:34 +02:00
1c598a1eae fix(pytest): robust plugin injection via pytest.main(plugins=[...])
The plugin was delivered by writing it to a temp dir, putting that dir on
PYTHONPATH and loading it with `python -m pytest -p _testium_pytest_plugin`.
That import-by-name failed in the AppImage runtime (ModuleNotFoundError:
_testium_pytest_plugin) so collection returned nothing and the item FAILed
— while wheel/pyinstaller/flatpak worked. Local sims forcing the AppImage
env path (apply_host_libs) passed, ruling out the env scrubbing.

Ship the plugin as a self-contained launcher run directly
(`python launcher.py ...`) that registers it as a plugin object via
pytest.main(plugins=[sys.modules[__name__]]): no PYTHONPATH, no `-p`, no
import-by-name. apply_host_libs is untouched. Verified on source, wheel,
pyinstaller, flatpak and AppImage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 23:19:30 +02:00
e167da97d0 feat(pytest): clear "pytest not installed" message
When collection finds nothing because pytest is missing on the host
interpreter, load() raises a dedicated message ("pytest is not installed
... pip install pytest") instead of the raw pytest output. The graceful
load mechanism surfaces it as a WARN at load + a clean FAIL at run, the
rest of the campaign keeps running.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 20:24:27 +02:00
b4bfe72239 Merge branch 'feat/graceful-item-load' into feat/pytest-item
# Conflicts:
#	DESIGN.md
2026-06-14 20:23:08 +02:00
5cc795ebb3 feat: graceful load failure for module-loading items
A self-loading item that can't load its module/file (unittest test file
with a missing import, pytest not installed on the host, ...) no longer
aborts the whole test load. TestSet._load_item() wraps load(), warns at
load time and records item._load_error; @test_run turns it into a clean
run-time FAILURE. The rest of the campaign loads and runs.

Scoped to module-loading items (unittest; pytest once merged). Structural
action loading stays fail-fast.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 20:19:43 +02:00
ea481b5889 feat(gui): dedicated pytest item icon
Use the official pytest logo (devicon) for the pytest item instead of
reusing python.png — visually distinct from the py_func (Python logo)
item. Three 64x64 theme variants (color RGBA, black RGBA silhouette,
white LA), declared in the QRC and compiled into testium_core_win_rc.py;
_ITEM_CONFIG "pytest" now points to pytest.png.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 19:57:42 +02:00
c9daaffea8 docs(pytest): add pytest test item manual section
New test_items/pytest_test_item.rst (params, host-subprocess execution,
pytest-must-be-installed note), wired into the toctree. Regenerated PDF.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 19:44:47 +02:00
06ae210e02 Merge branch 'main' into feat/pytest-item
# Conflicts:
#	DESIGN.md
2026-06-14 19:42:02 +02:00
a875828de0 chore: bump version back to 0.2.4
0.3 is reserved for the upcoming pytest item release. Regenerated the
manual PDF so its version stamp matches.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 17:33:33 +02:00
8a498dd6ac fix: expand parameters at run time, not at load
Variable substitution ($(...)) must use the runtime global dict, so it
must happen at run time (execute), never at load (__init__).

- console telnet_port: was never expanded — `telnet_port: $(port)` stayed
  literal. Now expanded at run (processed=True in execute, like the other
  host/port params).
- test_item base: stop_on_failure / execute_on_stop are now stored raw and
  resolved at run time via properties (so a $(...) flag reflects the
  runtime value, not the load-time one).
- cycle iterator and git repo: drop the redundant load-time expansion
  (execute() already re-expands them).
- tested_references: fetch 'reference' raw, expand each value in execute().

Justified load-time exceptions kept: name, doc, skipped (static/GUI at
load) and unittest test_method (drives child loading at load).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 17:19:07 +02:00
3661a71145 docs(console): read_until list match + regex
Document that read_until's 'expected' accepts a list (match any) and the
new 'regex' flag, with examples and the bounded-window limitation note.
Regenerated manual PDF.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 17:00:46 +02:00
e4300ecf7b feat(console): list/regex read_until, serial error clarity; v0.3
read_until:
- 'expected' now accepts a list of values (succeeds on any match).
- new 'regex: true' flag: each pattern is a Python regex (re.search over a
  bounded tail, Console.REGEX_WINDOW). Reports which pattern matched.

Serial console robustness & clarity:
- failed open() raises a clear ETUMRuntimeError ("Serial device '…' does not
  exist." / permission hint) instead of a raw pyserial traceback.
- a console whose open failed is safely "not open" (init _thd=None +
  isOpened guards in readchar/read_nowait/close) — no more cascading
  AttributeError: '_thd' on subsequent read steps.
- action handlers: one-liner for expected (ETUMRuntimeError) errors, full
  traceback kept for unexpected ones. All console errors use testium
  exceptions (ETUMRuntimeError).

Flatpak: grant --device=all so serial adapters (/dev/ttyUSB*, /dev/ttyACM*)
are visible in the sandbox.

Validation: new read_until list/regex (match + no-match) cases in
items/console/test.tum.

Version: 0.3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 16:54:00 +02:00
c77f56f2fb feat(items): add pytest test item
Run a user pytest file as a testium item, surfacing each collected test
as a child with its own PASS/FAIL/SKIP, duration and failure message.

Mirrors the unittest item but runs pytest in a subprocess on the host
interpreter (bins.python_bin(), like py_func/lua_func) so it works across
every packaging channel. A stdlib-only pytest plugin streams collected
node-ids and per-test results over stdout via sentinels; the parent parses
them live. Params: test_file, test_method. stop_on_failure maps to -x;
disabled children are reported NORUN without running.

Wiring: TYPE_PYTEST / TYPE_PYTEST_STEP constants, test_init registration,
self-loading branch in test_set, GUI tree icon. Schema/LSP pick it up
automatically from the declarative PARAMS.

Validation: test/validation/items/pytest/ (validation venv now installs
pytest).

WIP: paused mid-feature (DESIGN.md documented; manual section pending).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 16:09:09 +02:00
8c4e1b56b5 feat(windows): icon, windowed exe, no-admin installer
- PyInstaller exe built windowed (console=False) with package/testium.ico
  as the embedded icon (BMP entries for shell compatibility).
- Suppress stray subprocess console windows in the frozen Windows build via
  paths.no_window_kwargs() (CREATE_NO_WINDOW); wheel/source unchanged.
  Applied to py_process, lua_process, bins probes, sys_app_path_win.
- New per-user Inno Setup installer (package/innosetup/): no admin,
  version-scoped AppId/dir so versions install side-by-side, one Start
  Menu entry per version, .ico shipped for shortcut/uninstall icons.
- DESIGN.md + release_note.txt updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v0.2.3
2026-06-12 13:57:48 +02:00
e0802a9a72 release 0.2.3 preparation 2026-06-10 12:30:18 +02:00
fe1766c1fc cosmetics 2026-06-10 12:26:54 +02:00
3c1a736294 release note updated with new rev. 2026-06-07 19:52:57 +02:00
c3346c6bb7 chore: bump version to 0.2.3 2026-06-07 19:48:40 +02:00
b2f85591ce style: shorten code comments to one line 2026-06-07 18:47:44 +02:00
3d96e5060f fix: publish resolved python_bin/lua_bin into the global dict
bins.ensure() now stores the resolved interpreter path under
python_bin / lua_bin when the key is unset, so test scripts can use
$(python_bin) / $(lua_bin) in GUI mode (no -d override). Restores the
behaviour lost when bins.py centralised resolution. A user-provided
value is left untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 18:42:43 +02:00
2241dfb8c7 fix(windows): RPC port handshake for py/lua subprocesses
The subprocess now binds port 0, prints the bound port on stdout after
listen(), and the parent connects only once it reads that port. Removes
the reserve/close/rebind race and SO_REUSEADDR, and the connect-before-
ready timing guess that failed intermittently on Windows. wait_ready()
no longer hangs when a connection attempt fails.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 18:29:04 +02:00
9dae210f7f fix(windows): UTF-8 console + self-sufficient validation wrapper
Make the suite run cleanly on Windows.

Product code:
- __init__.py: force UTF-8 on stdout/stderr. The Windows console code
  page (cp1252) cannot encode the box-drawing/accented characters the
  runner prints, which crashed the parent capture_stdout thread. Only
  the stream encoders are reconfigured; the locale default used to read
  cp1252 config files is left untouched.
- report_export_junit/html: open the report file with encoding="utf-8"
  (XML/HTML are UTF-8) instead of the platform default, matching the
  txt/json exporters.

Validation:
- run.bat: source mode now sets up its own venv and runs testium from
  src\ directly instead of delegating to the project run.bat (which
  launches the GUI and drops its arguments). Installs the fake_exporter
  entry-point plugin (report_plugin) and the [lsp] extra, and runs the
  same lsp_check.py pre-flight as run.sh.
- jsonrpc/test.tum: launch the echo server via "$(python_bin)" instead
  of "python3" (the Microsoft Store stub on Windows).
- post_execution.py: write the JUnit XML with encoding="utf-8".
- restore items/run/sub_pass.tum and sub_fail.tum, deleted by mistake in
  d97d00c "removed test logs".
2026-06-06 21:39:36 +02:00
d97d00c593 removed test logs 2026-06-02 00:00:40 +02:00
2b0c4b5ee0 release v0.2.2 2026-06-01 23:48:56 +02:00
59e63e1338 fix(flatpak): console on host + dialog persistence
- term console via flatpak-spawn --host so host venvs resolve (bins.host_console_command)
- QSettings sync() before subprocess kill in choices/tested-refs dialogs
- console regression test: fails on the in-sandbox 0.2.1 console

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 23:42:48 +02:00
de32a524da docs: testium_assist install instructions (Open VSX / VSCode)
Manual (modes.rst) and README: install the extension from Open VSX in
VSCodium/Cursor/etc., and as a .vsix by hand in Microsoft VSCode; note
that testium must be on PATH or set via testium.serverPath.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 23:56:34 +02:00
2515213b14 release preparation v0.2.1 2026-05-31 16:15:52 +02:00
0376b77494 fix(gui): show the testium icon in the GNOME task bar (Wayland)
Set the app id via setDesktopFileName so the window stops inheriting the
launcher's class ("python3" under the AppImage), which is what GNOME was
keying the wrong icon off. On native Wayland the task-bar icon comes from
an installed desktop file matched to the app id (setWindowIcon is
ignored there), so on Linux drop an idempotent desktop entry + 256px icon
under ~/.local/share. Flatpak keeps its own id/desktop; Windows / macOS
use the window icon. No-op off Linux.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 16:14:04 +02:00
f2eedb5606 docs: add 0.2.1 release note (load-time optimisations + fix)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 15:33:13 +02:00