# Release smoke test

Run this on a **clean Chrome profile** (Settings → Profiles → Add → New)
before announcing a new build. Anything that can fail silently lives in
this list.

Roughly 15 minutes start to finish.

## 0. Prerequisites

- [ ] `npm run build` from `statisticasino/` finished without errors.
      This rebuilds `static/downloads/casino-inspector.zip` from the
      current `casinoMalwareExtension/` tree (the prebuild script does
      it automatically) and produces the production server bundle.
- [ ] The website is running somewhere reachable (locally with
      `node build`, or on its real production host). Note the URL.
- [ ] `casinoMalwareExtension/serialize.js`'s `FLUSH_ENDPOINT` and
      `casinoMalwareExtension/manifest.json`'s `host_permissions` both
      point at that same URL. **If either still says
      `statisticasino.example.com`, stop and fix it before continuing.**
      The current production URL is
      `http://www.sinostatistica.net/api/flush` (matching
      `host_permissions` entry: `http://www.sinostatistica.net/*`);
      flip both to `https://...` once site TLS is enabled per
      `statisticasino/DEPLOYMENT.md` §6.
- [ ] Manifest `version` was bumped since the last release (otherwise
      Chrome aggressively caches the old icon).

## 1. Install via the contribute page

- [ ] In a fresh Chrome profile with no extensions, navigate to
      `<site>/contribute`.
- [ ] Click "Download .zip". Confirm the download is named
      `casino-inspector.zip` and is a few MB.
- [ ] Unzip into a folder you'll remember.
- [ ] Open `chrome://extensions`, toggle Developer mode on, click
      "Load unpacked", select the unzipped folder.
- [ ] Confirm the extension appears with the new name (NOT
      "Casino.org Inspector (Dev)").
- [ ] Confirm the toolbar icon shows the **two-card** branding
      (Ace of Hearts overlapping a card back), not the puzzle-piece
      placeholder. Pin the extension so the icon stays visible.

If the icon shows the puzzle piece for more than ~10 seconds after
install, something went wrong with the icon files. Check
`icons/icon32.png` exists in the unzipped folder and that
`manifest.json` references it.

## 2. Capture a hand

- [ ] Open `https://www.casino.org/replaypoker/play/...`. Sit at any
      table and play (or watch) one full hand.
- [ ] Click the extension icon. The Game History tab opens.
- [ ] Confirm: at least one Player → Table → Round row exists.
- [ ] Click the round to expand the inline replay. Confirm the felt
      diagram, scrubber, and Prev/Next buttons all work.
- [ ] Confirm your seat is highlighted in red (perspective-owner).

## 3. Selection / action panel

- [ ] Click the parent checkbox at the table level. Confirm every
      child round becomes ticked, and the table parent becomes "all".
- [ ] Click one round-level checkbox to untick it. Confirm the table
      parent goes to "some" (the `-` indeterminate visual).
- [ ] Click "Cancel" in the action panel. Confirm everything clears.
- [ ] Click "Select all". Confirm every checkbox in every player /
      table / round is "all".

## 4. Flush

- [ ] With a non-empty selection, click "Flush now".
- [ ] Confirm the Sync card transitions to "flushing", then either
      "flushed" (success) or surfaces a readable error message.

If it fails, open the service worker DevTools (`chrome://extensions`
→ "service worker" link) and inspect the network call. The most
common cause is `FLUSH_ENDPOINT` not matching the running website
URL or its `host_permissions` allow-list.

## 5. Export `.casinodump`

- [ ] With a non-empty selection, click "Export". A `.casinodump`
      should download.
- [ ] On the website, sign in as admin, go to `/contribute`, drop
      that file on the upload form. Confirm the round shows up under
      `/data` after the page reloads.

## 6. Export readable

- [ ] With a non-empty selection, click "Export readable" in the
      extension. A `.json` file should download.
- [ ] Open it in a text editor. Confirm:
      - Top-level shape: an array of round objects.
      - Each round has `handId`, `firstTs`, `lastTs`, `hero`,
        `actions[]`.
      - `actions[]` are merged steps (postBlind, deal, bet, fold,
        showdown, etc.), NOT raw Phoenix frames.
      - For a hand whose hero name couldn't be resolved, `hero.name`
        is `null` (we don't fabricate one).

- [ ] On the website's `/data` page, select the same round and click
      "Export readable" there. Confirm the file shape matches the
      extension's output.

## 7. Delete (admin)

- [ ] Sign into the website as the admin account.
- [ ] On `/data`, select a couple of rounds. Click "Delete selected".
- [ ] Confirm those rounds disappear from the list.
- [ ] Sign out. Reload `/data`. The rounds remain hidden.
      (Soft-deleted rows have `removed_at` set; reads filter
      `WHERE removed_at IS NULL`.)
- [ ] Optional: open the DB and verify the rows are present with
      non-null `removed_at`/`removed_by_user_id`.

## 8. Sanity sweeps on a casino-org tab

While the extension is loaded:

- [ ] Open a non-casino tab (e.g. `https://example.com`). Confirm
      DevTools → "Sources" tab does NOT show injected scripts. The
      content scripts only match `https://*.casino.org/*`.
- [ ] In casino.org DevTools, in the Console, run
      `document.cookie`. Confirm the cookie string is **not** logged
      anywhere by the extension (search the bridge log).
- [ ] Confirm the extension's storage usage in
      `chrome://extensions` → Details → "Site storage" is reasonable
      (single-digit MB for a few hands).

## 9. Off switch

- [ ] In the extension's settings card, toggle "Capture enabled" off.
      Play another hand.
- [ ] Confirm no new round shows up in Game History.
- [ ] Toggle back on. Confirm new hands resume capturing.

## 10. Uninstall

- [ ] Remove the extension via `chrome://extensions`.
- [ ] Confirm `chrome.storage.local` is gone (visit `chrome://extensions`
      → Details → Site storage; the extension is no longer listed).

---

If every box above is checked, the build is good to go. If anything
is off, the most likely culprits in order: (1) `FLUSH_ENDPOINT`
mismatch with `host_permissions`, (2) stale icon cache from an
unbumped manifest version, (3) a forgotten `npm run build` so the
zip on `/contribute` is older than the source tree.
