#925 Spix: Integrate Spix for GUI testing via XML-RPC#929
Conversation
Wires find_package(Spix CONFIG REQUIRED) and appends Spix::QtWidgets to THIRD_PARTY_LIBRARIES so both ApplicationLibCode (where the server is constructed) and ApplicationExeCode pick it up via the existing variable propagation. Defines ENABLE_SPIX so source files can guard the integration.
Forward-declares spix::AnyRpcServer / spix::QtWidgetsBot, holds them as unique_ptr members behind ENABLE_SPIX, and constructs them in handleArguments when --spix-port <n> is supplied. The server is reset before window teardown so its worker thread joins before the bot is destroyed.
Skips when RESINSIGHT_SPIX_PORT is unset so it stays out of the default CI
suite. Spix exposes an XML-RPC server (anyrpc::XmlHttpServer) rather than
JSON-RPC, so the test calls existsAndVisible("mainWindow") via the stdlib
xmlrpc.client.ServerProxy.
The project's default vcpkg baseline (84bab45d4 from 2025-12-13) predates the addition of the spix port (5d70180b0, 2026-01-25). Add a per-package registry override so only spix uses the newer baseline; all other ports still resolve from the default registry.
The vcpkg spix port pulls in qtbase and qtdeclarative as transitive deps, which would force vcpkg to build a duplicate Qt6 stack alongside the system Qt6 the project already uses. Switch to FetchContent at Spix v0.14 and add_subdirectory it inline so Spix builds against the project's existing Qt6. Only anyrpc remains a vcpkg dependency (Spix's CMake calls find_package(AnyRPC REQUIRED)). SPIX_BUILD_QTQUICK and SPIX_BUILD_EXAMPLES are forced off; only the QtWidgets scene library is built.
Spix::QtWidgets is an ALIAS target, which is incompatible with the set_property(TARGET FOLDER ...) walk over THIRD_PARTY_LIBRARIES at the end of the top-level CMakeLists.txt. Wire the link locally in ApplicationLibCode (which is where RiaGuiApplication.cpp consumes the headers); ResInsight.exe picks Spix up transitively through its existing dependency on ApplicationLibCode. Also drops the now-unused find_package(AnyRPC CONFIG REQUIRED) at the top level: the vcpkg anyrpc port ships no CMake config file, so Spix's own FindAnyRPC.cmake (module mode) handles discovery once add_subdirectory runs.
existsAndVisible(<path>) requires the target widget to have a Qt objectName. RiuMainWindow does not currently call setObjectName, so the previous assertion failed even with the RPC server fully wired. getErrors() takes no widget path, so it verifies the AnyRPC server is alive and the bot is responsive without coupling the smoke test to widget naming. Naming top-level widgets for path-based UI tests can be added separately when functional UI tests land.
Review Summary by QodoIntegrate Spix for automated GUI testing via XML-RPC
WalkthroughsDescription• Integrates Spix library for remote GUI testing via XML-RPC • Adds --spix-port command-line option to start RPC server • Implements AnyRpcServer and QtWidgetsBot in RiaGuiApplication • Adds Python smoke test using xmlrpc.client for validation • Gated behind RESINSIGHT_ENABLE_SPIX CMake option (disabled by default) Diagramflowchart LR
CLI["--spix-port argument"]
Parser["RiaArgumentParser registers option"]
Handler["RiaGuiApplication.handleArguments"]
Server["AnyRpcServer + QtWidgetsBot"]
Test["test_spix_smoke.py validates RPC"]
CLI --> Parser
Parser --> Handler
Handler --> Server
Server --> Test
File Changes1. CMakeLists.txt
|
Code Review by Qodo
1. Spix port unvalidated
|
| #ifdef ENABLE_SPIX | ||
| if ( cvf::Option o = progOpt->option( "spix-port" ) ) | ||
| { | ||
| if ( o.valueCount() == 1 ) | ||
| { | ||
| int port = o.value( 0 ).toInt(); | ||
| if ( port > 0 ) startSpixServer( port ); | ||
| } |
There was a problem hiding this comment.
1. Spix port unvalidated 🐞 Bug ≡ Correctness
RiaGuiApplication::handleArguments parses --spix-port with toInt() and only checks >0, so non-numeric input becomes 0 (silently ignored) and out-of-range ports can attempt startup without a clear error/exit status when startup fails.
Agent Prompt
### Issue description
`--spix-port` is parsed via `toInt()` and only checked for `> 0`, which means invalid strings silently become `0` (server not started, no message), and invalid ranges can proceed to `startSpixServer()`.
### Issue Context
There is already precedent for strict CLI validation (`--threadcount`) returning `EXIT_WITH_ERROR` and logging a clear message. Spix startup failures are currently swallowed (log-only) and the application keeps running.
### Fix Focus Areas
- ApplicationLibCode/Application/RiaGuiApplication.cpp[568-594]
- ApplicationLibCode/Application/RiaGuiApplication.cpp[1867-1886]
### Suggested fix
- Validate that the value is a valid integer and within `[1, 65535]`.
- If invalid, log an error and return `EXIT_WITH_ERROR` (consistent with `--threadcount`).
- Consider changing `startSpixServer` to return `bool` (or throw) so `handleArguments()` can fail fast when startup fails, instead of continuing silently.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Summary
--spix-port <port>command-line option that starts an AnyRPC server insideRiaGuiApplicationwhen providedRESINSIGHT_ENABLE_SPIX(off by default); Spix is fetched viaFetchContentand linked directly intoApplicationLibCodetest_spix_smoke.py) that exercises the bridge using the standard libraryxmlrpc.clientTest plan
-DRESINSIGHT_ENABLE_SPIX=ONand verify the build succeeds--spix-port 9000and confirm the RPC server startsGrpcInterface/Python/rips/tests/test_spix_smoke.pyagainst the running instanceRESINSIGHT_ENABLE_SPIX) is unchanged