mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
* test(performance): add J4 search journey Measures typing a six-character query into the header search box on /workspace/search until the global search results settle, on a profile with the M3U fixture and the mock's existing 12,000-item `large` Xtream catalog. Counters: bridge calls and SQL statements per search (with a per-keystroke breakdown), serial IPC depth, DOM mutations, change-detection ticks, layout shift and long tasks; wall-clock last keystroke to settled and first keystroke to first result. Runs in the existing journeys target and the warn-only CI job, whose summary now prints the per-keystroke table. Moves J3's picsum artwork blocker into a shared helper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(performance): J4 settles only on the final term's query The probe could settle on cards of an earlier term that stay visible while the final term debounces. The journey now stamps every dbGlobalSearch trace event in the main process, and the record requires the last query between the sentinels to be for the final term and to have completed before the end sentinel. Iterations with a keydown gap over 250 ms (below the 350 ms debounce) are rejected; gaps and the final query are kept as evidence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(performance): anchor J4's SQL count to the journey sentinels renderer.sqlStatementsPerSearch was the difference of test-side samples taken before the first key and after the end sentinel had been read, so database work in either gap could be counted. The main process now reads main.sqlStatements when the start and end sentinels arrive, and the counter is their difference; sqlStatementsAfterSettled starts at the end sentinel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: 4gray <fourgray@proton.me> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
83 lines
4.3 KiB
YAML
83 lines
4.3 KiB
YAML
name: Run the performance journeys
|
|
description: >-
|
|
Runs `pnpm run perf:journeys` under xvfb on an Ubuntu runner, writes the
|
|
measurements to the job summary and returns the path of the summary.json
|
|
it wrote. Callers check out, set up pnpm and Node, install dependencies
|
|
and upload what they need. Contract: docs/architecture/performance-journeys.md.
|
|
|
|
outputs:
|
|
summary:
|
|
description: Path of the journey summary.json this run wrote.
|
|
value: ${{ steps.summary.outputs.path }}
|
|
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
# The journeys drive Electron through Playwright's _electron API
|
|
# and never launch a Playwright browser, so no `playwright
|
|
# install`. The runner image ships Electron's shared libraries and
|
|
# xvfb; fail fast with a clear message if an image update drops one.
|
|
# pnpm skips Electron's postinstall, so download the binary first;
|
|
# otherwise ldd sees no file and the check passes vacuously.
|
|
- name: Check Electron runtime dependencies
|
|
shell: bash
|
|
run: |
|
|
command -v xvfb-run || { echo "::error::xvfb-run is missing on the runner"; exit 1; }
|
|
node tools/testing/ensure-electron-binary.mjs || { echo "::error::Electron binary download failed"; exit 1; }
|
|
missing="$(ldd node_modules/electron/dist/electron | grep 'not found' || true)"
|
|
if [ -n "$missing" ]; then
|
|
echo "::error::Electron is missing shared libraries:"
|
|
echo "$missing"
|
|
exit 1
|
|
fi
|
|
|
|
# The Nx target builds electron-backend:build-performance first
|
|
# and playwright.journeys.config.ts starts the Xtream mock server.
|
|
- name: Run the performance journeys
|
|
shell: bash
|
|
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" pnpm run perf:journeys
|
|
env:
|
|
CI: 'true'
|
|
NX_TASKS_RUNNER_DYNAMIC_OUTPUT: 'false'
|
|
|
|
# Every run writes a fresh timestamped directory, so a clean
|
|
# checkout must hold exactly one summary.
|
|
- name: Locate the journey summary
|
|
id: summary
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
mapfile -t summaries < <(find dist/performance/journeys -mindepth 2 -maxdepth 2 -name summary.json)
|
|
if [ "${#summaries[@]}" -ne 1 ]; then
|
|
echo "::error::Expected one journey summary, found ${#summaries[@]}"
|
|
exit 1
|
|
fi
|
|
echo "path=${summaries[0]}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Report journey measurements
|
|
shell: bash
|
|
env:
|
|
SUMMARY: ${{ steps.summary.outputs.path }}
|
|
run: |
|
|
set -euo pipefail
|
|
jq -r '
|
|
"## Performance journeys (\(.harness.platform), \(.harness.measuredIterations) measured iterations)", "",
|
|
(.journeys | to_entries[] | .key as $journey | .value as $j |
|
|
"### `\($journey)`", "",
|
|
"| Measurement | Value | Iterations |",
|
|
"| --- | ---: | --- |",
|
|
(($j.counters // {}) | to_entries[] |
|
|
($j.counterStability[.key] // {}) as $s |
|
|
"| `\(.key)` | \(.value) | \(($s.values // []) | map(tostring) | join(", "))\(if $s.stable == false then " (unstable)" else "" end) |"),
|
|
(($j.wallClock // {}) | to_entries[] | "| `\(.key)` | \(.value) | |"),
|
|
"",
|
|
([($j.iterations // [])[] | select(.warmup | not) | .evidence.ipcSerialDepth // empty][0] // empty |
|
|
"Serial IPC chain (first measured iteration): \(.chain | map("`\(.)`") | join(" → "))", ""),
|
|
([($j.iterations // [])[] | select(.warmup | not) | .evidence.perKeystroke // empty][0] // empty |
|
|
"Per keystroke (first measured iteration):", "",
|
|
"| Key | Query calls | Bridge calls | SQL statements | DOM mutations | CD ticks |",
|
|
"| --- | ---: | ---: | ---: | ---: | ---: |",
|
|
(.[] | "| `\(.key)` | \(.queryCalls) | \(.ipcCalls) | \(.sqlStatements) | \(.domMutations) | \(.cdTicks) |"),
|
|
""))
|
|
' "$SUMMARY" | tee -a "$GITHUB_STEP_SUMMARY"
|