From d9d6bdba64a303d89a18905f9346e6c482d6f041 Mon Sep 17 00:00:00 2001 From: s8n Date: Sun, 10 May 2026 00:47:20 +0100 Subject: [PATCH] testing/ folder: theme-edit guides + error catalog + headless recipes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 7 docs in /testing/ — institutional memory after 6+ regressions in 24-48h on the v6 theme. Read before any edit. README.md — index + quickstart THEMING.md — safe-edit checklist + layer/specificity tables ERROR-PATTERNS.md — 12 cataloged patterns (Symptom/Cause/Diag/Fix/Prev) HEADLESS-PROBE.md — 11 playwright recipes (md5 chain, darkPct, ancestor bg sample, dropdown listItem probe) ROLLBACK.md — 8 emergency revert recipes (overlay, branding, encoding, full-from-repo, dev-clone-prod, git-revert, pw-reset, bind-mount inode-swap) SMOKE-TEST.md — manual + headless verify checklist DEPLOY.md — dev → prod promotion workflow with backup + chown root + restart inode-swap Empty subdirs: snipUSER-Es/, recipes/, incidents/ (post-mortems land here). Goal: stop reinventing the same fixes. Catalog every error class, codify the recovery, build a skills folder for future ARRFLIX work. --- testing/DEPLOY.md | 74 +++++++++++++ testing/ERROR-PATTERNS.md | 215 +++++++++++++++++++++++++++++++++++++ testing/HEADLESS-PROBE.md | 209 +++++++++++++++++++++++++++++++++++ testing/README.md | 32 ++++++ testing/ROLLBACK.md | 154 ++++++++++++++++++++++++++ testing/SMOKE-TEST.md | 74 +++++++++++++ testing/THEMING.md | 123 +++++++++++++++++++++ testing/incidents/.gitkeep | 0 testing/recipes/.gitkeep | 0 testing/snippets/.gitkeep | 0 10 files changed, 881 insertions(+) create mode 100644 testing/DEPLOY.md create mode 100644 testing/ERROR-PATTERNS.md create mode 100644 testing/HEADLESS-PROBE.md create mode 100644 testing/README.md create mode 100644 testing/ROLLBACK.md create mode 100644 testing/SMOKE-TEST.md create mode 100644 testing/THEMING.md create mode 100644 testing/incidents/.gitkeep create mode 100644 testing/recipes/.gitkeep create mode 100644 testing/snippets/.gitkeep diff --git a/testing/DEPLOY.md b/testing/DEPLOY.md new file mode 100644 index 0000000..acb726d --- /dev/null +++ b/testing/DEPLOY.md @@ -0,0 +1,74 @@ +# DEPLOY — dev → prod promotion workflow + +> Strict order. Skip a step → break prod. + +## Pre-flight + +- [ ] testing/SMOKE-TEST.md passed on dev +- [ ] You can name the change in one sentence +- [ ] You have a rollback target (the current prod md5 — capture before deploy) + +## Step 1 — capture current prod md5 (rollback anchor) + +```bash +PROD_BEFORE=$(ssh user@nullstone 'md5sum /opt/docker/jellyfin/web-overrides/index.html' | awk '{print $1}') +echo "rollback anchor: $PROD_BEFORE" +``` + +If anything goes wrong: `cp /opt/docker/jellyfin/web-overrides/index.html.bak. /opt/docker/jellyfin/web-overrides/index.html` + restart. + +## Step 2 — backup prod overlay + branding + +```bash +ssh user@nullstone 'set -e +TS=$(date +%s) +docker run --rm --userns=host -v /opt/docker/jellyfin/web-overrides:/d:rw alpine cp /d/index.html /d/index.html.bak.deploy.$TS +docker run --rm --userns=host -v /home/docker/jellyfin/config/config:/d:rw alpine cp /d/branding.xml /d/branding.xml.bak.deploy.$TS +' +``` + +## Step 3 — copy dev overlay to prod via docker shim (root-owned dest) + +```bash +ssh user@nullstone 'docker run --rm --userns=host -v /opt/docker/jellyfin-dev/web-overrides:/dev:ro -v /opt/docker/jellyfin/web-overrides:/prod:rw alpine sh -c "cp /dev/index-dev.html /prod/index.html && chown root:root /prod/index.html && md5sum /prod/index.html"' +``` + +## Step 4 — bind-mount inode swap requires restart + +```bash +ssh user@nullstone 'docker restart jellyfin && sleep 14' +``` + +## Step 5 — verify + +```bash +ssh user@nullstone 'docker exec jellyfin md5sum /jellyfin/jellyfin-web/index.html' # should match dev's md5 +ssh user@nullstone 'docker exec jellyfin curl -s http://127.0.0.1:8096/web/index.html | grep -c ARRFLIX-MIDDLE-THEME-BEGIN' # = 1 +ssh user@nullstone 'docker exec jellyfin curl -s http://127.0.0.1:8096/Branding/Css.css | wc -c' # ~36000 +ssh user@nullstone 'docker ps --format "{{.Names}} {{.Status}}" | grep "^jellyfin "' # healthy +``` + +## Step 6 — manual smoke on prod + +Open arrflix.s8n.ru in incognito. Run testing/SMOKE-TEST.md manual checklist. + +## Step 7 — commit + push to repo + +```bash +cd /tmp/arrflix-recon +cp web-overrides/index.html snapshots/2026-05-09-v6-stable/index.html # update snapshot +git add bin/inject-middle-theme.py web-overrides/index.html snapshots/2026-05-09-v6-stable/index.html docs/ # whatever changed +git -c user.name=s8n -c user.email=admin@s8n.ru commit -m "" +git push origin main +``` + +## If verify fails + +Run `testing/ROLLBACK.md` immediately. Don't try to fix forward on prod. + +## Common deploy gotchas + +- Forget `docker restart jellyfin` after `cp` → bind-mount inode swap → container serves stale +- Forget `chown root:root` → user can't write but root needs to own per host config +- Forget snapshot bump → next "what's deployed" question gets wrong answer +- Forget commit → repo drifts from prod (per doc 26 INC1 root cause) diff --git a/testing/ERROR-PATTERNS.md b/testing/ERROR-PATTERNS.md new file mode 100644 index 0000000..2b5d9be --- /dev/null +++ b/testing/ERROR-PATTERNS.md @@ -0,0 +1,215 @@ +# ERROR-PATTERNS — recurring theme/deploy/playback bugs + +> Bookmark this. Every pattern below has happened multiple times. Read before debugging. + +## Index of past errors + +| # | Pattern | First seen | Last seen | Recurrences | +|---|---------|------------|-----------|-------------| +| 1 | Black screen over video (CSS overlay) | 2026-05-09 INC1 | 2026-05-10 image-12 | 6+ | +| 2 | Video covers OSD controls (z-index too high) | 2026-05-10 image-12 | 2026-05-10 image-12 | 1 | +| 3 | Bind-mount inode swap (container serves stale) | 2026-05-09 backHide | 2026-05-10 v4-selector | 3+ | +| 4 | branding.xml XML parse silent fail | 2026-05-09 v6-stable | 2026-05-09 v6-stable | 1 | +| 5 | test/123 password nuked after docker cp | 2026-05-09 multi | 2026-05-10 multi | 5+ | +| 6 | DB readonly after docker cp (uid 101000) | 2026-05-09 multi | 2026-05-10 multi | 4+ | +| 7 | camelCase class typo (.htmlVideoPlayer) | 2026-05-09 a6cf925 | 2026-05-09 a6cf925 | 1 | +| 8 | Wrong Jellyfin class assumption | 2026-05-09 multi | 2026-05-10 multi | 3+ | +| 9 | HDR10 grey wash (tonemap off) | 2026-05-08 doc 21 | 2026-05-09 fix | 1 | +| 10 | Favicon clobbered by lockFavicon shim | 2026-05-09 favfix | 2026-05-09 favfix | 1 | +| 11 | Backdrop residue / carousel black band | 2026-05-09 multi | 2026-05-10 multi | 2+ | +| 12 | Quick Connect bypass + login mismatch | 2026-05-09 dev | 2026-05-09 dev | 1 | + +## ERROR 1 — Black screen over video (CSS overlay) + +**Symptom.** `