Summary
Issue #1 originally bundled two phases of integration testing:
- Phase 1 —
MANUAL_SMOKE_TEST.md (done — landed in commit bbf7f9c)
- Phase 2 — self-hosted runner + OCR (still aspirational)
Splitting Phase 2 out into its own ticket so #1 can close on Phase 1
acceptance and Phase 2 can stay open as the long-tail "dreamy"
follow-on without blocking Phase 1's closure.
Why this matters
The byte-equality suite (tests/test_dry_run_bytes.py, 109 cases as
of v0.3.2) locks the wire protocol — what bytes the CLI emits
for given input. That's the highest-value regression guard we have.
What it doesn't cover:
- Does writing the bytes actually do what we documented? (
/dev/rongta-receipt
open + write path, plugdev perms, udev rule, firmware behavior on receipt.)
- Did firmware quietly change semantics? (Already happened once — the
2017 Linux SDK numbered WCP1252 as 12, the 2025 firmware as 16. Future
firmware revisions could move the goalposts again.)
- Does the cutter actually cut? "Cutter=Yes" in the self-test report
is necessary but not sufficient.
Phase 1's manual checklist makes "did the CLI work end-to-end on real
hardware" a documented, repeatable thing — but it relies on a human
running it pre-release. Phase 2 automates that.
Architecture sketch
┌──────────────┐
│ GitHub │
│ Actions │ ──── workflow_dispatch / release tag trigger
│ │
└──────┬───────┘
│
▼ (self-hosted runner registration)
┌──────────────────────────────────────────────────────────┐
│ tickerbox-ci (separate Pi from production tickerbox) │
│ │
│ ├── unspooled checkout (per-job clone) │
│ ├── Rongta RP332 over USB → /dev/rongta-receipt │
│ ├── Pi Camera v3 + ring light → /dev/video0 │
│ └── Tesseract / EasyOCR + Python harness │
└──────────────────────────────────────────────────────────┘
Per-test loop:
- CLI writes a known config (e.g.,
base --cutter on).
- CLI triggers a self-test print (
printf '\x12T' > /dev/rongta-receipt).
- Camera captures the receipt.
- OCR parses the relevant fields (
Cutter: Yes/No, Page: N, etc.).
- Assertion: parsed value matches expected.
- (Optional) Save raw image as a workflow artifact for human review.
What needs to be solved
Hardware
Software harness
Ops / cost
What's deliberately out of scope
- Color-fidelity testing (thermal printer is monochrome).
- Cutter-cuts-cleanly testing (binary: did paper separate, yes/no —
can be done via paper-end-sensor delta, but OCR can't see it).
- Multi-SKU testing on the same rig (would need a multi-printer carousel;
out of reasonable scope).
- Stress / endurance testing (this is a release-gate suite, not a
load test).
Done definition (for the issue, not the feature)
Related
Why this is "dreamy"
It needs hardware investment (~$80 Pi 4 + camera + mount + ring light)
and ongoing maintenance (paper, runner uptime, OCR drift). Not a
prerequisite for any release; would be nice for v1.0 confidence.
Open to deferring indefinitely unless someone (maintainer or
volunteer) volunteers to build it.
Summary
Issue #1 originally bundled two phases of integration testing:
MANUAL_SMOKE_TEST.md(done — landed in commitbbf7f9c)Splitting Phase 2 out into its own ticket so #1 can close on Phase 1
acceptance and Phase 2 can stay open as the long-tail "dreamy"
follow-on without blocking Phase 1's closure.
Why this matters
The byte-equality suite (
tests/test_dry_run_bytes.py, 109 cases asof v0.3.2) locks the wire protocol — what bytes the CLI emits
for given input. That's the highest-value regression guard we have.
What it doesn't cover:
/dev/rongta-receiptopen + write path,
plugdevperms, udev rule, firmware behavior on receipt.)2017 Linux SDK numbered WCP1252 as 12, the 2025 firmware as 16. Future
firmware revisions could move the goalposts again.)
is necessary but not sufficient.
Phase 1's manual checklist makes "did the CLI work end-to-end on real
hardware" a documented, repeatable thing — but it relies on a human
running it pre-release. Phase 2 automates that.
Architecture sketch
Per-test loop:
base --cutter on).printf '\x12T' > /dev/rongta-receipt).Cutter: Yes/No,Page: N, etc.).What needs to be solved
Hardware
tickerboxproduction —printing self-tests during a CI run would interrupt real prints).
Likely a Pi 4 (more USB bandwidth than the 3B+, camera headroom).
capture area. Distance, angle, and lighting need to be consistent
across runs or OCR accuracy will drift.
paper is high-contrast against thermal-black, but ambient light
drift (sun through a window) will wreck things.
on the wire. The printer's paper-out sensor IS readable over USB
(
DLE EOT 4) — wire it into the harness so the runner reports"halted: out of paper" instead of stalling.
Software harness
may struggle with the small font in the code-page table.
Alternatives to try in order: Tesseract → EasyOCR → a fine-tuned
Tesseract model trained on captures of THIS printer's output.
Document accuracy numbers per pipeline.
auto-crops to receipt bounds (template-matching against printer
housing edges or QR-code anchor), runs OCR, returns structured
fields.
Start with
base's self-test (cutter / beeper / drawer / density /code-page / chars-per-line), expand from there.
a pytest-style API. Probably a new
tests/hardware/subdir,pytest-marked with
@pytest.mark.hardwareand skipped by default.workflow_dispatchworkflow (manual trigger first; on everyrelease tag once stable).
Ops / cost
Standard GitHub Actions runner setup; well-trodden path.
≈ 16" of paper. At ~$30/roll for 80mm thermal × 200ft of paper,
that's ~$0.05 per CI run. Negligible.
docs/wine-cups-backend-recovers-nv-bytes.md;the harness should detect missing
/dev/rongta-receiptand trya
udevadm triggeronce before failing.concurrency: hardware-ciin the workflow.What's deliberately out of scope
can be done via paper-end-sensor delta, but OCR can't see it).
out of reasonable scope).
load test).
Done definition (for the issue, not the feature)
baseself-test to fail loud onregression (target: 100% on bold-text fields, ≥95% on code-page
table small-font fields).
diff against expected) attached to the workflow run for human triage.
docs/for someone else to replicate(camera position, lighting, OCR model choice, runner registration).
Related
the first place:
docs/wine-cups-backend-recovers-nv-bytes.md.MANUAL_SMOKE_TEST.md—the human-runnable version this would automate.
Why this is "dreamy"
It needs hardware investment (~$80 Pi 4 + camera + mount + ring light)
and ongoing maintenance (paper, runner uptime, OCR drift). Not a
prerequisite for any release; would be nice for v1.0 confidence.
Open to deferring indefinitely unless someone (maintainer or
volunteer) volunteers to build it.