From 61b4131aee4ab57333f487ba818de1435760d8b0 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 3 Jun 2026 04:14:24 +0800 Subject: [PATCH] feat(automation): runnable e2e slice example / smoke test --- tools/automation/example_slice.py | 74 +++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tools/automation/example_slice.py diff --git a/tools/automation/example_slice.py b/tools/automation/example_slice.py new file mode 100644 index 0000000000..984b84e1dc --- /dev/null +++ b/tools/automation/example_slice.py @@ -0,0 +1,74 @@ +"""End-to-end smoke test: launch OrcaSlicer with the automation server, load a +model, slice it, wait for completion, and save both a window PNG and a 3D PNG. + +Run: + python example_slice.py --orca /path/to/OrcaSlicer --model /path/to/cube.stl + +On Linux CI, wrap with a virtual display, e.g.: + xvfb-run -a python example_slice.py --orca ./OrcaSlicer --model cube.stl +""" +from __future__ import annotations +import argparse +import subprocess +import sys +import time + +from orca_automation import OrcaClient, OrcaError + + +def main() -> int: + ap = argparse.ArgumentParser() + ap.add_argument("--orca", required=True, help="path to the OrcaSlicer executable") + ap.add_argument("--model", required=True, help="path to an STL/3MF to load") + ap.add_argument("--port", type=int, default=13619) + args = ap.parse_args() + + proc = subprocess.Popen([ + args.orca, + "--automation-server", + f"--automation-server-port={args.port}", + args.model, + ]) + try: + orca = OrcaClient(port=args.port) + + # Wait for the server to come up. + for _ in range(60): + try: + print("connected:", orca.version()) + break + except OSError: + time.sleep(0.5) + else: + print("ERROR: automation server did not start", file=sys.stderr) + return 1 + + # Wait until the project (model) is loaded. + deadline = time.time() + 30 + while time.time() < deadline: + if orca.app_state().get("project_loaded"): + break + time.sleep(0.5) + + # Click Slice and wait for the Export button to become enabled + # (slicing complete) — wait_for replaces fragile fixed sleeps. + orca.click({"id": "btn_slice"}) + orca.wait_for({"id": "btn_export"}, state="enabled", timeout_ms=180000, + poll_ms=500) + + with open("window.png", "wb") as f: + f.write(orca.screenshot()) + with open("preview_3d.png", "wb") as f: + f.write(orca.screenshot_3d(width=1024, height=768)) + print("wrote window.png and preview_3d.png") + return 0 + finally: + proc.terminate() + try: + proc.wait(timeout=10) + except subprocess.TimeoutExpired: + proc.kill() + + +if __name__ == "__main__": + raise SystemExit(main())