From 205938088ca437c7c4abc802809ac7ee214a8b90 Mon Sep 17 00:00:00 2001 From: erhant Date: Thu, 18 Jun 2026 18:06:44 +0300 Subject: [PATCH] chore: add integration test --- README.md | 31 +++++++++++++++++++------------ tests/ui-tests.mjs | 28 ++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 tests/ui-tests.mjs diff --git a/README.md b/README.md index 66e7612..21626a0 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,6 @@ # LEZ Explorer UI -A QML block explorer for the **Logos Execution Zone** (LEZ), packaged as a -`logos-module-builder` **`ui_qml`** module (universal authoring model). The QML -view runs process-isolated in a `ui-host`, backed by a small C++ backend that -reads from the [`lez_indexer_module`](https://github.com/logos-blockchain/logos-execution-zone-indexer-module) -**in-process over the Logos protocol** (Qt Remote Objects) — no WebSocket, no -external RPC socket. +A QML block explorer for the **Logos Execution Zone** (LEZ), packaged as a `logos-module-builder` **`ui_qml`** module (universal authoring model). The QML view runs process-isolated in a `ui-host`, backed by a small C++ backend that reads from the [`lez_indexer_module`](https://github.com/logos-blockchain/logos-execution-zone-indexer-module) **in-process over the Logos protocol** (Qt Remote Objects) — no WebSocket, no external RPC socket. ## Features @@ -28,8 +23,7 @@ external RPC socket. into QVariant for the view, and polls the chain tip for live updates. - `src/qml/` — the view (`Main.qml`, `pages/`, `components/`, `icons/`). -The `*Plugin` / `*Interface` glue is generated by the builder from the `.rep` + -`metadata.json` (`interface: "universal"`). +The `*Plugin` / `*Interface` glue is generated by the builder from the `.rep` + `metadata.json` (`interface: "universal"`). ## Building with Nix @@ -40,10 +34,23 @@ nix run . # preview in logos-standalone-app (spawns the ui-host) nix build .#lgx # bundle as a .lgx for logos-basecamp ``` -Running against live data needs the indexer reachable; enter its -`indexer_config.json` path in the explorer's config field (leave blank if the -indexer is already running). Load the explorer and indexer `.lgx` bundles -together in logos-basecamp for the full experience. +Running against live data needs the indexer reachable; enter its `indexer_config.json` path in the explorer's config field (leave blank if the indexer is already running). Load the explorer and indexer `.lgx` bundles together in logos-basecamp for the full experience. + +## Testing + +`tests/ui-tests.mjs` holds UI smoke tests (auto-detected by `mkLogosQmlModule`): they launch the view, wait for it to come up, and check the home page renders. They don't require a running indexer — with none ingesting, the backend stays in its "Connecting" empty state, which is expected. + +```sh +git add -A # nix only sees tracked files +nix build .#integration-test -L # build + run the tests (logs streamed with -L) +``` + +To iterate interactively against a local, un-pushed indexer branch, add the override used during development: + +```sh +nix build .#integration-test -L \ + --override-input lez_indexer_module path:../logos-execution-zone-indexer-module +``` ## License diff --git a/tests/ui-tests.mjs b/tests/ui-tests.mjs new file mode 100644 index 0000000..4147571 --- /dev/null +++ b/tests/ui-tests.mjs @@ -0,0 +1,28 @@ +import { resolve } from "node:path"; + +// CI sets LOGOS_QT_MCP automatically; for interactive use: +// nix build .#test-framework -o result-mcp +const root = process.env.LOGOS_QT_MCP || new URL("../result-mcp", import.meta.url).pathname; +const { test, run } = await import(resolve(root, "test-framework/framework.mjs")); + +// Smoke tests: the view loads and the home page renders. They do NOT assert a +// live indexer connection — with no indexer ingesting, the backend stays in +// "Connecting" (chain tip is 0), which is the correct empty state. They only +// verify the QML view comes up and the backend is wired (readiness overlay +// clears, revealing the navigation bar + home page). + +test("lez_explorer_ui: loads the view", async (app) => { + await app.waitFor( + async () => { await app.expectTexts(["LEZ Explorer"]); }, + { timeout: 30000, interval: 500, description: "the explorer view to load" } + ); +}); + +test("lez_explorer_ui: renders the home page", async (app) => { + await app.waitFor( + async () => { await app.expectTexts(["Recent Blocks", "Indexer config"]); }, + { timeout: 15000, interval: 500, description: "the home page to render" } + ); +}); + +run();