Skip to content

v1.3.36.8 -- Capture: threats screenshot helper

A bugfix on top of v1.3.36.7. v1.3.36.7's selector chain (h1 + waitForSettled + 1s settle) reaches the screenshot step reliably, but the screenshot itself -- page.screenshot({ fullPage: true }) via shotFullScroll -- timed out at 10 s in the operator's prod. Cause: /threats is materially heavier than other long-list surfaces because the Collections section enumerates every CrowdSec scenario installed (54+ in the operator's prod), so a fullPage capture has to paint and snapshot a very tall composited tree. v1.3.36.8 switches test 20 to shotFull (viewport-only).

argosVersion and frontend/package.json deliberately stay at 1.3.35.4 (tooling-only). scripts/capture/package.json bumps 1.3.36.7 -> 1.3.36.8.

Why

v1.3.36.7 was a selector fix; the screenshot helper was left at v1.3.36.1's shotFullScroll choice without re-evaluation. The operator's run reached the screenshot step (h1 + waitForSettled + 1s settle all succeeded), then page.screenshot({ fullPage: true }) hit Playwright's default 10 s screenshot timeout.

PHASE 0 verification against test #19 (security-overview.png, /security/hosts): also uses shotFullScroll and works fine in operator's prod. So shotFullScroll itself is not broken -- /threats is specifically heavier. Threats.tsx structure:

  • h1 + stats cards (4 KPI cards)
  • <section> Active decisions (table or empty/loading)
  • <AddDecisionForm /> (always rendered)
  • <section> Collections (one card per scenario from /api/security/scenarios, ~54 in operator's prod)

The Collections section is the heavy one. It is internal CrowdSec inventory, not operator-facing screenshot material -- the docs portal page that uses threats-decisions.png only illustrates the active- decisions UX. shotFull (viewport-only) captures exactly what the docs portal needs (h1 + stats cards + top of Active decisions) without paying the cost of rendering Collections to PNG.

Helper inventory across the spec post-fix:

Helper Use case Test 20
shotFull above-fold / modals YES
shotFullScroll long lists with N rows no

This is a one-line change at the screenshot call site; all selector / wait logic from v1.3.36.7 is preserved.

Fix

test('20. threats-decisions.png', async ({ page }) => {
  await page.goto('/threats');
  await page.waitForSelector('h1:has-text("Threats")', { timeout: 10_000 });
  await waitForSettled(page);
  await page.waitForTimeout(1000);  // render-settle
  await shotFull(page, 'threats-decisions');  // was shotFullScroll
});

The comment block in test 20 now records the v1.3.36.7 selector history AND the v1.3.36.8 helper switch as a single regression-context block, so future readers don't have to spelunk three release notes to understand the test.

Smoke phase 14 update

Phase 14 grows one new assert (5 total):

14. threats-decisions selector + screenshot fix:
    - Active code uses h1:has-text("Threats")
    - Old broken 'table, [role="tabpanel"]' selector gone
    - v1.3.36.6 h2:has-text("Active decisions") wait gone
    - test 20 calls shotFull(page, ...)
    - test 20 does NOT call shotFullScroll(page, ...)  <- new
    - Threats.tsx still has <h1> + 'Threats' text

The new asserts scope shotFull / shotFullScroll checks to the test 20 block (via awk '/^test\(.20\. threats-decisions/,/^\}\);/') so other tests' use of shotFullScroll doesn't false-positive the v1.3.36.8 regression-guard.

Smoke result post-fix

phase 1:  run.sh refuses without .env...                     PASS
phase 2:  .env is git check-ignore'd...                      PASS
phase 3:  .env.example placeholders only...                  PASS
phase 4:  safeClick synthetic test...                        PASS (13/13)
phase 5:  working tree unchanged by smoke...                 PASS
phase 6:  storageState wiring (v1.3.36.1)...                 PASS (5/5)
phase 7:  banner output uses fs.readFileSync...              PASS
phase 8:  viewport 1440x1080 + shotFullScroll...             PASS
phase 9:  waitForSettled helper (timing fix)...              PASS (5/5)
phase 10: openModal modal-visibility wait + TG selector...   PASS (6/6)
phase 11: host-row triggers click button[aria-label=edit]... PASS (2/2)
phase 12: safeClickTab helper + tab-click migrations...      PASS (7/7)
phase 13: DNS-01 selector fix...                             PASS (3/3)
phase 14: threats-decisions selector + screenshot fix...     PASS (5/5)

scripts/check-no-personal-data.sh clean. mkdocs build --strict clean.

Files changed

  • scripts/capture/capture.spec.js -- test 20 last line switches shotFullScroll -> shotFull; comment block rewritten to document v1.3.36.8 helper switch alongside v1.3.36.7 selector history.
  • scripts/capture/package.json -- 1.3.36.7 -> 1.3.36.8.
  • scripts/smoke/capture-automation.sh -- phase 14 gains scoped shotFull / shotFullScroll regression-guards against test 20.
  • docs/release-notes/v1.3.36.8.md -- this file.
  • CHANGELOG.md, mkdocs.yml.

NOT changed: argosVersion stays at 1.3.35.4, frontend/package.json version stays at 1.3.35.4. No Go code; no frontend code; no panel binary change.

Operator workflow post-fix

cd ~/argos-edge && git pull
scripts/capture/run.sh

# Verify post-fix:
# 1. threats-decisions.png shows the above-fold view of
#    /threats: page header + stats cards + top of the
#    Active decisions section. Collections is below the
#    fold and intentionally not in the frame.
# 2. Test 20 runs in ~3-4s end-to-end (no 10s screenshot
#    timeout).
# 3. No regression on other surfaces -- security-overview
#    (test 19) and other shotFullScroll users keep
#    working.

Versioning

scripts/capture/package.json 1.3.36.7 -> 1.3.36.8. Tag-without-rebuild precedent for tooling-only patches: v1.3.27.1, v1.3.34, v1.3.35.1, v1.3.35.5.