"""Launches the real MainWindow, loads the out-of-sync fixture, drives the actual marker -> offset -> export flow through the same code the UI buttons call (not a copy of the logic), and grabs screenshots so it can be visually checked instead of just trusting the app "should" work. """ import sys import time from pathlib import Path from PyQt6.QtWidgets import QApplication sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) import main as app_main ROOT = Path(__file__).resolve().parent.parent CLIP = str(ROOT / "test_media" / "sync_test_OUTOFSYNC_audio+350ms.mp4") OUT_DIR = ROOT / "test_media" / "seek_validation" EXPORT_OUT = str(OUT_DIR / "_ui_smoke_export.mp4") def main(): OUT_DIR.mkdir(exist_ok=True) qapp = QApplication(sys.argv) win = app_main.MainWindow() win.show() qapp.processEvents() win._load(CLIP) qapp.processEvents() time.sleep(0.3) qapp.processEvents() print(f"loaded: duration slider range = {win.seek_slider.maximum()}ms") win.player.seek(5.000) qapp.processEvents() win._mark_video() print(f"video mark: {win.video_mark:.3f}s -> label: {win.video_mark_label.text()}") win.player.seek(5.350) qapp.processEvents() win._mark_audio() print(f"audio mark: {win.audio_mark:.3f}s -> label: {win.audio_mark_label.text()}") print(f"offset label: {win.offset_label.text()}") print(f"export button enabled: {win.export_button.isEnabled()}") assert win.export_button.isEnabled() # hr-seek lands on the nearest frame boundary (33.3ms steps @ 30fps), so # marks won't hit 5.350 exactly -- check within one frame, not bit-exact. assert abs(win.offset.delay_ms - (-350.0)) < 34 assert win.offset.target == "video" win.grab().save(str(OUT_DIR / "ui_smoke_after_marking.png")) # Drive export directly through the worker (skip the file-save dialog, # which needs a real user) but through the same ExportWorker class the # button uses. done = {"ok": False, "err": None} def on_ok(result): done["ok"] = True print("export finished OK, ffmpeg log:", result.stderr[:200]) def on_err(msg, stderr): done["err"] = (msg, stderr) worker = app_main.ExportWorker(win.input_path, win.offset.delay_ms, EXPORT_OUT) worker.finished_ok.connect(on_ok) worker.finished_err.connect(on_err) worker.start() deadline = time.time() + 15 while not done["ok"] and done["err"] is None and time.time() < deadline: qapp.processEvents() time.sleep(0.05) if done["err"]: raise RuntimeError(f"export failed: {done['err']}") assert done["ok"], "export did not finish within timeout" assert Path(EXPORT_OUT).exists() print(f"exported file exists: {EXPORT_OUT}, size={Path(EXPORT_OUT).stat().st_size} bytes") win.player.shutdown() print("\nUI SMOKE TEST PASSED") if __name__ == "__main__": main()