--- phase: 15-ux-driver-upload-feedback-fix plan: 01 type: execute wave: 1 depends_on: [] files_modified: - imptune/templates/printers_new.html - tests/test_printer_form.py autonomous: true requirements: - UX-01 must_haves: truths: - "GET /printers/new renders a #driver-list div with no style=\"display:none\" attribute" - "After uploading a driver on /printers/new, the OOB response fragment contains the driver name (upload confirmation visible)" - "The driver dropdown (OOB select) still refreshes after upload (no regression)" artifacts: - path: "imptune/templates/printers_new.html" provides: "Printer new page template with visible #driver-list anchor" contains: "id=\"driver-list\"" - path: "tests/test_printer_form.py" provides: "Smoke tests for driver-list visibility and upload feedback" exports: - "test_printers_new_driver_list_visible" - "test_upload_feedback_visible_on_printers_new" key_links: - from: "imptune/templates/printers_new.html" to: "partials/driver_upload_with_oob.html" via: "HTMX hx-target=\"#driver-list\" outerHTML swap" pattern: "id=\"driver-list\"" - from: "POST /drivers/upload?caller=printer_form" to: "driver_upload_with_oob.html primary fragment" via: "caller sentinel in upload handler" pattern: "caller == \"printer_form\"" --- Close the integration gap: the `#driver-list` div on `/printers/new` is hidden (`style="display:none"`), so the HTMX outerHTML swap from the driver upload succeeds but the confirmation content (driver name, driver table) is invisible to the technician. Purpose: A technician uploading a driver on `/printers/new` must see the upload confirmation — driver name + driver list table — immediately after uploading, without reloading the page. The OOB select refresh (dropdown update) must continue to work. Output: One-line template change to `printers_new.html` (remove `style="display:none"`), two new integration assertions in `tests/test_printer_form.py`. @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/15-ux-driver-upload-feedback-fix/15-RESEARCH.md @.planning/phases/15-ux-driver-upload-feedback-fix/15-VALIDATION.md From imptune/templates/printers_new.html (line 87-99, current state): ```html
``` From tests/conftest.py — `client` fixture: ```python @pytest.fixture def client(tmp_data_dir): from imptune.main import app with TestClient(app) as c: yield c ``` From tests/test_driver_upload.py — helper `_make_driver_zip`: ```python SAMPLE_INF = """\ [Version] Signature="$Windows NT$" ... [Strings] MFG="Test Manufacturer" DRIVER_NAME="Test LaserJet Pro" """ def _make_driver_zip( inf_content: str = SAMPLE_INF, inf_name: str = "sample.inf", extra_files: dict[str, bytes] | None = None, ) -> bytes: ... ``` Note: `_make_driver_zip` is defined in `test_driver_upload.py` — do NOT import it. Replicate a minimal equivalent helper locally in `test_printer_form.py` (or inline the zip creation).
Task 1: Add Wave 0 smoke tests for driver-list visibility and upload feedback tests/test_printer_form.py - test_printers_new_driver_list_visible: GET /printers/new returns 200 and the response HTML contains `id="driver-list"` but does NOT contain `id="driver-list" style="display:none"` — i.e., the anchor exists and is not hidden. - test_upload_feedback_visible_on_printers_new: POST /drivers/upload with a valid driver ZIP and `data={"caller": "printer_form"}` returns 200 and the response body contains the driver name from the INF ("Test LaserJet Pro") AND contains `hx-swap-oob="true"` (OOB select still present). Append two new test functions to the bottom of `tests/test_printer_form.py`. **test_printers_new_driver_list_visible:** - GET /printers/new, assert 200 - Assert `'id="driver-list"' in resp.text` (anchor exists) - Assert `'id="driver-list" style="display:none"' not in resp.text` (not hidden) **test_upload_feedback_visible_on_printers_new:** - Build a minimal driver ZIP in-memory: create a `BytesIO` + `zipfile.ZipFile`, write one .inf file containing `DRIVER_NAME="Test LaserJet Pro"` using the same SAMPLE_INF-style content as in `test_driver_upload.py`. Do NOT import from `test_driver_upload.py` — replicate the ~10-line helper inline or as a local `_make_driver_zip_for_form_test` function at the top of the new block. - POST to `/drivers/upload` with `files={"file": ("driver.zip", zip_bytes, "application/zip")}` and `data={"caller": "printer_form"}` - Assert `resp.status_code == 200` - Assert `"Test LaserJet Pro" in resp.text` (upload confirmation contains driver name) - Assert `'hx-swap-oob="true"' in resp.text` (OOB select still present — regression guard) Add required imports at top of file if not already present: `import io`, `import zipfile`. **Run tests after writing — they MUST fail (RED) before the template fix.** Run: `pytest tests/test_printer_form.py::test_printers_new_driver_list_visible tests/test_printer_form.py::test_upload_feedback_visible_on_printers_new -x -q` Expected: `test_printers_new_driver_list_visible` FAILS (div is currently hidden). Expected: `test_upload_feedback_visible_on_printers_new` may PASS already (server response is correct; visibility is DOM-side). If it passes, that is expected and acceptable — the server already returns the driver name in the fragment; the bug is only that the DOM target is hidden. Document this in a comment. pytest tests/test_printer_form.py::test_printers_new_driver_list_visible tests/test_printer_form.py::test_upload_feedback_visible_on_printers_new -x -q Both test functions exist in tests/test_printer_form.py. `test_printers_new_driver_list_visible` FAILS (RED — confirming the bug). `test_upload_feedback_visible_on_printers_new` PASSES (server fragment is correct). Test file has no import errors. Task 2: Remove display:none from #driver-list in printers_new.html and verify GREEN imptune/templates/printers_new.html Edit `imptune/templates/printers_new.html` line 98. **Change:** ```html ``` **To:** ```html
``` That is the complete change. Do NOT modify any other line. Do NOT touch `printer_form.html`. Do NOT touch `driver_upload_with_oob.html`. Do NOT touch `driver_list.html`. After saving, run the full targeted test suite to confirm GREEN: `pytest tests/test_printer_form.py tests/test_driver_upload.py -x -q` Then run the full suite (excluding e2e) to confirm no regression: `pytest tests/ -x -q --ignore=tests/e2e`
pytest tests/test_printer_form.py tests/test_driver_upload.py -x -q - `tests/test_printer_form.py::test_printers_new_driver_list_visible` PASSES (GREEN — div no longer hidden) - `tests/test_printer_form.py::test_upload_feedback_visible_on_printers_new` PASSES - `tests/test_driver_upload.py::test_upload_returns_oob_when_called_from_form` PASSES (no regression) - Full suite `pytest tests/ -x -q --ignore=tests/e2e` is green - `printers_new.html` line 98 reads `
` with no style attribute
1. `pytest tests/test_printer_form.py -x -q` — all tests pass including the two new ones 2. `pytest tests/test_driver_upload.py -x -q` — OOB regression test passes 3. `pytest tests/ -x -q --ignore=tests/e2e` — full suite green 4. `grep 'display:none' imptune/templates/printers_new.html` — returns no matches (the hidden style is gone) 5. Manual smoke (optional): Open /printers/new in browser, upload a driver ZIP, confirm driver name + table appears without page reload - GET /printers/new: `#driver-list` div exists with no `style="display:none"` attribute - POST /drivers/upload with caller=printer_form: response fragment contains driver name (upload confirmation) - OOB select (`hx-swap-oob="true"`) still present in upload response (no regression) - All tests pass: `pytest tests/ -x -q --ignore=tests/e2e` - Single-line change in `printers_new.html` — no other files modified except test additions After completion, create `.planning/phases/15-ux-driver-upload-feedback-fix/15-01-SUMMARY.md` with: - What was changed (printers_new.html line 98, two new test functions) - Why (hidden div made upload confirmation invisible despite correct server response) - Tests added and their status - Regression: OOB select refresh unaffected - Full suite result