What is not supported yet
We would rather tell you the edges up front than have you discover them in the middle of a proof of concept. This page lists the current, honest limitations of veriCue. If one of these blocks your use case, tell us at sales@vericue.dev - real-world demand drives the roadmap.
Recording
- The recorder does not generate assertions. It captures mouse, key and wheel events, resolves them to object paths, coalesces typed text, and emits a runnable Python script - but the script only replays what you did. You add the
assertstatements (property checks, screenshot comparisons) yourself. See Recording & replay. - Touch gestures are not recorded. Taps, swipes, pinches and other multi-touch input are fully supported for playback via
touch_tap,swipe,pinchandmulti_touch, but the recorder does not capture them. Write touch test steps by hand (Touch & gestures).
Drag and drop
drag is synthesized as a press-move-release sequence of mouse events inside your application. That covers in-app drags (sliders, reordering, item views). Native OS drag-and-drop between applications (dragging a file from a file manager into your app, or from your app to another program) is not supported.
Object identification
- Dynamically created objects and transient popups (context menus, completers, tooltips, dialogs created on the fly) need a stable
objectNameto be addressed reliably. Unnamed objects fall back toClassName#Nindex paths, which are order-dependent: creating or destroying a sibling changes the index. SetobjectNameon anything you want to automate. - Custom-rendered canvases are opaque. Shapes drawn inside an OpenGL viewport, a custom
paintEvent, or a charting canvas are not QObjects, so they are not individually addressable. Interaction with such content is coordinate-based: you click at offsets within the canvas widget and verify results via application-side properties or screenshots. See OpenGL viewports for the recommended patterns. - Bare
QWindow/QOpenGLWindowwithout a widget container is not resolvable by the object resolver. Wrap it withQWidget::createWindowContainer()(or use aQOpenGLWidget) so it appears in the widget tree.
Platform coverage
vericue run(running an unmodified Qt binary under veriCue with zero integration; from 0.5.0 - not in the released v0.4.0) is supported on Linux x64 and Windows x64, and only for applications that link Qt dynamically. A statically linked Qt cannot be injected into on any platform - there is no dynamic-load step to bring the Runtime in through. The mechanism differs by platform but the command and its flags do not:- Linux x64 preloads
libvericue-inject.sowithLD_PRELOAD. Set-user-ID and set-group-ID binaries are refused (the loader dropsLD_PRELOADfor them), and a wrapper script is refused because nothing about the binary it execs can be checked from it. - Windows x64 launches the target suspended and loads
vericue-inject.dllinto it withCreateRemoteThread+LoadLibraryW. This is an injection-shaped technique that endpoint security (Windows Defender ASR, EDR/AV) can block or quarantine; a hardened environment should embed the Runtime instead. Windows exposes TCP only. See Windows launch path. - macOS has no transparent launch path - the hardened runtime blocks loading a library into another process. Embed the Runtime; local IPC works.
All refusable configurations are refused before launch with the reason; embed the Runtime instead. The full Linux matrix is in Zero-source-change runs. Injection also does not make veriCue serverless: the same
VeriCueServercode runs inside the same process, it just got there without a source change.- Linux x64 preloads
macOS builds are Apple Silicon (arm64) with Qt 6 only. There is no macOS Intel (x64) build, and no Qt 5 build for macOS.
Linux and Windows are supported for both Qt 5.15 and Qt 6.
The local IPC transport (
startLocal(), see Transports) is supported on Linux and macOS, where it uses a UNIX-domain socket. It is not supported on Windows yet - it is neither built nor tested there, so use TCP on Windows.
Transport coverage in the tooling
The protocol is identical on both transports, but not every convenience layer exposes both:
MultiVeriCueClient(Python and C#) addresses each process by(host, port), so multi-process fleets run over TCP. Single-client code can still useconnect_local()/ConnectLocalAsync().- The GoogleTest fixture (
vericue/gtest_fixture.h) is configured withVERICUE_HOST/VERICUE_PORT/VERICUE_TOKENand connects over TCP. CallVeriCueClient::connectToLocalServer()directly for local IPC. - The bundled pytest fixtures spawn the app with
--port 0and connect over TCP on loopback.
The CLI (including vericue inspect) and all three clients' single-connection APIs support both transports.
Headless environments
QT_QPA_PLATFORM=offscreen is the usual headless answer for QWidget applications and is what the bundled pytest fixtures set. It is not a universal one: the offscreen plugin cannot obtain an OpenGL context on a machine without a display server, so Qt Quick / QML applications (and widgets that require a real GL context at startup) generally need a virtual X server - xvfb-run plus the xcb platform plugin, optionally with software rasterization. See the CI guide for the recipe.
Visual comparison
screenshot_compare is pixel-based with a configurable threshold, not perceptual or structural. Font rendering, GPU drivers and scale factors differ across machines, so baselines captured on one machine usually need a tolerance to pass on another - or per-environment baselines. See Visual regression for threshold and masking strategies.

