---
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