content(guide): Testing tabs for all 63 modules — slim frontend QA checklists (DRAFT)

Every customer module now has the full 5-lens set (Customer/Internal/Architect/
Testing/Claude). Testing = frontend-only what-to-test -> pass/fail checklist vs
bcos.dev sim data (C1/C2/C3 + test logins), audience internal. Authored via
per-module fan-out (2 retried on Sonnet 5).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 15:50:40 -04:00
parent 467b7243df
commit 2488408ee9
63 changed files with 2306 additions and 0 deletions
@@ -0,0 +1,35 @@
---
module: analytics.adoons
title: Adoons Insights
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Adoons Insights** (the **Fleet Insights** tab in Analytics, `analytics.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **analytics.bcos.dev** and open the **Adoons / Fleet Insights** tab — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 · read-only |
Insights describe the simulator fleet (**C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…**, plus C2-/C3-). Cards are fleet-wide, not per-device — you don't select a device here.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open the **Fleet Insights** tab | Header reads **FLEET INSIGHTS** with sub-text **Powered by Adoons fleet intelligence** and a **Refresh** button top-right |
| 2 | Look at any insight card on screen | Card shows a **severity** badge, a **category** badge, a **time** (e.g. "2h ago"), a **title** and a **detail** line, with a coloured **left border** matching the severity |
| 3 | Click **Refresh** | Button briefly shows a spinner + **Refreshing…**, then the list updates — **no red error bar** appears |
| 4 | Click the **✕** on one card | That card **disappears** from the list right away |
| 5 | Click **Refresh** again (or reload the tab) | The card you dismissed **does not come back** |
| 6 | Compare a **CRITICAL** or **HIGH** card against an **INFO** card | Higher-severity cards are visibly **red/orange**, INFO is **blue** — colour matches severity |
| 7 | Dismiss every card (or open a fleet with none) | Empty state shows a lightbulb icon and **"No active fleet insights"** — no error, no crash |
| 8 | Log in as `customer_a`, open the tab | You can **view** cards and use **Refresh** / **✕** — but there is **no Add / Create / Publish button** anywhere (no way to author an insight from the UI, for any role) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: analytics.agents
title: Agents
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Agents** tab in HiveIQ Analytics (`analytics.bcos.dev`). This tab is **view-only** — there is nothing to create, edit, or push. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **analytics.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open Analytics and click the **Agents** tab | Tab loads with three panels: **Version Distribution**, **Connection Status**, and **Outdated ATMs** — no error banner |
| 2 | Look at **Version Distribution** | Bars show a count per agent version; the version with the most ATMs has the longest bar and the current release carries a green **latest** badge |
| 3 | Look at **Connection Status** | Shows **Connected / Disconnected / Never Connected** with a count and a % on each, plus a **Latest: …** version line; the three percentages add up to ~100% |
| 4 | Look at **Outdated ATMs** | Either a table with columns **ATM ID · Version · Last Seen · Status**, or the green **"All ATMs are on the latest version"** message if the fleet is current |
| 5 | In the Outdated ATMs table, check the **Last Seen** and **Status** cells | Last Seen shows a relative time (e.g. **"2h ago"**, **"3d ago"**); Status shows a coloured badge — Connected green, Disconnected red, Never Connected grey |
| 6 | Scan the whole tab for action controls | There are **no Add / Edit / Delete / Update buttons** anywhere — it is a read-only snapshot |
| 7 | Watch the header (top right) and leave the tab open | It shows **"Updated … · Next in Ns"** counting down; when it refreshes a **"Refreshing…"** badge appears and the panels reload with no error |
| 8 | Log in as `customer_a` and open the **Agents** tab | Version counts, Connection Status, and the Outdated list reflect **only C1** devices (`C1-…`) — no C2 or C3 ATMs appear |
| 9 | Log in as `msp_a` and compare, then `bcos_a` | `msp_a` sees **C1 + C2** but not C3; `bcos_a` sees **all** institutions — totals grow accordingly |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,39 @@
---
module: analytics.cash
title: Cash Intelligence
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Cash Intelligence** tab (`analytics.bcos.dev`). Open the tab in the UI and mark each row Pass or Fail. This tab is **view-only** — there is nothing to create, edit, or delete.
## Set up
Log in at **analytics.bcos.dev**, then open the **Cash Intelligence** tab — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Cash Intelligence** | Page loads with four stat cards on top — **Balanced · Variance · Open Cycle · Pending Conf.** — each showing a number, and two tables below |
| 2 | Look at the **ATMs Near Empty** table (left) | Columns are **ATM ID · Est. Balance · Last Replenishment**, and rows are ordered **lowest balance first** (most urgent on top) |
| 3 | Find a row with a very low balance | Rows under ~$3,000 are highlighted **red** so they stand out |
| 4 | Look at the **ATMs With Variance** table (right) | Columns are **ATM ID · Variance · Cycle Status**, ordered **largest difference first**; a **negative** variance shows in **red** |
| 5 | Read a few ATM IDs in either table | The balances/variances are money-formatted (e.g. `$12,500.00`) and each ATM has a **Cycle Status** badge — nothing shows as blank or `undefined` |
| 6 | Find a category with nothing in it (or use a scope with no cash data) | The table shows a tidy **"No ATMs near empty" / "No ATMs with variance"** message — **no error or blank crash** |
| 7 | Scan the whole tab | There are **no Add / Create / Edit / Delete buttons** anywhere — it is read-only |
| 8 | As `customer_a`, open the tab | Every ATM ID listed starts with **C1-** — no C2 or C3 machines appear |
| 9 | As `msp_a`, open the tab | You see **C1 and C2** ATMs but **not C3** |
| 10 | Log in as `bcos_a`, open the tab | You see ATMs across **all institutions (C1 + C2 + C3)** |
> Note: on the admin (`bcos_a`) view, an ATM that has never had a cash cycle in Recon can appear in **Near Empty at $0.00** — that is expected, not a fail.
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: analytics.fleet-health
title: Fleet Health
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Fleet Health** tab in **Analytics** (`analytics.bcos.dev`). Click through in the UI and mark each row Pass or Fail. This screen is **read-only** — there is nothing to create, edit, or delete.
## Set up
Open **Analytics** in the **HiveIQ Browser** (a plain web browser shows a "Browser Required" message). Log in — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Analytics** | Header reads **HiveIQ Analytics**, **Fleet Health** is the highlighted (active) tab by default |
| 2 | Look at the **Fleet Health** screen | Four cards show: **Connectivity**, **Event Breakdown**, **Top Problematic ATMs**, **Alerts & Gaps** |
| 3 | Read the **Connectivity** donut | Center shows a **TOTAL** number, a big green **% connected**, and a legend with **Connected / Disconnected / Never connected** counts that add up to the total |
| 4 | Read the **Event Breakdown** bars | Categories (Hardware, Network, Cash, Power, Auth, System, Operations) are listed with the **longest bar on top** (sorted highest-first) |
| 5 | Read **Top Problematic ATMs** | A ranked list **#1, #2, #3…** shows sim ATM IDs (e.g. `C1-ATM-001`) each with an event count, worst first |
| 6 | Read **Alerts & Gaps** | Two numbers show: **Open Incidents** (red) and **ATMs with Journal Gaps** (yellow) |
| 7 | Watch the header, wait ~60s (don't touch anything) | The **"Next in Ns"** countdown ticks down and the screen **auto-refreshes** (a "Refreshing…" badge flashes / the "Updated" time changes) |
| 8 | Click the other tabs across the top, then click **Fleet Health** again | Tabs switch without error and Fleet Health loads back with its four cards |
| 9 | Log in as `customer_a`, open Fleet Health | **Top Problematic ATMs shows only C1- devices** (no C2 or C3) and the total ATM count is smaller than what `bcos_a` sees |
| 10 | Log in as `msp_a`, open Fleet Health | Top Problematic shows **C1- and C2- devices but no C3-** |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: analytics.incidents
title: Incident Trends
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Incident Trends** tab in Analytics (`analytics.bcos.dev`). This tab is **read-only** — there is nothing to create, edit, or delete, so the tests focus on the four panels rendering correctly and on role scoping. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **analytics.bcos.dev**, then open the **Incident Trends** tab — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Fleet data comes from the simulator devices: **C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Incident Trends** | Page loads with four panels: **30-Day Incident Trend**, **Event Category Breakdown**, **Peak Hours Heatmap**, **Recurring Failures** — no error/blank screen |
| 2 | Look at the **30-Day Incident Trend** line chart | It shows the message **"Not enough data"** — this is expected on the current build, so treat the message (not a drawn line) as a pass |
| 3 | Look at **Event Category Breakdown** | Ranked horizontal bars, **largest at the top**, each with a coloured bar and a count number on the right (e.g. Hardware, Network, Cash, Power, Auth, System) |
| 4 | Look at the **Peak Hours Heatmap** | A grid with days **MonSun** down the side and hours across the bottom; brighter red cells = busier periods |
| 5 | Hover any heatmap cell | A tooltip appears showing the **day, hour, and count** (e.g. "Wed 14:00 — 3") |
| 6 | Look at the **Recurring Failures** table | It renders without error — either rows of ATM / Event Type / Count, or the message **"No recurring failures"**. An empty table here is expected on the current build, so don't fail it for being empty |
| 7 | Scan the whole tab for buttons | There are **no Add / Edit / Delete / Export** buttons anywhere — this tab is view-only for every role |
| 8 | Log in as `bcos_a` (all institutions), note the Category/Heatmap totals; then log in as `customer_a` (C1 only) and compare | `customer_a` shows **the same or fewer** incidents than `bcos_a` — a customer never sees more data than the all-institution admin |
| 9 | Still as `customer_a`, confirm the page still loads its own C1 data | All four panels render with **no error and no institution picker** — scoping is automatic, not a dropdown |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,38 @@
---
module: analytics.transactions
title: Transactions
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Transactions** tab in **Analytics** (`analytics.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Open the **HiveIQ Browser** desktop app, sign in, and open **Analytics → Transactions** tab. (Analytics only runs inside the HiveIQ Browser app — a plain web browser shows a "requires browser" message.)
Test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions). Everything here is **today-only**, so empty tiles early in the day are normal, not a fault.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, click the **Transactions** tab | Tab loads showing five cards — **Today's Journal Volume**, **Parse Success Rate**, **Open Journal Gaps**, **ATMs With Gaps (Top 10)**, **Top 10 ATMs by Transaction Volume** — with no red error banner |
| 2 | Look at **Today's Journal Volume** | A bar chart with a legend **Successful (green) / Failed (red)** and dates along the bottom — or the message **"No data available"** if nothing was ingested today |
| 3 | Look at the **Parse Success Rate** ring | Shows a percentage inside a coloured ring — **green** at 95%+, **amber** at 8095%, **red** below 80% |
| 4 | Look at **Open Journal Gaps** and **ATMs With Gaps (Top 10)** | A count of unresolved gaps, plus a table of **ATM ID + Gap Count** — or **"No ATMs with open gaps"** when there are none |
| 5 | Look at **Top 10 ATMs by Transaction Volume** | A ranked list **#1…#10** of ATM IDs, each with a blue bar and a transaction count — or **"No transaction data available"** if empty |
| 6 | Watch the header for ~1 minute without touching anything | The **"Next in Ns"** countdown ticks down and the tab auto-refreshes (a brief **"Refreshing…"** badge appears) — no manual reload needed |
| 7 | Log in as `customer_a`, open the Transactions tab | Any ATM IDs listed (Top 10 / ATMs with gaps) are **only C1-** devices — no C2- or C3- (or empty if no journals today) |
| 8 | As `msp_a`, check the ATM IDs listed | You see **C1- and C2-** devices but **no C3-** |
| 9 | Scan the whole tab for any Add / Create / Edit / Delete button | There are **none** — the tab is view-only for every role |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: analytics.uptime
title: Uptime
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Uptime** tab in Analytics (`analytics.bcos.dev`). This screen is **read-only** — there are no buttons, forms, or actions, so the tests are all about what you can *see*. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **analytics.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Analytics → Uptime** | Page loads with four KPI cards across the top: **NOW**, **7-DAY AVG**, **30-DAY AVG**, **CURRENTLY DOWN** |
| 2 | Look at the **NOW** ring | It shows a percentage (e.g. `98.5 %`) inside a coloured ring — **green** ≥95%, **amber** 8094%, **red** below 80% |
| 3 | Look at **7-DAY AVG** and **30-DAY AVG** | Each shows its own percentage ring (they may read the same number — that's expected, not a fail) |
| 4 | Look at the **CURRENTLY DOWN** card | Either a green **All online** check, or a red number **X of N ATMs**; if any never connected, a small **"N never connected"** badge appears |
| 5 | Look at the **30-Day Uptime Trend** panel | You see either a trend line with 80% / 90% / 100% guide marks and a dot on the right, **or** the message **"Not enough data"** — both are valid, no crash |
| 6 | Look at the **ATMs Currently Down** table at the bottom | Either **All ATMs online** with a green check, or a table with columns **ATM · Status · Down Since** and a Down Since like `2h 15m` |
| 7 | Scan the whole Uptime screen | There are **no** action buttons — no Add, Edit, Delete, Export or Refresh anywhere (read-only screen) |
| 8 | Log in as `customer_a`, open **Uptime** | Any ATMs listed in **Currently Down** are **only C1** devices — no C2 or C3 IDs appear |
| 9 | Log in as `msp_a`, open **Uptime** | Down list / counts cover **C1 and C2** only — **no C3** devices |
| 10 | Navigate away to another tab and back to **Uptime** | The screen re-loads its numbers on open (no button needed) and shows data — **no error/blank crash** |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: aria.dashboard
title: Threat Dashboard
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **ARIA Threat Dashboard** (`aria.bcos.dev`) — the landing screen of the ARIA SPA. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **aria.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | Full ARIA dashboard (BCOS_ADMIN only) |
| `msp_a@msp1.bcos.dev` | MSP admin | **No access** — dashboard fails to load |
| `customer_a@customer1.bcos.dev` | Customer | **No access** — dashboard fails to load |
The cards are fleet-wide totals built from the simulator devices (**C1-ATM-001…**, **C1-TCR-001…**, and C2-/C3- for the other institutions). The dashboard loads **once on open** — there is no refresh button, so reload the page to re-pull numbers.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open the **ARIA Dashboard** | Page loads with header **ARIA Dashboard** and three sections: **Threat Activity**, **Compliance**, **Phase Coverage** — cards show numbers, no "Load Failed" toast |
| 2 | Look at the **Threat Activity** cards | Four cards visible: **Total Events**, **Critical**, **High**, **Active Sequences** |
| 3 | Click the **Critical** card | Jumps to the events list filtered to critical events |
| 4 | Click the **High** card | Jumps to the events list filtered to high events |
| 5 | Click **Active Sequences** | Opens the Precursor Alerts / sequences view |
| 6 | Click **Active IOCs** | Opens the IOC Management view |
| 7 | Click **Low Posture** (and **EOL Devices**) | Opens the Device Posture view |
| 8 | Try clicking **Total Events** and **Non-Critical Events** | Nothing happens — these two cards are **not clickable** (no hover lift, no navigation) |
| 9 | Scroll to **Phase Coverage** | Shows five reference rows: Physical Access, Malware Staging, Malware Execution, Persistence, Cleanup — each with a description |
| 10 | Log in as `msp_a`, then `customer_a`, open the dashboard | Both see a **"Could not load ARIA stats"** error toast with empty/no cards — ARIA is admin-only |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: aria.device-posture
title: Device Posture
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Device Posture** (`aria.bcos.dev`). Click through in the UI and mark each row Pass or Fail. This screen is **read-only** — there is nothing to create, edit, or delete.
## Set up
Log in at **aria.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin (BCOS_ADMIN) | Full screen · all institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | **No access** — screen is admin-only |
| `customer_a@customer1.bcos.dev` | Customer | **No access** — screen is admin-only |
Test devices are the simulators grouped under institutions **C1BD / C2BD / C3BD** — e.g. **C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…**.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Device Posture** | Table loads with institution group headers (e.g. **C1BD**, **C2BD**), each **collapsed** and showing a device count + average score |
| 2 | Click an institution header | The row expands (chevron **▶ → ▼**) and its device rows appear with columns **Device / OS Version / OS Status / Disk Enc. / … / Score / Last Check** |
| 3 | Click a device row (or its **Detail** button) | A panel slides in from the right showing a big **Posture Score** and a per-check breakdown (Disk Encryption, Audit Policy, Software Whitelist, OS Version, OS EOL) |
| 4 | In the panel, look at a failing check (e.g. Disk Encryption **✗**), then close with **✕** / **Close** / clicking the dark overlay | The failing check shows a red penalty chip (e.g. **25**); closing dismisses the panel |
| 5 | Open **Filters** (**▶** on the left sidebar), set **Score** → **Below Good (<80)** | The list narrows to only devices scoring under 80, and a **Score: Below Good (<80)** chip appears at the top |
| 6 | Set **OS Status** → **EOL**, then remove filters via a chip **×** or **✕ Clear all** | Only devices with an **EOL** badge remain; clearing brings the full list back |
| 7 | Turn the **Auto-refresh** toggle off, then click the **↻** button | The countdown (e.g. "(60s)") disappears when off; clicking **↻** reloads the list (button briefly shows **⟳**) |
| 8 | Find an institution header that contains a low-scoring device | The header shows an amber **⚠ below 80** flag and a colour-coded average score |
| 9 | Log in as `msp_a`, then `customer_a`, and open **Device Posture** | **No** posture data shows and a **Load Failed** error toast appears — ARIA posture is BCOS_ADMIN-only (this is expected, not a bug) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: aria.ioc-feeds
title: IOC Feeds
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **IOC Feeds** in ARIA (`aria.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **aria.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | IOC Feeds — full access |
| `msp_a@msp1.bcos.dev` | MSP admin | IOC Feeds **not** available |
| `customer_a@customer1.bcos.dev` | Customer | IOC Feeds **not** available |
IOC Feeds pulls global threat data (AlienVault OTX, MalwareBazaar, ThreatFox) — it is **not** scoped to institutions or devices, so there is no C1/C2/C3 split here. Access is admin-only.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **IOC Feeds** | Page loads with **three feed cards** — AlienVault OTX, MalwareBazaar, ThreatFox — and a **Run history** table below |
| 2 | Look at each feed card | Each shows a **status badge** (Success / Error / Running / Never run), a **Configured** or **API key required** tag, and **Last run / IOCs added / Updated** stats |
| 3 | Find a card tagged **API key required** | Its **↻ Run Feed** button is **greyed out / disabled** (card has an amber tint) |
| 4 | Click **Run All Feeds** | Button shows **Running…** and a success toast appears; after a few seconds the status and Run history reload |
| 5 | On a **Configured** card, click **↻ Run Feed** | A toast confirms that feed is refreshing; the card badge can move to **Running** then update *(if every card shows "API key required", all single Run buttons are disabled — note it and skip)* |
| 6 | Click **Refresh** (grey button) | Status and history **reload**, but **no new run row** is added to the history |
| 7 | In **Run history**, hover a row's **Error** cell that has text | A tooltip shows the **full error message** (the cell itself may be truncated with …) |
| 8 | Leave the screen open ~30 seconds without clicking | Status **refreshes on its own** (the "Last run" times update) — no manual reload needed |
| 9 | Log in as `msp_a`, then `customer_a`, and look for IOC Feeds | The screen is **not available** to them (not in the menu, or it shows no feed data) — only the admin can use it |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: aria.ioc-management
title: IOC Management
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **IOC Management** in ARIA (`aria.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **aria.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | Full IOC Management — can add / edit / deactivate |
| `msp_a@msp1.bcos.dev` | MSP admin | **No access** — this screen is admin-only |
| `customer_a@customer1.bcos.dev` | Customer | **No access** — this screen is admin-only |
This is a **global watchlist** — it is not tied to a device or institution, so no simulator devices are needed. The list starts pre-seeded with FBI FLASH indicators (e.g. Ploutus jackpotting filenames).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **IOC Management** | Table loads with columns **Type · Value · Description · Source · Confidence · Added · Expires · Status** and some seeded rows |
| 2 | Expand the **Filters** sidebar (▶) and click a type pill (e.g. **Filename**) | Only that type shows, a filter chip appears up top, and the count updates. **Clear all** brings every row back |
| 3 | In Filters, tick **Show inactive** | Retired **Inactive** rows appear (dimmed) alongside the Active ones |
| 4 | Click **+ Add IOC**, leave Type/Value blank, click **Add IOC** | A validation warning shows and **nothing is added** — panel stays open |
| 5 | Fill Type **Filename**, Value `qa-test.exe`, Confidence **High** → **Add IOC** | Panel closes, success toast, new row appears as **Active** with Source **Manual** and Confidence **HIGH** |
| 6 | Click **Edit** on that new row | Panel opens with **IOC Type greyed out / not editable**; change the Description and **Update** → new description shows in the row |
| 7 | Click **Deactivate** on that row, confirm the prompt | Row flips to **Inactive** (dimmed) and its **Deactivate** button disappears; with **Show inactive** on it still lists |
| 8 | Log in as `msp_a`, try to open **IOC Management** | **No editable list** — screen is empty / blocked / errors (admin-only), not the full watchlist |
| 9 | Log in as `customer_a`, try to open **IOC Management** | Same — **no access** to the IOC watchlist |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: aria.precursor-alerts
title: Precursor Alerts
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Precursor Alerts** (`aria.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **aria.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All alerts — the only account that can use this screen |
| `msp_a@msp1.bcos.dev` | MSP admin | **Nothing** — admin-only screen (used for the role check) |
| `customer_a@customer1.bcos.dev` | Customer | **Nothing** — admin-only screen (used for the role check) |
Alerts are raised on the simulator devices: **C1-ATM-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Precursor Alerts** | Page loads with heading **Precursor Alerts** and a table with columns **Type / Device / Phases Detected / Confidence / Triggered / Status** — list defaults to **Active** alerts |
| 2 | Open the filters with the **▶** arrow (left), set **Type = Jackpotting** | List narrows to only **💰 Jackpotting** rows and a **Type: JACKPOTTING** chip appears above the table |
| 3 | Change **Status** to **Resolved**, then **All** | List switches to resolved-only, then to every alert; the count above the table updates |
| 4 | Type a device (e.g. `C1-ATM-001`) into **Device ID** | After a moment the list shows only that device's alerts, with a **Device:** chip |
| 5 | Click **✕ Clear all** (or remove a chip with its ×) | All filters clear and the full Active list returns |
| 6 | Click any alert row (or its **Events** button) | A side panel slides in from the right showing **Events in Sequence** — the individual signals, their phase, and severity |
| 7 | On an **Active** row click **Resolve** (or **Mark Resolved** in the panel) | A green **Resolved** toast shows and the row's Status becomes **Resolved** / drops out of the Active list |
| 8 | Turn the **Auto-refresh** toggle (top-right) off, then click the **↻** button | The toggle stops its countdown; **↻** reloads the list with no error |
| 9 | Log out and log in as `msp_a`, then as `customer_a`, open **Precursor Alerts** | Neither sees any alerts (empty list / "Load Failed") — this screen is admin-only, so this is expected, not a real bug |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: aria.threat-events
title: Threat Events
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Threat Events** (`aria.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **aria.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | Full Threat Events list (all institutions) |
| `msp_a@msp1.bcos.dev` | MSP admin | **No access** — Threat Events is admin-only |
| `customer_a@customer1.bcos.dev` | Customer | **No access** — Threat Events is admin-only |
Threat Events is a **read-only** screen — there is nothing to create, edit, or delete. Rows are detected events across the simulator fleet (devices like **C1-ATM-001**, **C1-TCR-001**, C2-/C3- for the others).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Threat Events** | Table loads with columns **Severity · Signal · Device · Attack Phase · IOC Match · Detected**, newest at top, and a count like "N events" in the toolbar |
| 2 | Open the **Filters** sidebar (▶) and pick **Severity → CRITICAL** | List narrows to only **CRITICAL** rows, a **Severity: CRITICAL** tag appears above the table, and the count drops |
| 3 | Click **✕ Clear all** in the Filters sidebar | All filters and tags clear and the full list comes back |
| 4 | With severity set to **All**, copy a **Device** value from any row into the Filters **Device ID** box | After a moment the list shows only that device's events and a **Device: …** tag appears (clear the Severity filter first, or the device box is ignored) |
| 5 | Toggle **Auto-refresh** off (top-right) | The countdown stops and the label reads just **Auto-refresh** (no `(60s)`); toggling it back on resumes the countdown |
| 6 | Click the **↻ refresh** button | A brief **Loading…** shows and the list reloads with no error toast and no crash |
| 7 | If there is more than one page, use the pager to go to page 2 | A different set of rows loads and the page indicator updates |
| 8 | Log in as `msp_a`, open **Threat Events** | You do **not** see the list — an empty screen or a **"Could not load threat events"** error toast (admin-only; this is expected) |
| 9 | Log in as `customer_a`, try **Threat Events** | Same as above — **no threat events are shown** (customer has no access) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: claims.claim-detail
title: Claim Detail
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Claim Detail** panel (`claims.bcos.dev`). Open a claim, click through each tab, and mark each row Pass or Fail.
## Set up
Log in at **claims.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Claims are tied to terminals — the simulator devices **C1-ATM-001…** (and **C2-/C3-** for the other institutions). Open a claim by clicking its row in the claims list.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, click any claim row in the list | A panel slides in from the **right** with tabs **Overview / Messages / Files / 🔒 Notes / Payment**, and the header shows the claim number, terminal, and a status badge |
| 2 | On **Overview**, read the details grid | You see Shortage amount, Loss Start/End, Terminal, CIT/SP Vendor, and dates — no blank "Could not load claim details" toast |
| 3 | Click **Edit**, change **Status** to **Waiting CIT**, click **Save** | A "Claim updated" toast appears and the status badge changes to **Waiting CIT** |
| 4 | In that same Edit form, note the **CIT/SP Vendor** dropdowns before saving | If a vendor shows **"— None —"**, saving **removes** that vendor from the claim — leave them as-is unless you mean to change them (expected behaviour, not a bug) |
| 5 | Open **Messages**, type a message, click **Send** | Your message appears in the thread on the **right**, labelled **"You"**, and the box clears |
| 6 | Open **Files**, click **+ Upload File**, pick a small file | The file appears in the list with its size and your name; clicking the file name **downloads** it |
| 7 | Open **🔒 Notes**, type a note, click **Add Note** | The note appears in the list with your name and time (these are internal-only) |
| 8 | Open **Payment**, click **Edit** on a card, change **Paid**, click **Save** | The card updates and **Balance** recomputes to **Owed Paid** |
| 9 | Click the **✕** to close, then log in as `customer_a` and open the claims list | You see **only C1** claims — no C2 or C3 terminals appear |
| 10 | Log in as `msp_a` and open the claims list | You see **C1 and C2** claims but **not C3** |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: claims.dashboard
title: Claims Dashboard
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Claims Dashboard** (`claims.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **claims.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | Its own institution's claims |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Claims are tied to the simulator terminals: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open the **Claims Dashboard** | Page loads with **six stat cards** (Active Claims, Deposit/Withdraw Exposure, Awaiting Response, Deposit/Withdraw Recovered YTD) above a claims table |
| 2 | Click any row in the claims table | That claim's **detail panel opens** showing its full info |
| 3 | Click **+ File New Claim** (top-right of the table) | The **New Claim form/panel opens** — you can close it without saving |
| 4 | Open the **Filters** sidebar (**»** on the left), type a terminal (e.g. `ATM-001`) in **Terminal ID** | List narrows to only claims on matching terminals; the **count above the table updates** |
| 5 | In Filters, click a **Status** pill (e.g. **Open**) | Only claims with that status show; click again to deselect and they return |
| 6 | Click **✕ Clear all** in the Filters sidebar | Every filter resets and the **full claim list** comes back |
| 7 | Click the **Shortage** (or **Claim #**) column header | Rows **re-sort** by that column; clicking again flips the order |
| 8 | Turn the **Auto-refresh** toggle off, then click the **↻** refresh button | Countdown stops when off; **↻** reloads the list on demand — no error |
| 9 | Log in as `customer_a`, open the dashboard | You see **only C1** claims (all terminals start `C1-`) — no C2 or C3 claims |
| 10 | Still as `customer_a`, look at the table toolbar | **+ File New Claim is still shown** (Claims has no read-only lock) — pass if the button is present and clicking it opens the form |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,35 @@
---
module: claims.settings
title: Settings
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Claims → Settings** (`claims.bcos.dev`). The Settings screen is a **read-only** view of the effective vendor-email template — there is nothing to create or edit here. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **claims.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
This module has no simulator-device dependency — it shows the email template for the **logged-in user's institution**.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, in the left sidebar under **System** click **⚙️ Settings** | The item expands and shows a **✉️ Email Template** sub-item |
| 2 | Open the **Email Template** screen | Header reads **Settings** with the sub-line about email templates, and the template card loads (never stuck on **Loading…**) |
| 3 | Look at the template card | It shows exactly **one** of: **Active Template** (blue), **Global Template (inherited)** (purple) with name + subject, or a **No template configured** fallback card — no error or blank screen |
| 4 | Scan the whole Settings screen for controls | There is **no Add / Edit / Save / Delete** button anywhere — the screen is view-only |
| 5 | If the card shows **Global Template (inherited)** or **No template configured** | It displays a **"contact your administrator"** note instead of any inline editor |
| 6 | Log in as `customer_a`, open **Settings → Email Template** | The screen loads and is viewable (not blocked for customers); it reflects **only C1** and offers no way to switch institution |
| 7 | Log in as `bcos_a`, open **Settings → Email Template** | Same read-only Email Template card appears — admin gets **no extra edit controls** here |
| 8 | On the Settings screen, refresh the browser (F5) | The Email Template card re-loads to the **same state** and settles — no permanent **Loading…**, no crash |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: claims.vendors
title: Vendors
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Vendor Registry** (`claims.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **claims.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Vendors are the CIT / SP companies you register per institution — there are no simulator devices for this screen.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Vendors** | Page loads with header **Vendor Registry**, a **{n} vendors** count, and two sections: **CIT — Cash-in-Transit** and **SP — Service Provider**, each with its own count |
| 2 | Click **+ Add Vendor** in the toolbar | A panel slides in **from the right** with fields **Vendor Name\***, **Type** (CIT / SP), **Contact Name**, **Contact Email**, **Contact Phone** |
| 3 | Fill Name `Acme CIT`, Type **CIT**, add contact/email/phone → **Add Vendor** | Success toast **"Acme CIT registered successfully"**, panel closes, and the new row appears in the **CIT** table with its details |
| 4 | Click **+ Add Vendor** again, Type **SP**, submit | New vendor appears under the **SP** section (not CIT), and the **SP** count goes up by one |
| 5 | Open the panel, leave **Vendor Name** blank, click **Add Vendor** | Inline error **"Vendor name is required"** under Name, and nothing is saved |
| 6 | Type an invalid email like `nope` into **Contact Email**, submit | Inline error **"Enter a valid email address"** and the submit is blocked (an empty email is allowed) |
| 7 | Add a vendor with **only** Name + Type (no contact fields) | Its **Contact / Email / Phone** cells show a dash **(—)**, not blank or an error |
| 8 | Look at any existing vendor row | There is **no edit and no delete** control — once added, a vendor can't be changed from the UI (this is expected, not a bug) |
| 9 | Log in as `customer_a`, open **Vendors** | The **+ Add Vendor** button is **still shown** (customers can add here), and you see **only your own institution's** vendors — there is no "all institutions" list |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: dashboard.cash-stats
title: Cash Stats
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Cash Stats** page (`dashboard.bcos.dev`). Click through in the UI and mark each row Pass or Fail. The page is **read-only** — there is nothing to create, edit, or delete, so testing is about what you can **see** and **filter**.
## Set up
Log in at **dashboard.bcos.dev** and open **Cash Stats** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Cash Stats** | Page loads with a table (**ATM** / **Cassettes** columns) and four cards at the top: **Empty**, **Low**, **OK**, **No Data** |
| 2 | Look at any ATM row with cassette data | The Cassettes cell shows coloured pills, each with `[position]`, `$denomination`, a `(count)`, and a `$total` — red = empty, amber = low, green = OK |
| 3 | Check the row order | Rows needing attention sort to the top: **Empty** ATMs first, then **Low**, with No-Data / config-only rows at the bottom |
| 4 | Click the **Empty** card | The list filters to only ATMs with an empty cassette (or shows "No ATMs match the current filter" if none); the card looks selected |
| 5 | Click the **Empty** card again (or the **Low**/**OK**/**No Data** cards) | Clicking the active card clears the filter and shows all ATMs again; other cards switch the filter to that status |
| 6 | Click the **↻ Refresh** button | The button spins briefly and the list reloads — no error banner appears |
| 7 | Look for any server device (e.g. `C1-SRV-001`) in the list | Servers are **not** listed — Cash Stats shows ATMs/TCRs only, never SVR/SRV devices |
| 8 | Find an ATM that hasn't reported cash | Its row reads **"No inventory reported"** (or pills say **(no data)** for config-only cassettes) — this is expected, not an error |
| 9 | Log in as `customer_a`, open **Cash Stats** | You see **only C1** ATMs — no C2 or C3 rows; the card counts reflect just C1 |
| 10 | Log in as `msp_a`, open **Cash Stats** | You see **C1 and C2** ATMs but **not C3** |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: dashboard.overview
title: Fleet Overview
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Fleet Overview** landing page (`dashboard.bcos.dev`). Click through in the UI and mark each row Pass or Fail. This screen is **read-only** — there is nothing to create, edit, or delete, so testing focuses on what each card shows and on role scoping.
## Set up
Log in at **dashboard.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Fleet numbers come from the simulator devices: **C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open the dashboard | Header reads **Fleet Overview** and four KPI cards show numbers (not blank): **Total ATMs**, **Connected**, **Open Incidents**, **Active Tasks** |
| 2 | Read the **Total ATMs** and **Connected** cards | **Connected** is ≤ **Total ATMs**, and the "% of fleet" line under Connected matches (e.g. 6 of 12 → 50%) |
| 3 | Look at the **Fleet Health** card | Three bars — **Connected / Disconnected / Never Connected** — each with a count, and a **By Model** list showing your top ATM models |
| 4 | Look at the **Fleet Operations** card | Shows task counts **Total / Pending / Running / Completed / Failed**, plus **Artifacts**, **Modules Reporting**, and an **"N incidents this week"** line (Completed, Failed, and Modules Reporting may read **0** — that's expected, do not fail on it) |
| 5 | Look at the **Recent Incidents** card | Either a table with **ATM / Type / Severity / Opened** rows (Severity shown as a colored badge) **or** the message **"No open incidents"** — no blank card or error |
| 6 | Watch the **Auto-refresh** toggle in the header | Label counts down each second (e.g. `Auto-refresh (59s)`); clicking the **↻ refresh** button reloads the numbers and the countdown resets |
| 7 | Turn the **Auto-refresh** toggle **off**, then reload the page | Toggle stays **off** after reload (setting is remembered) and the countdown no longer ticks |
| 8 | Log in as `customer_a`, open the dashboard | Recent Incidents card has **no "View all →" link**, and the fleet numbers reflect **only C1** devices |
| 9 | Compare `msp_a` (C1 + C2) with `bcos_a` (all institutions) | `bcos_a`'s **Total ATMs** is **higher** than `msp_a`'s, because it includes C3 devices too |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: devices.agent-profile
title: Agent Profile
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Agent Profile** (Devices Settings Agent Profile, `devices.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **devices.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can add/edit/delete |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 · can add/edit/delete |
| `customer_a@customer1.bcos.dev` | Customer | C1 · read-only |
> Agent Profiles are **fleet-wide** — they are hardware groupings (e.g. `hyosung`), not per-institution, so every login sees the **same** list. Test devices are the simulators (**C1-ATM-001…**, etc.).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Devices Settings Agent Profile** | Table loads with columns **Key / Label / Description / Modules / Status** and a profile count top-left |
| 2 | Click **+ Add Profile**, set Key `qatest`, Label `QA Test`, then **Add Profile** | Modal closes, green **"Profile added"** shows, and a new `qatest` row appears with an **Active** badge |
| 3 | Click **+ Add Profile**, leave **Label** blank, click **Add Profile** | Red **"Label is required"** inside the modal — modal stays open, nothing is added |
| 4 | Click **+ Add Profile**, enter Key `qatest` again (already exists), submit | A red error appears (key already exists) — **no** duplicate row is created |
| 5 | Click **Edit** on the `qatest` row, change the **Label**, save | **Profile Key** field is greyed/disabled (can't change), green **"Profile updated"**, row shows the new label |
| 6 | Click the **"N modules"** count on any row | The row expands a bulleted list of module names, a **★** marks exclusive ones, and the chevron flips ▼→▲ |
| 7 | Type part of a key or label in **Search profiles…** | List filters live and the count reads **"X of Y profiles"**; clicking the **✕** clears it and shows all again |
| 8 | Click **Delete** on `qatest`, confirm in the dialog | **"Profile deleted"** and the row disappears (deleting a profile still assigned to ATMs instead shows an error and keeps the row — that's expected) |
| 9 | Log in as `customer_a`, open the same screen and try **+ Add Profile → Add Profile** | Either the screen isn't available to you, or the save is **refused with an error** — no new profile is created (customers can't change profiles) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: devices.agent-scripts
title: Agent Scripts
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Agent Scripts** (`devices.bcos.dev` → **Settings → Agent Scripts**). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **devices.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 · read-only |
Test devices are the simulators: **C1-ATM-001…** (connected ATMs) and **C1-TCR-001…** (TCR machines, which are excluded from pushes).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Settings → Agent Scripts** | Page loads with a **+ Add Script** button and a table headed **Name / Description / Updated** |
| 2 | Click **+ Add Script**, name it `qa-cleanup.cmd`, add a description + some content, click **Add Script** | Panel slides closed, green "created" toast appears, and the row shows a blue **CMD** tag next to the name |
| 3 | **+ Add Script** again, name it `qa-check.txt`, add content, click **Add Script** | Inline error **"Name must end with .cmd, .sh, or .ps1"** — nothing is saved |
| 4 | Add a script but leave the **Script Content** editor empty, click **Add Script** | Inline error **"Script content is required."** — nothing is saved |
| 5 | Add `qa-tidy.ps1` and `qa-run.sh` | The `.ps1` row shows a purple **PS1** tag and the `.sh` row a green **SH** tag |
| 6 | Click **Edit** on `qa-cleanup.cmd` | The **Script Name** field is greyed out / can't be changed; description + content are editable, and **Save Changes** shows an "updated" toast |
| 7 | Click **Push** next to `qa-cleanup.cmd` | Modal opens showing a count of **connected ATMs**, a note that **TCR machines are excluded**, and a **Push to [n] ATMs** button; clicking it shows a green "pushed to n ATMs" toast |
| 8 | Click **Delete** on `qa-check`/a test script, confirm in the dialog | Confirm dialog appears; after confirming, the row disappears from the table with a "deleted" toast |
| 9 | Log in as `customer_a` and try to reach **Settings → Agent Scripts** | You **cannot manage scripts** — the page is unavailable / the list fails to load / there is **no + Add Script button** (customers have no access) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: devices.config-audit
title: Config Audit
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Config Audit** in the Devices app (`devices.bcos.dev` → **Settings → Config Audit**, header reads **Config Change Audit**). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **devices.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can save agent properties |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Config Audit tracks saves to **institution agent properties**, so the "data" here is the institutions **C1BD / C2BD / C3BD** (not individual devices). Rows only appear after someone saves agent properties, so a couple of tests below have you make a save first.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Settings → Config Audit** | Page loads with heading **Config Change Audit** and a table with columns **Institution · Changed By · When · Changes** |
| 2 | As `bcos_a`, open **Settings → Agent Properties**, change one field for **C1BD**, **Save**, then return to **Config Audit** and click **Refresh** | A new row appears at the **top** for **C1BD**, **Changed By** shows your name, **When** is now, and **Changes** shows a **X fields changed** badge |
| 3 | Click **View diff** on that row | Row expands into a **Field / Before / After** table; the field you edited shows the old value under **Before** and the new one under **After**. Clicking **Hide** collapses it |
| 4 | Find the very first entry for an institution (or save props for an institution that has none yet) | Its **Changes** column shows an **Initial save** badge, and in the diff every **Before** value is a dash (`—`) |
| 5 | As `bcos_a`, use the **institution dropdown** (top right) → pick **C2BD**, then pick **All institutions** | Selecting **C2BD** shows only C2 rows; **All institutions** brings every institution's rows back |
| 6 | As `bcos_a`, click **Refresh** | Button briefly reads **Loading…** then the list reloads with no error banner |
| 7 | Log in as `msp_a`, open **Config Audit** | You see history rows but **only for C1/C2** — **no C3BD** rows appear, even if you change the dropdown (scoped users are pinned to their own institution) |
| 8 | Log in as `customer_a`, open **Config Audit** | You can **view** the log for **C1 only** (no C2/C3), and you cannot create a new row (no Save/Agent Properties edit available) — read-only |
| 9 | Open an institution with no saves yet (e.g. filter to one with no history) | The table area shows **"No config changes recorded yet."** — no error or crash |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: devices.device-detail
title: Device Detail
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Device Detail** page (`devices.bcos.dev`). Open a device, click through the tabs and actions, and mark each row Pass or Fail.
## Set up
Log in at **devices.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can edit everything |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only · can edit |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open a device with the selector at the top, pick `C1-ATM-001` | Page loads; header shows the ATM ID plus a live **Status** and **Agent Connection** badge |
| 2 | Type part of a device ID/location into the selector's search box | The list narrows to matching devices; picking one switches the page to it |
| 3 | Click through the tabs (Details, System Info, Agent, Software, Hardware, Cassettes, Incidents, Activity, Task History…) | Each tab shows its content or a clear empty message — **no blank page or crash** |
| 4 | On **Details**, click **Edit**, change the terminal comment or location, click **Save** | Form closes and the new value is shown; it survives a page reload |
| 5 | Click **Rename**, change the display name, confirm | The header/ID updates to the new name |
| 6 | Click **Move Institution**, move `C1-ATM-001` to **C2**, confirm | Device now shows institution C2 (and disappears from a C1-only filter) |
| 7 | Click **Reset to In Service** on a device in supervisor/out-of-service state | Status badge changes to **IN SERVICE** |
| 8 | Click **Deactivate** on an active device | Device becomes **INACTIVE** and the button now reads **Delete permanently** (first click deactivates, not deletes) |
| 9 | Log in as `customer_a`, open a C1 device, try **Edit → Save** | The change is **rejected** (error / nothing saves) — customers are read-only |
| 10 | Still as `customer_a`, open the device selector | You see **only C1** devices — no C2 or C3 |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: devices.device-groups
title: Device Groups
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Device Groups** (`devices.bcos.dev` → **Device Groups**). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **devices.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can create/edit/delete |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only · can create/edit/delete |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Device Groups** | Table loads with columns **Name / Description / Institution / ATMs / Default / Actions** and a **+ New Group** button in the toolbar |
| 2 | Click **+ New Group**, type name `QA Test Group`, pick a **Color** swatch, in the ATMs picker highlight `C1-ATM-001` and click **** to move it to **Assigned**, click **Create Group** | Panel slides in from the right; after save a green **"Group … created"** message shows and a new row appears with **ATMs = 1** and the color strip on its left |
| 3 | Click **+ New Group** again, and in the **Institution** dropdown pick `C1BD` | The **Assigned** panel auto-fills with all of C1's devices (no need to move them by hand) |
| 4 | On the `QA Test Group` row click **Edit**, change the **Description**, click **Save Changes** | Panel opens pre-filled with the group's current values; after save the row shows the new description |
| 5 | On that row click **Assign Devices**, move a different device into **Assigned**, click **Save Assignment** | The **ATMs** count updates to exactly the set now in **Assigned** — note this **replaces** membership, it does not add to it |
| 6 | On that row click **Assign Profile**, pick a hardware profile, click **Assign Profile** | A modal opens; after save it shows **"Profile … assigned to N devices — M CONFIG_UPDATE task(s) queued"** |
| 7 | Click **Set Default** on a group, then **✕ Clear** on it | Set Default turns into a **"Default"** badge + **Clear** button; Clear returns it to **Set Default** |
| 8 | On `QA Test Group` click **Delete** and confirm the popup | Popup warns **"ATMs will not be deleted"**; after confirm the row disappears and the devices still exist in the main device list |
| 9 | Log in as `customer_a` and open **Device Groups** | You see **only C1** groups and only C1 devices in any picker — **no C2 or C3** |
| 10 | Log in as `bcos_a`, then `msp_a`, and compare the group + device lists | `bcos_a` sees groups/devices for **all** institutions; `msp_a` sees **C1 and C2** but **not C3** |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: devices.device-list
title: Device List
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Device List** (`devices.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **devices.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open the **Device List** | Table of devices loads with a **Total** count above it; each row shows ATM ID, Location, Institution, Status and an **Agent** dot/version |
| 2 | Type `C1-ATM` in the **Search** box (left Filters sidebar) | List narrows to only matching devices as you type; clearing the box brings them all back |
| 3 | Open **Filters** → set **Device Type** to **TCR** | Only **TCR** rows remain (e.g. `C1-TCR-001`); switch back to **All Types** to reset |
| 4 | Open **Filters** → **Agent Status** → pick **Connected** | A blue filter tag appears above the table and only devices with a **green** agent dot show; click the tag's **×** (or **Clear all**) to remove it |
| 5 | Click the **ATM ID** column header, then click it again | Rows re-sort ascending, then descending (arrow flips) |
| 6 | Click the **⚙ Columns** button and tick **Address** | An **Address** column appears in the table; untick it and it disappears |
| 7 | Click any device row | A detail panel slides in from the right with **Properties / Modules / 🎮 Command Center** tabs; the **✕** closes it |
| 8 | As `bcos_a` (or `msp_a`), click **+ Add Device**, fill ATM ID / Location / Model / Address, click **📍 Lookup Coords**, then **Create Device** | Lookup fills Latitude/Longitude, the panel closes, and the new device shows up in the list |
| 9 | Log in as `customer_a` and open the Device List | You see **only C1** devices — no C2 or C3 rows; then log in as `msp_a` and confirm you see **C1 and C2 but not C3** |
| 10 | As `customer_a`, open **+ Add Device**, fill it in and click **Create Device** | Create is **rejected** — an error message shows in the panel and **no** new device is added (customer is read-only) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: devices.map
title: Map
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Fleet Map** (`devices.bcos.dev` → **Map**). It's a read-only view — no create/edit/delete. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **devices.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Map** | Map loads with coloured pins, a legend (Online / Offline / Out of Cash / Supervisor), and a count like **"N of M ATMs shown"** |
| 2 | Set **Status** → **Online** | Map shows only green pins and the count drops; a **Filters:** tag bar appears with an **Online** tag |
| 3 | Open the **Group** dropdown and pick a group | Map narrows to that group's ATMs and the count updates; a **Group** tag shows in the Filters bar |
| 4 | Click **Clear all** in the Filters bar | All tags disappear and every pin returns (count back to the full total) |
| 5 | Set a filter, click **💾 Save preset**, name it, **Save** — then Clear all and click the preset chip under **Saved:** | Clicking the chip re-applies exactly those filters; its **×** deletes the chip |
| 6 | Click a pin, then in its popup click the blue **ATM ID** | Popup lists ATM ID, location, address, status and agent connection; clicking the ID opens that ATM's detail |
| 7 | Find a pin with a **count badge** (number) and open it | Popup header reads **"N ATMs at this location"** and lists each ATM stacked |
| 8 | Toggle **Auto-refresh** off, then on | Off = countdown timer stops; On = a live "(Ns)" countdown resumes next to the toggle |
| 9 | Log in as `customer_a`, open **Map** | You see **only C1** pins — no C2 or C3 ATMs anywhere on the map |
| 10 | As `msp_a`, open **Map** | You see **C1 and C2** pins but **not C3** |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,35 @@
---
module: devices.sw-deploy
title: Software Deployment
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **SW Deploy** tab (`devices.bcos.dev` → open a device → **SW Deploy** tab). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **devices.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
To reach the tab: open a device from the list, then click the **SW Deploy** tab in its detail panel. Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open `C1-ATM-001` → **SW Deploy** tab | Two step cards show — **1 Software Download** and **2 Software Install** with an arrow between — plus a **Software History** section below |
| 2 | Open a device that has never had a software update | Step 1 shows a **NO TASKS** badge with "No software download tasks for this device", Step 2 shows **NOT RUN**, and History reads "No software tasks found for this device" — no error |
| 3 | Open a device that does have software history | The History table lists rows with a **Type** badge (Download / Install), a colored **Status** badge, and filled **Date** / **Duration** columns |
| 4 | Compare the two step cards to the newest History rows | Step 1's badge matches the newest **Download** row's status and Step 2's badge matches the newest **Install** row's status |
| 5 | If a **Schedule Install** button appears on Step 2, click it | A **Schedule Software Install — <device>** dialog opens with an optional "Schedule for" date/time field and **Cancel** / **Create Install Task** buttons *(the button only appears briefly right after a successful download — if it's absent, that's expected, skip this row)* |
| 6 | In that dialog click **Cancel** (or the ✕) | The dialog closes and nothing new is added to the History table |
| 7 | Log in as `customer_a`, open a C1 device → **SW Deploy** tab | You can **view** the step cards and History, but there is **no Schedule Install button** (read-only) |
| 8 | Check the device list scoping: `customer_a` then `msp_a` | `customer_a` sees **only C1** devices; `msp_a` sees **C1 and C2** but **not C3** |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: fleet.dashboard
title: Fleet Dashboard
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Fleet Stats** dashboard (`fleet.bcos.dev`). It is a read-only screen — no create/edit/delete. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **fleet.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Fleet Stats** | Header reads **Fleet Stats**; a **Task Statistics** bar (Total · Pending · Running · Completed · Failed) and a **Fleet Overview** bar (Artifacts · Modules Reporting) both show |
| 2 | Click **ATMs by Model** to expand it | Table opens with columns **Model / Total / Operational / Offline**, and the heading shows a count like "**N models · M ATMs**" |
| 3 | Click **ATMs by Institution** to expand it | Table opens with a row per institution — as `bcos_a` you see **C1BD, C2BD and C3BD** |
| 4 | Check the numbers in each row | Per row, **Operational + Offline** never exceeds **Total**; Offline shows a number (or "—" when zero) |
| 5 | Look at the **Completed** and **Failed** task counters | They read **0** — this is expected/known behaviour, **do not fail this** even though tasks have completed |
| 6 | Look at **Modules Reporting** | It reads **0** — expected/known behaviour, **do not fail this** |
| 7 | Log in as `msp_a`, expand **ATMs by Institution** | You see **only C1BD and C2BD** — **no C3BD** row |
| 8 | Log in as `customer_a`, open the dashboard | You see **only C1BD** items, and the screen is **view-only** — no Add / Create / Edit / Refresh buttons anywhere |
| 9 | Leave the page open ~1 minute (don't reload) | The **task counters** refresh on their own; the **ATMs by Model / Institution** tables stay put until you reload — this is expected, not a bug |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,35 @@
---
module: fleet.modules
title: Modules
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Agent Modules** screen (`fleet.bcos.dev`). This screen is a read-only reference catalog — there is nothing to create, edit, or delete. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **fleet.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
The module catalog is the same fixed list for everyone — it is **not** filtered by institution or device, so you won't need specific simulators (C1-ATM-001…) here.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open the **Modules** screen from the Fleet menu | Page loads with the heading **Agent Modules** and a short description line under it |
| 2 | Scan the section headings | You see **four** category sections in order: **Data Collection**, **Monitoring**, **Fleet Management**, **Updates** — each with an icon |
| 3 | Count the module cards across all sections | There are **16** cards total (Data Collection 7, Monitoring 3, Fleet Management 4, Updates 2) |
| 4 | Look at any single card (e.g. **Journal Events**) | It shows a bold display name, a small grey code chip beneath it (e.g. `journal-events`), and a plain-language description sentence |
| 5 | Check the status counts on the cards | Cards render cleanly **with no running / disabled / failed badges** — this is expected right now, so **empty badges are a Pass, not a fail** |
| 6 | Look for any action controls on the screen | There is **no Add / Create / Edit / Delete button anywhere** — the screen is view-only |
| 7 | Log in as `customer_a`, open the **Modules** screen | You see the **same 16 modules** in the same 4 categories, still with **no Add button** (read-only catalog, not scoped to C1) |
| 8 | Log in as `bcos_a`, open the **Modules** screen | The same full catalog loads with no error — the list does not change by role |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: incident.dashboard
title: Dashboard
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Dashboard** (the **Overview** landing screen in the Incident app). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **incident.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Fleet data comes from the simulators: **C1-ATM-001…**, **C1-TCR-001…**, **C1-SRV-001…** (and C2-/C3- for the other institutions). The Dashboard is **view-only** — there is nothing to create, edit, or delete here.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open the app — it lands on **Overview** | Page shows **Device Status** cards, **Tickets** cards, and the **Incident Trends** + **Incidents by Type** panels — no error banner |
| 2 | Look at the **Device Status** cards (Total Devices, In Service, Out of Service) | Numbers are filled in; **Total Devices** shows an **ATM · TCR** split, and In Service shows a **%** |
| 3 | Look at the **Tickets** cards (Open / Assigned / In Progress / Critical / This Week) | Each card shows a number (may be 0) — none are blank or show `undefined`/`NaN` |
| 4 | Watch the **Auto-refresh** toggle in the header | The label counts down in seconds (e.g. `Auto-refresh (28s)`) and reaches 0, then restarts |
| 5 | Turn the **Auto-refresh** toggle **off** | The countdown stops and the label just reads **Auto-refresh** (no seconds) |
| 6 | Click the **↻** refresh button (top-right) | Numbers reload; the button briefly shows the spinner (⟳) then returns — no error |
| 7 | On **Incident Trends**, change the dropdown to **Last 30 days**, then **Last 60 days** | The bar chart redraws to show more bars each time; do the same on **Incidents by Type** and its list updates |
| 8 | Read the **Agent Connection** panel (Connected / Disconnected / Never) | Counts add up to the fleet total and the colored bar underneath reflects the mix |
| 9 | Log in as `customer_a` and open the Dashboard | You see **only C1** devices/tickets (no C2 or C3 numbers) and there is **no Add / Create / Edit button** anywhere on the screen |
| 10 | Log in as `msp_a` and compare the totals to `bcos_a` | `msp_a` totals cover **C1 + C2** but **not C3** — the numbers are smaller than the admin's fleet-wide totals |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: incident.incident-management
title: Incident Management
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Incident Management** (`incident.bcos.dev` → **Incident Mgmt Incident List**). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **incident.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can work incidents |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only · can work incidents |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Incidents are auto-raised from the simulator devices — **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions). If the list is empty, open the **Filters** sidebar and clear the status filter first.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Incident Mgmt Incident List** | Grid loads with **Active** / **Parked** tabs, a **Filters** sidebar, and a table of incidents |
| 2 | Open **Filters**, tick a **Severity** (e.g. Critical) or type into **Incident Text** | List narrows to only matching rows; clearing the filter brings the others back |
| 3 | Set a filter combo, type a name and click **💾 Save preset**, change filters, then reload the preset | The saved filters are re-applied exactly |
| 4 | Click any incident row | A detail panel opens showing the **Event Timeline**, **Assign** dropdowns, and workflow buttons |
| 5 | In the panel, pick a **Technician**, then click **Start** / **Resolve** | The row's **Status** updates (e.g. Assigned → In Progress) without a page reload |
| 6 | Open an active incident and click **Park** | It leaves the **Active** tab and appears under **Parked**; **Unpark** there returns it to Active |
| 7 | Tick checkboxes on **2 incidents from different devices**, click **🔗 Link** | It is blocked with a message like *"must belong to the same device"* — no crash |
| 8 | Tick 2 incidents, click **Close** (the `Close N` bulk button) | They leave the active list (moved to Closed) |
| 9 | As `msp_a` scan the ATM column; then log in as `bcos_a` and compare | `msp_a` sees only **C1 and C2** devices (no C3); `bcos_a` sees **C1, C2 and C3** |
| 10 | Log in as `customer_a` and look at the left sidebar | There is **no Incident Mgmt menu** — read-only customers cannot open this list |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: incident.incident-tracker
title: Incident Tracker
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Incident Tracker** board (`incident.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **incident.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Incident Tracker** | Board loads with the **Open** chip, a **Recently Closed** chip, and the stage legend **Open → Assigned → In Progress → Resolved → Closed** |
| 2 | Look at any row that needs attention | Row shows the **ATM ID + location**, one or more incident badges (e.g. `#1042`), a filled **pipeline**, an **⚠ Action Required** badge, a coloured **severity** chip, and an **N open** count |
| 3 | Check the ordering of the rows | Rows needing action come **first**, most urgent (Critical, then High, Medium, Low) at the top |
| 4 | Click the **Recently Closed** chip in the toolbar | Resolved/closed ATMs also appear (amber **✓ Recently Closed** badge + a "Xh Ym ago" time); click it again and they **hide** |
| 5 | Click the refresh button (**↻**) top-right | Board reloads and the **Updated HH:MM:SS** time in the header changes — no error |
| 6 | On any row, click **View Incidents** | You jump to the full incident list **filtered to that same ATM** |
| 7 | Log in as `customer_a`, open **Incident Tracker** | Board is **view-only** — there is **no create/add button**; you can only view rows and drill in |
| 8 | Still as `customer_a`, read the ATM IDs on the board | You see **only C1** machines — no C2 or C3 rows anywhere |
| 9 | Log in as `msp_a` and read the ATM IDs | You see **C1 and C2** machines but **not C3** |
| 10 | Find (or create in another view) a state where nothing is open, then open the tracker | Board shows **"All ATMs clear — no open incidents"** with a check icon — no error/crash |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: incident.journal-events
title: Journal Events
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Event Journal** screen (the incident app on **bcos.dev**). This is a read-only, per-ATM event viewer — there is nothing to create, edit, or delete. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **bcos.dev** and open **Event Journal** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Event Journal** before picking anything | Filters panel shows on the left (ATM search, Category, Period) and the table area reads **"Select an ATM to view events"** — no data yet |
| 2 | In the **ATM** search box type `C1-ATM-001`, then click that terminal in the list | Events load newest-first; the count above the table shows a number (e.g. "42 events") and the heading shows the ATM name |
| 3 | Click the **Time** column header | The list re-sorts (oldest-first ↔ newest-first) and the arrow flips |
| 4 | Open **Category**, tick **Cassette** only | Only cassette-type rows remain, a **Cassette** tag appears in the Filters bar, and the count updates |
| 5 | Change **Period** to **Last 7 days** | More (or equal) events load; a **Period: 7d** tag appears. Default is Last 24 hours |
| 6 | Click **Clear all** in the Filters bar | ATM, Category and Period all reset — screen returns to "Select an ATM to view events" |
| 7 | Pick an ATM again, then click a row that shows a **▶** arrow | The row expands into a details panel with the full text and any hardware readings (card reader slot/status or cassette type/fill %/bill count) |
| 8 | As `customer_a`, open **Event Journal** and scroll the ATM list | Only **C1** terminals appear (C1-ATM/C1-TCR…) — no C2 or C3 devices |
| 9 | As `msp_a`, scroll the ATM list | **C1 and C2** terminals appear but **not C3** |
| 10 | Anywhere on this screen, look for a way to add or edit an event | There is **no Add / Create / Edit button** — the screen is view-only for everyone |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: incident.processing-rules
title: Processing Rules
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Processing Rules** (the incident app, `incident.bcos.dev`). Open the **Processing Rules** menu in the left sidebar and click through in the UI. Mark each row Pass or Fail.
## Set up
Log in at **incident.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Rules apply to **event types** (e.g. `CARD_READER_FAIL`, `CASSETTE_LOW`, `TCR_SENSOR_FAULT`) from the simulator devices **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Processing Rules** in the sidebar | The menu expands to **Opening Rules / Closing Rules / Event Exceptions**, and Opening Rules loads a table of rules |
| 2 | Log in as `customer_a` and look at the sidebar | There is **no Processing Rules menu at all** — customers can't see this screen |
| 3 | As `msp_a` on **Opening Rules**, click **+ Add Rule**, enter a name, pick an **Event Type**, action **Create Incident**, **Save** | Panel slides in from the right; after Save a green **"Rule created"** message shows and the new rule appears in the table |
| 4 | In that Add Rule panel, open the **Institution** dropdown | As `msp_a` only **C1 and C2** are listed (plus Global) — no C3. Repeat as `bcos_a`: **all of C1, C2, C3** appear |
| 5 | On a rule row, click the **Enabled** toggle | It flips to **Disabled**; switch the **Enabled / Disabled** sub-tabs and the rule now shows under **Disabled**, not Enabled |
| 6 | Click **Edit** on a rule, change the name, **Save Changes**, then click **History** | The new name shows in the table, and the History modal lists change entries (Created / Updated) |
| 7 | In the left filter sidebar, type a word in **Search** or pick an **Action** (e.g. Suppress) | The list narrows to matching rules, the count updates, and a filter tag / highlighted filter bar appears |
| 8 | Click **✦ Suggest a Rule**, paste a sample log line and/or a description, click **Get Suggestion** | A suggested rule with a **confidence %** and reasoning appears, offering **Publish Directly / Save as Draft / Edit First**. (If the status shows **Unavailable**, Adoons is down — not a rule bug) |
| 9 | Open the **Event Exceptions** tab | Unrecognised event types are listed grouped by type with counts, each with a **Dismiss all** button — no error/crash |
| 10 | Click **Delete** on a rule, then confirm | A confirm dialog appears; after confirming the rule disappears from the table |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: msp.contact-groups
title: Contact Groups
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Contact Groups** (MSP app → **Contact Groups**). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **msp.bcos.dev**, open **Contact Groups** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Can do |
|-------|------|--------|
| `bcos_a@bcos.dev` | Admin | Full — create/edit/delete/notify |
| `msp_a@msp1.bcos.dev` | MSP admin | Full — create/edit/delete/notify |
| `customer_a@customer1.bcos.dev` | Customer | View only |
Members are picked from your existing HiveIQ **users** (the C1/C2/C3 test users), not from devices.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Contact Groups** | Table loads with columns **Group Name / Description / Members / Subscriptions / Created**, and toolbar buttons **Send Notification** and **+ New Group** |
| 2 | **+ New Group** → name `QA Managers` + a description → **Create Group** | Green "Group created" toast; the new group appears as a row in the table |
| 3 | **+ New Group** again with the same name `QA Managers` → **Create Group** | An error shows in the panel (name already exists); **no** duplicate row is added |
| 4 | Click the `QA Managers` row → in the panel click **Edit**, change the description → **Save** | "Group updated" toast; the new description shows in the panel and the table |
| 5 | In the panel, tick a **Notification Subscription** (e.g. *System Announcement*) | The checkbox fills blue and that type shows as a green tag in the group's **Subscriptions** column |
| 6 | In the panel → **Add Members**, search a user, tick them → **Add … Selected**, then **Remove** one | Member appears and the **Members** count goes up; after Remove it goes back down — no error |
| 7 | Toolbar **Send Notification** → pick a type, enter Subject + Message → **Send Notification** | "Sent to N recipient(s)" toast and the panel closes (N may be 0 if no group is subscribed — still a pass) |
| 8 | Open the **Filters** sidebar (▶), type part of a group name, then click a **Subscription** pill | The list narrows to matching groups; a filter chip appears and **Clear all** empties it again |
| 9 | Delete `QA Managers` via **Delete** → confirm in the modal | "Group deleted" toast; the row disappears from the table |
| 10 | Log in as `customer_a`, open **Contact Groups** | You can **view** the group list. ⚠️ Groups are shared, not institution-filtered — seeing C2/C3 groups here is expected, not a fail. Create/Delete should not succeed for a customer (error toast, nothing changes) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: msp.institution-keys
title: Institution Keys
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Institution Keys** in the MSP app (`msp.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **msp.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1BD, C2BD, C3BD) · can add/edit/delete |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only · can add/edit/delete |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
The keys map to the simulator institutions **C1BD / C2BD / C3BD** (whose devices are `C1-ATM-001…`, `C1-TCR-001…`, etc.).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Institution Keys** | Table loads with columns **Key / Institution Name / Device Types** and a row for each institution key |
| 2 | Type part of a key or name in the **Search** box (e.g. `C1`) | List narrows to matching rows; clearing the box brings them all back |
| 3 | Click **+ Add Mapping**, enter Key `TEST1`, an Institution Name, tick **ATM** + **TCR**, click **Add Mapping** | Panel closes, a success toast shows, and a new **TEST1** row appears in the table |
| 4 | Click **Edit** on the `TEST1` row | Panel opens with the **Key field greyed out / not editable**; you can still change the name and ATM/TCR checkboxes |
| 5 | Change the name or a device-type checkbox and click **Save Changes** | Toast confirms, and the row shows the updated name / device types |
| 6 | Click **Delete** on the `TEST1` row | A confirm pop-up naming **TEST1** appears; clicking **Delete** removes the row from the table |
| 7 | Turn the **Auto-refresh** toggle off then on, then click the **↻** refresh button | List reloads with no error and the `(60s)` countdown resets |
| 8 | Log in as `msp_a` and open Institution Keys | You see the **C1BD and C2BD** rows only — **no C3BD** |
| 9 | Log in as `customer_a` and open Institution Keys | You see **only C1BD**; if you try **+ Add Mapping** and save, an **error toast** shows and no new row is added (read-only) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: msp.institutions
title: Institutions
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the MSP **Institutions** screen (`msp.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **msp.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | **All** institutions (C1BD, C2BD, C3BD) |
| `msp_a@msp1.bcos.dev` | MSP admin | **C1BD + C2BD only** |
| `customer_a@customer1.bcos.dev` | Customer | Not an MSP admin — no access to this screen |
Data is the sim institutions **C1BD / C2BD / C3BD** (with their C1-/C2-/C3- simulator devices behind them).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Institutions** | Table loads with columns **Institution · Contact · License Key · Granted** and rows for C1BD, C2BD, C3BD |
| 2 | Open the **Filters** sidebar, type an institution name in **Search** | List narrows to matches; **✕ Clear all** brings every row back |
| 3 | On a row, click **Edit Contact**, change Name/Email/Phone, click **Save Changes** | A success toast appears, the panel closes, and the new contact shows in that row |
| 4 | Click **Edit Contact**, clear the **Name** field, click **Save Changes** | A **"Contact name is required"** error shows and nothing is saved |
| 5 | Click **Tokens**, enter a name (e.g. `C1-ATM-001`), click **+ Generate** | A green banner shows the **raw token once** with a **Copy** button, and the token appears in the list as **ACTIVE** |
| 6 | In the same Tokens panel, click **Revoke** on that token | Its status flips to **REVOKED** and a **Delete all revoked** button appears |
| 7 | On a row, click **Readiness** | A panel opens with a **Ready to onboard** / **Not ready** banner and grouped checks (Customer Profile, Licensing, Agent Connectivity) each marked ✓ or ✗ |
| 8 | Log in as `msp_a` and open **Institutions** | You see **only C1BD and C2BD** — **C3BD is not listed** |
| 9 | Log in as `customer_a` | The **MSP / Institutions screen is not available** to you (not in the menu / access denied) — no institution list |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: msp.module-allocations
title: Module Allocations
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Module Allocations** in the MSP admin SPA (`msp.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **msp.bcos.dev** and open **Module Allocations** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1BD + C2BD + C3BD) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1BD + C2BD only |
| `customer_a@customer1.bcos.dev` | Customer | No MSP access |
This screen lists **users** grouped by institution (C1BD / C2BD / C3BD) — it does not target devices. Use the seeded sim users under each institution.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Module Allocations** | Page loads with an **Available modules** legend at the top and users grouped under institution headings |
| 2 | Click an institution heading (e.g. **C1BD**) | The group expands/collapses; each user row shows **User**, **Status** (Active/Disabled), **Email**, **Current Modules** |
| 3 | In the **Filters** sidebar, type a name or email in **Search** | The list narrows to matching users, a filter chip appears, and the count pill updates |
| 4 | Set the **Institution** filter to **C2BD**, then click **✕ Clear all** | Only C2BD users show while filtered; Clear all resets back to every group |
| 5 | Click a user row | A slide-in panel opens on the right listing every module with a name, description and checkbox |
| 6 | Tick a module, click **Save Allocations** | A success toast appears, the panel closes, and that user's **Current Modules** now shows the new module icon |
| 7 | Reopen the same user, untick every module, **Save Allocations** | The row's **Current Modules** now reads **None** |
| 8 | Still as `msp_a`, look at the institution headings | You see **C1BD and C2BD** only — **no C3BD** |
| 9 | Log in as `bcos_a`, open the screen | **All** institutions appear, including **C3BD** |
| 10 | Log in as `customer_a` | The **Module Allocations** screen is **not available** (no MSP tile / access denied) — customers can't manage allocations |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: msp.users
title: Users
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Users** screen (`msp.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **msp.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · not an admin |
Users are grouped under institutions **C1BD / C2BD / C3BD**. Sample people live under each (e.g. the `customer_a` / `msp_a` accounts show up in the C1 group).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Users** | Page loads with users grouped under institution headers **C1** and **C2** — each group **collapsed** by default |
| 2 | Click an institution header (e.g. **C1**) | Group expands to a table with **Name · Email · Role · Status · Last Login** columns; click again to collapse |
| 3 | Open **Filters** (◀/▶ bar on the left), type a name/email in **Search** | List narrows to matching users; the count pill updates; **Clear all** resets it |
| 4 | In **Filters**, set **Role → MSP Admin** | Only MSP Admin users remain; a filter chip appears above the table; removing it restores the full list |
| 5 | Click **Edit** on a user, change **Role** and toggle **Fleet Task Approver**, click **Save Changes** | Slide-in panel closes, a green **User updated** toast shows, and the row reflects the new role. **Email field is read-only** in the panel |
| 6 | Click **Reset PW** on a user → **Send Reset Email** | Modal closes with a **Password reset — a reset email has been sent** toast (no password is shown on screen) |
| 7 | Click **Disable** on a user → confirm in the modal | Status badge flips to **Disabled**; the button now reads **Enable** and clicking it flips it back to **Active** |
| 8 | Find your own row (`msp_a`) | There is **no Disable/Enable button** on your own account (only Edit / Reset PW) |
| 9 | Log in as `bcos_a`, open **Users** | You see **all three** institution groups including **C3** — more than `msp_a` sees |
| 10 | Log in as `customer_a` | The Users admin screen is **not available** — either it isn't in the menu or it loads with **no users to manage** (no Edit/Reset/Disable actions), never a crash |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: profile.appearance
title: Appearance
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Appearance** panel in Profile (`profile.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **profile.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 · read-only elsewhere |
No simulator devices are needed — Appearance is a **per-user personal setting** (theme + table density), not tied to any institution or device.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Profile → Appearance** | Panel loads with a **Theme** row (Light / Dark / System) and a **Table density** row (Comfortable / Compact); **Save** is greyed out |
| 2 | Click the **🌙 Dark** theme card | The Dark card gets a highlighted border, an **Unsaved changes** badge appears top-right, and **Save** + **Discard** become active |
| 3 | Click **Save** | Screen switches to dark background, an **Appearance saved** toast shows, and the badge disappears |
| 4 | Reload the page (F5) | It comes back in **Dark** with the Dark card still selected — the choice persisted |
| 5 | Change the theme again, then click **Discard** | The selection snaps back to your last saved value and the **Unsaved changes** badge disappears (nothing saved) |
| 6 | Switch to **Compact** table density and **Save**, then reload | Compact stays selected after reload |
| 7 | Set theme to **💻 System**, Save, then flip your OS light/dark setting | The app follows the OS setting (System = follows the computer) |
| 8 | Log in as `customer_a`, open **Appearance**, pick a theme and **Save** | It saves normally with the **Appearance saved** toast — everyone can set their **own** appearance, even read-only customers |
| 9 | Still as `customer_a`, log out and back in | Your saved theme is still applied — preferences are remembered per user, not shared with other accounts |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: profile.display
title: Display
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Profile → Display** (`profile.bcos.dev`). These are personal, per-user preferences — click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **profile.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Display settings are **personal to each account** — there's no device or institution scoping here, so no simulator devices are needed. Each login edits only its own preferences.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Profile → Display** | Page loads with four fields — **Items per page**, **Date format**, **Time format**, **Timezone** — and the **Save** button is greyed out |
| 2 | Open the **Items per page** dropdown | Only **10, 25, 50, 100** are offered |
| 3 | Change any field (e.g. Items per page → 50) | An **Unsaved changes** badge appears, **Discard** shows, and **Save** becomes clickable |
| 4 | Click **Discard** | The field snaps back to its previous value, the badge disappears, and Save is greyed out again |
| 5 | Change **Date format**, tick a **Time format** radio, pick a **Timezone**, then click **Save** | A success toast **"Display settings saved"** appears and the Unsaved badge clears |
| 6 | Reload the page | Your saved choices are still selected (they persist across reload) |
| 7 | Click both **Time format** radios in turn | Only one is selected at a time — **12-hour (3:00 PM)** or **24-hour (15:00)**, never both |
| 8 | Log in as `customer_a`, open **Profile → Display** | The same editable form loads — customer can change and **Save** their own settings (this screen is **not** read-only) |
| 9 | As `customer_a`, look over the page | There is **no** device/institution picker and **no** "manage another user" option — only your own four preferences |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: profile.inbox
title: Inbox
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the Profile **Inbox** (on `bcos.dev`, open **Profile → Inbox**). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in on **bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can Broadcast |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 · can Broadcast |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · Direct messages only |
Recipients are other test users (e.g. `msp_a`, `customer_a`); institutions are **C1BD / C2BD / C3BD**.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `customer_a`, open **Profile → Inbox** | Page loads with **Inbox** and **Sent** tabs and a message list (or "No messages") |
| 2 | Look at any unread rows | Unread rows show a **blue dot** + **bold subject**; the **Inbox** tab shows a count badge and the toolbar reads e.g. "3 messages · 1 unread" |
| 3 | Click an unread message row | A **side panel** slides in from the right with the full message; on close the row is **no longer bold**, dot gone, and the unread count drops by one |
| 4 | Click **Mark all read** in the toolbar | Every row loses its bold/dot, the tab badge disappears, and the **Mark all read** button itself disappears |
| 5 | Click **+ Compose** → **Direct**, search a recipient and add them (chip appears), type a subject + message, click **Send** | Success toast appears, panel closes, and the message shows on the **Sent** tab with the recipient in the **To** column |
| 6 | Still as `customer_a`, open **+ Compose** | Only **Direct** is offered — there is **no Broadcast** button and **no Institution** dropdown |
| 7 | Log in as `bcos_a`, open **+ Compose** | Both **Direct** and **Broadcast** buttons show, plus an **Institution** dropdown listing C1BD / C2BD / C3BD |
| 8 | As `bcos_a`, choose **Broadcast**, pick an institution (or "All institutions"), write a message, **Send** | "Broadcast sent" toast appears and it shows on the **Sent** tab as type **Broadcast** ("All users") |
| 9 | On an inbox message, click **Delete** (row button or in the open panel) | The message disappears from the list and the message count drops by one |
| 10 | In the header, toggle **Auto-refresh** off | The label stops showing a countdown; toggle back on and the countdown resumes |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,35 @@
---
module: profile.notifications
title: Notifications
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Notifications** settings screen (`profile.bcos.dev` → **Profile → Notifications**). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **profile.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
No simulator devices are needed — this is a **personal, per-user settings page**. Each account only ever edits its own preferences.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `customer_a`, open **Profile → Notifications** | Page loads with three sections — **Channels**, **Alert severity**, **Quiet hours** — and **Save** is greyed out (nothing to save yet) |
| 2 | Toggle **Email notifications** off | An **Unsaved changes** badge appears at the top, a **Discard** button appears, and **Save** becomes clickable |
| 3 | Click **Discard** | The toggle jumps back to its saved state; the **Unsaved changes** badge and **Discard** button disappear and **Save** is greyed again |
| 4 | Toggle **Incident assignments** on, then click **Save** | A green **"Notification settings saved"** toast shows; badge disappears and **Save** greys out again |
| 5 | Reload the page (F5) | Your change stuck — **Incident assignments** is still on |
| 6 | Under **Quiet hours**, set **From** and **To** times, then **Save**, then reload | Toast confirms save and both times are still shown after the reload |
| 7 | Log in as `msp_a`, open **Notifications** | You see the **same self-service screen** editing your own prefs — there is **no institution filter** and no way to pick or edit another user's notifications |
| 8 | Log in as `bcos_a` (admin), open **Notifications** | Same screen as everyone else — **no extra admin controls** to edit other users' notification settings (admins only manage their own here) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: profile.profile
title: Profile
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Profile** tab (`profile.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **profile.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Profile shows |
|-------|------|---------------|
| `bcos_a@bcos.dev` | Admin | Role badge **Admin** |
| `msp_a@msp1.bcos.dev` | MSP admin | Role badge **MSP Admin** |
| `customer_a@customer1.bcos.dev` | Customer | Role badge **Customer** · Institution shown |
This tab edits **your own** account only — there are no devices to pick and nothing scoped by institution. Each login sees just their own profile.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `customer_a`, open the **Profile** tab | Page loads showing your **Email**, a **System role** badge, and **Full name / Job title / Phone** fields |
| 2 | Type into **Full name** | An **Unsaved changes** badge appears and a **Discard** button shows next to **Save changes** |
| 3 | Click **Save changes** | A **Profile saved** toast appears and the **Unsaved changes** badge disappears |
| 4 | Reload the page | Your saved name is still there |
| 5 | Edit **Job title**, then click **Discard** | The field reverts to the saved value and the **Unsaved changes** badge disappears |
| 6 | With no edits made, look at **Save changes** | The button is **disabled** until you actually change something |
| 7 | Click the round photo and pick an image under 2 MB → **Save changes** | The photo replaces your initials, crops to a square, and a **Remove** link appears |
| 8 | Click the photo and pick an image **larger than 2 MB** | An **Image too large** toast appears and the photo does **not** change |
| 9 | Look at the **Email**, **System role**, and **Institution** values | They are shown as plain read-only text with **no input box** — you can't edit them here |
| 10 | Log in as `bcos_a` and check the role badge | It reads **Admin** (each login shows its own correct role, not Customer) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: profile.security
title: Security
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Security** screen in the **Profile** app. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in to any HiveIQ app, then open **Profile → Security** (sidebar 🔒). Test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
This screen is **self-service** — it only ever touches *your own* account, so there's no device or institution list to check. Every role sees the exact same two cards.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `customer_a`, open **Profile → Security** | Screen shows two cards: **Change Password** and **Session Timeout** — no admin-only controls |
| 2 | In **Change Password**, leave one field empty | The **Change Password** button stays greyed out until both fields are filled |
| 3 | Type two **different** values in New / Confirm, click **Change Password** | Red message **"Passwords do not match."** appears and nothing is saved |
| 4 | Type a strong password (12+ chars, upper + lower + a number + a symbol) in **both** fields, click **Change Password** | Green **"Password changed"** toast; both fields clear |
| 5 | Type a short simple password like `abc12345` in both fields, click **Change Password** | A **red error toast** appears (real rule is 12+ chars with mixed case, a number and a symbol). This is **expected** — the placeholder says "Min. 8" but the stronger rule wins, so don't false-fail |
| 6 | Open **Session Timeout** without changing anything | The **Save** button is greyed out (nothing to save); **Discard** is not shown |
| 7 | Change the minutes value (e.g. to `30`), click **Save** | Green **"Session timeout saved"** toast; Save greys out again |
| 8 | Change the minutes value again, then click **Discard** | Value snaps back to the previously saved number and Save greys out — no toast |
| 9 | Log in as `bcos_a` (admin) and open the same screen | Identical two cards acting on the admin's **own** account — no extra admin-only password/reset controls here |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,38 @@
---
module: recon.atm-cycle-history
title: ATM Cycle History
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **ATM Cycle History** in the Reconciliation app (`recon.bcos.dev`). Open Reconciliation inside the HiveIQ Browser (**Cash Reconciliation** in the sidebar), click through in the UI, and mark each row Pass or Fail.
## Set up
Log in — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can sync/save |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only · can sync/save |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…** (and C2-/C3- for the other institutions). Pick a C1 ATM that shows cycle rows for the detail tests.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Cash Reconciliation** | Page loads with the five stat cards (**ATMs Tracked / Balanced / Variance / Open Cycles / Pending**) and a fleet table of ATMs |
| 2 | Click a `C1-ATM-001…` row | ATM detail opens — header **ATM C1-ATM-001**, a left **Cycle History** panel, and **← Fleet** + **+ Record Replenishment** buttons |
| 3 | Look at the Cycle History list | Rows show **# / Started / Ended / Status / Variance**; a still-running cycle shows **Open** under Ended; each row has a **Balanced** or **Variance** status badge |
| 4 | Click a cycle row | Right panel fills in with the cash breakdown — **Opening Balance** down to **Expected Closing**, **Actual Closing (Physical Count)**, and **Variance** |
| 5 | Open a cycle whose status is **Variance** | Its **Variance** amount is shown in red and the detail panel does **not** say Balanced ✓ (a Balanced cycle shows **Balanced ✓** and a blank/zero variance) |
| 6 | As `msp_a`, on an ATM with an **open** cycle, click **↻ Sync Journal** | Button shows **Syncing…**, then totals refresh with **no error banner**. On an ATM with no open cycle the button is **greyed out** |
| 7 | Click the **⚙** gear → **Cassette Configuration**, then **↓ Sync from Device**, then **Save Configuration** | Modal opens; slots populate (or a "configure manually" hint appears); Save closes the modal with **no error** |
| 8 | Log in as `customer_a`, open the same C1 ATM, open **⚙ Cassette Configuration** and click **Save Configuration** | Save is **rejected** — an error message shows and nothing is saved (customers are read-only) |
| 9 | As `customer_a`, look at the fleet table | You see **only C1** ATMs — no C2 or C3 |
| 10 | As `msp_a`, look at the fleet table | You see **C1 and C2** ATMs but **not C3** |
| 11 | Open an ATM that has **no** cycles yet | Left panel shows **"No cycles recorded yet."** and the right panel shows **"Select a cycle to view details"** — no error/crash |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: recon.cash-forecast
title: Cash Forecast
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Cash Forecast** (`recon.bcos.dev` → **Cash Forecast**). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **recon.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can Recompute |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only · can Recompute |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Rows are per-cassette forecasts for the enrolled simulator ATMs (**C1-ATM-001…**, **C1-TCR-001…**, and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Cash Forecast** | Table **Cassette Runout Forecast** loads with columns ATM · Slot · Denomination · Current Level · Burn Rate / Day · Projected Runout · Fill By · Status |
| 2 | Look at the default row order | Rows are sorted **soonest runout first** — the top rows show the nearest Projected Runout (e.g. "overdue" / "today" / "3d") |
| 3 | Open the **Filters** sidebar (the `»` toggle on the left), type an ATM into **Search ATM** (e.g. `C1-ATM-001`) | List narrows to just that ATM; the sidebar count pill updates (e.g. `4 / 60`) |
| 4 | Set **Institution** = `C2BD`, then set **Forecast Status** = `No Burn`, then click **✕ Clear all** | Each filter narrows the table live (only C2 rows, then only **No Burn** badges); Clear all restores the full list |
| 5 | Click the **Current Level** column header, then click it again | Table re-sorts by that column ascending, then descending (sort arrow flips) |
| 6 | Scan the rows for urgency colour | Cassettes due to run out within ~3 days show **amber**, and rows whose Fill By date has passed show **red** |
| 7 | Click **↻ Recompute** in the header | Button shows "Recomputing…", then an **Updated <time>** stamp appears and the table reloads with **no error banner** |
| 8 | Log in as `customer_a`, open **Cash Forecast** | You see **only C1** rows; the **Institution** filter dropdown lists **only C1BD** — no C2 or C3 |
| 9 | Still as `customer_a`, click **↻ Recompute** | A red **error banner** appears (recompute is admin-only) — the customer can view but not recompute; **no crash** |
| 10 | Log in as `bcos_a`, open the **Institution** filter | All institutions are listed (**C1BD, C2BD, C3BD**) and rows from every institution appear |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: recon.cash-reconciliation
title: Cash Reconciliation
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Cash Reconciliation** — the fleet grid "ATM Cash Positions" (`recon.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **recon.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (incl. un-enrolled ATMs) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open Cash Reconciliation | The **ATM Cash Positions** grid loads with columns **ATM ID · Last Replenishment · Projected Balance · Last Known Balance · Cycle Status · Variance · Last Sync** |
| 2 | Click **»** to expand the **Filters** panel, then type a C1 ATM ID in **Search** | The list narrows to matching ATMs and the counter (e.g. **1 / 12**) updates |
| 3 | Clear search, set **Status** = Balanced | Only rows with a green **Balanced** badge remain |
| 4 | Set **Journal Format** = Recycler (Format B) | Only recycler ATMs remain; switching back to **All Formats** restores the list |
| 5 | Click the **Variance** column header | Rows re-sort by variance; non-zero variances show in **red**, and clicking again flips the sort order |
| 6 | Click any ATM row (or **View →**) | That machine's reconciliation detail opens |
| 7 | Change the page-size control (10 / 25 / 50 / 100) and page through | Row count per page changes and the pager moves without error |
| 8 | With a filter active, click **✕ Clear all** | Every filter resets and the full in-scope list returns |
| 9 | Log in as `customer_a` and look at the grid | You see **only C1** ATMs — no C2 or C3 — and there are **no Add / Edit / Record-replenishment buttons** (read-only) |
| 10 | Log in as `bcos_a` and compare | You see **all institutions** (C1, C2, C3), including ATMs with no reconciliation yet — more rows than `msp_a` or `customer_a` |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: recon.device-cycle-mgmt
title: Device Cycle Management
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Device Cycle Mgmt** in Cash Reconciliation (`recon.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **recon.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can save |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only · can save |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Open the **Device Cycle Mgmt** screen in Recon. Devices are the simulator ATMs: **C1-ATM-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Device Cycle Mgmt** | Two lists show — **Available** (left) and **Selected for Recon** (right) — each with a count badge in its header |
| 2 | Type `C1-ATM` in the **Available** Filter box, then clear it | List narrows to only matching ATM IDs; clearing the box shows the full list again |
| 3 | Click an ATM in **Available**, then click the **&gt;** button | The ATM highlights blue on click, then moves to **Selected** and the Selected count goes up by one |
| 4 | **Double-click** an ATM in either list | It jumps to the other list instantly (one move, no page reload) |
| 5 | Click **&gt;&gt;** (move all) | Available empties and shows **"All ATMs are selected"**; Selected count equals the total |
| 6 | Click **&lt;&lt;** (remove all) | Selected empties and shows **"No ATMs selected — all will be shown"** |
| 7 | Select a few ATMs, click **Save Selection** | A green message appears: **"Saved. Cash Reconciliation will show N ATMs."** Reload the page — the same ATMs stay in Selected |
| 8 | Clear everything, click **Save Selection** | Message reads **"Selection cleared — showing all ATMs"** (empty is valid — not a failure) |
| 9 | Log in as `customer_a`, open the screen, click **Save Selection** | You can view and drag ATMs, but saving shows a red **"Save failed"** message — customers are read-only |
| 10 | As `customer_a` look at the lists; then as `msp_a` | `customer_a` sees **only C1** ATMs; `msp_a` sees **C1 and C2** but **not C3** |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: recon.recon-rules
title: Recon Rules
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Recon Rules** (`recon.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **recon.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | Full access to Recon Rules |
| `msp_a@msp1.bcos.dev` | MSP admin | Full access to Recon Rules |
| `customer_a@customer1.bcos.dev` | Customer | No access — this screen is admin-only |
This module isn't tied to institutions or devices — the rules apply fleet-wide, so no sim device list is needed here.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Recon Rules** | A table loads with columns **Format / Detection Sentinel / Slot Strategy / Deduplication / Pre-Block End** and a count like "N rules" above it |
| 2 | Look at the **Detection Sentinel** column | One row (the catch-all format) shows **fallback** instead of a sentinel value |
| 3 | Click any row | A panel slides in from the right showing that format's details plus a **Raw Configuration (YAML)** box below |
| 4 | In the panel, click **Edit** | The YAML box becomes an editable text box, and the buttons change to **Cancel / Save** |
| 5 | Make a small text change, then click **Cancel** | The panel goes back to view mode and your change is **not** kept |
| 6 | Click **Edit**, make a valid change, click **Save** | A success message appears and the YAML shown now includes your change |
| 7 | Click **Edit**, type something that isn't valid YAML (e.g. delete a colon), click **Save** | A red error banner appears explaining the problem, and you're still in edit mode with your text intact (nothing is lost) |
| 8 | Click **Reload** (not editing) | The YAML box refreshes and shows the last **saved** version |
| 9 | Log in as `customer_a` and try to open **Recon Rules** | You're blocked — no table or rule data appears, not just a missing Edit button |
| 10 | Log in as `bcos_a` and repeat step 1 | Same full view/edit access as `msp_a` — table loads and Edit/Save/Reload all work |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: reports.builder
title: Report Builder
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Report Builder** (`report.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **report.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Reports are **per-user** — each account sees only its own templates plus ones **Shared** with it. When you run a report, pick the simulator ATMs: **C1-ATM-001…** (and **C2-**/**C3-** for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Reports** | Page loads with tabs **Templates / Run History** and a **+ New Report** button |
| 2 | Click **+ New Report** → set a **Name**, **Data Source** = Incidents, **Format** = CSV, click a few **Columns**, then **Save** | Panel closes and the new report shows in the **My Reports** table |
| 3 | Open **+ New Report** again, fill the name but select **no columns** | **Save is blocked** — you can't save until at least one column (or Group By field) is picked |
| 4 | Edit a report and pick a **Group By** field | An **Aggregations** section appears (SUM/AVG/MIN/MAX) and the report row shows a **Grouped by …** badge |
| 5 | Click **▶ Run** on a report → choose **Custom**, set a date range, search and move **C1-ATM-001** into the selected list → **Run** | You land on **Run History** with a new run that moves **Pending → Running → Completed** |
| 6 | On a **Completed** run, click **Preview**, then **Download** | Preview opens a table of rows in-app; Download saves a CSV/JSON file |
| 7 | On a run, click **Delete** → **Confirm?** | The run disappears from Run History (no error/crash) |
| 8 | On one of your reports click **Share**, then log in as `bcos_a` and open **Reports** | The report appears under **Shared Reports** for `bcos_a` with a **▶ Run** button |
| 9 | As `customer_a`, click **▶ Run** on a report → **Custom** and open the ATM picker | Only **C1** devices are listed — no C2 or C3 ATMs |
| 10 | As `customer_a`, look at the **Templates** tab | You see **only your own** reports (and Shared ones) — not `msp_a`'s or `bcos_a`'s reports |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: reports.queries
title: Saved Queries
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Saved Queries** (`report.bcos.dev`). Saved Queries live on the **Templates** tab — each report row has a **Queries** button. Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **report.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Queries hang off a **report template**, so first make sure at least one report exists on the **Templates** tab (create one if the list is empty). The ATM picker lists the simulator devices: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, on **Templates** click the **Queries** button on a report row | A **Saved Queries** panel opens beneath that row (shows existing cards, or "No saved queries yet") |
| 2 | Click **+ New Query** → enter a **Name**, pick **Last 30 days**, leave ATMs empty → **Save** | A new query card appears reading **Last 30 days · All ATMs** |
| 3 | Click **Edit** on that card → switch Date Range to **Custom range**, set From/To, move one ATM to the assigned side → **Save** | Card updates to show the custom dates and **1 ATMs** |
| 4 | In **+ New Query**, open the ATM picker as `msp_a` | Only **C1-** and **C2-** devices are listed — no C3- devices |
| 5 | Log in as `customer_a`, open **Queries** → **+ New Query** → ATM picker | Only **C1-** devices are listed — no C2- or C3- |
| 6 | On a report that has its **schedule turned on**, click **Set Scheduled** on a query card | Card gets a **Scheduled** badge and the button changes to **Unschedule** |
| 7 | Open the Queries panel on a report with **no schedule** turned on | Query cards show only **Edit** / **Delete** — there is **no Set Scheduled** button |
| 8 | Click **▶ Run** on the report | Your saved query is listed as a pickable option alongside **Custom (one-off)** |
| 9 | On a query card click **Delete** → **Confirm?** | The card disappears; if it was the scheduled one, the **Scheduled** badge is gone from the panel |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: reports.runs
title: Run History
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Run History** (`report.bcos.dev` → **Run History** tab). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **report.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Run History is **per-user**: you only see runs **you** triggered. To create a run, use the **Templates** tab and click **▶ Run** on a report (an ATM Health report over `C1-ATM-001…` finishes quickly).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Run History** | Table loads with columns **Report · Status · Rows · Triggered By · Started · Completed · Actions** (or an empty-state message if you have no runs yet) |
| 2 | Go to **Templates**, click **▶ Run** on a report, submit, then return to **Run History** | A new row appears at the top with status **PENDING** or **RUNNING** |
| 3 | Leave **Auto-refresh** on (top right) and watch the row | Status advances on its own to **COMPLETED**, and the **Rows** column shows a number |
| 4 | On the **COMPLETED** row, click **Preview** | A modal opens showing report data; if there are many rows it says **"Showing first 50 of N rows"** |
| 5 | On the **COMPLETED** row, click **Download** | A file saves to your computer (`.csv` or `.json`) — no error banner appears |
| 6 | Toggle **Auto-refresh** off, then on (top right) | Off = the countdown stops; On = it resumes counting down |
| 7 | On any row click **Delete**, then **Confirm?** | The row disappears from the list; **Cancel** instead leaves it |
| 8 | Check the **Triggered By** column for the run you made | It shows **your login email** (a scheduled run would read **Scheduled**) |
| 9 | Trigger a run as `bcos_a`, then log in as `msp_a` and open **Run History** | `bcos_a`'s run is **not** listed — you only see runs you triggered yourself |
| 10 | Find or force a **FAILED** run and hover the **⚠ Failed** marker | A reason tooltip shows, and that row has **no Preview/Download** buttons |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: reports.schedule
title: Scheduling & Distribution
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Reports — scheduling & distribution** (`report.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **report.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Reports are **per-user** — everyone can build/schedule their own. Test devices are the simulators: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Reports** | Page loads with **Templates** and **Run History** tabs, plus **My Reports** and **Shared Reports** sections |
| 2 | **+ New Report** → give a **Name**, pick a **Data Source** (e.g. Incidents), tick a few **Columns**, **Save Report** | New report appears in **My Reports** with a **Manual** schedule |
| 3 | **Edit** that report → tick **Enable Schedule** → pick **Frequency: Weekly**, set a **Time** and **Day(s)** → **Save Report** | Row now shows a **schedule badge** and a **Next Run** time (the cron/summary preview updated as you changed fields) |
| 4 | On the report click **Queries** → **+ New Query** → name it, pick **Last 30 days**, leave ATMs empty → **Save Query**, then **Set Scheduled** | Query appears in the list and shows a **Scheduled** badge (Set Scheduled becomes **Unschedule**) |
| 5 | Click **▶ Run** on the report → choose the saved query (or **Custom (one-off)**) → **▶ Run Report** | You land on **Run History** and the new run appears, moving **Pending → Running → Completed** |
| 6 | On the completed run click **Preview**, then **Download** | Preview opens the data in-app; Download saves a CSV/JSON file |
| 7 | Back on Templates, click **Share** on the report | Button toggles and the row shows a **Shared** badge (click again to Unshare) |
| 8 | Log in as `customer_a`, open a query's **ATM** picker (New Query on any report) | ATM list shows **only C1** devices (C1-ATM-001…) — no C2 or C3 |
| 9 | As `msp_a`, open a query's **ATM** picker | ATM list shows **C1 and C2** devices but **not C3** |
| 10 | As `customer_a`, look at **My Reports** | You see **only your own** reports — `msp_a`'s reports are not listed unless they were shared to you |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: reports.templates
title: Report Templates
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Report Templates** (`report.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **report.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Reports are **owned per user** — everyone (including customers) can build their own. Use the simulator ATMs when a run asks you to pick devices: **C1-ATM-001…**, **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open the Reports page | Page loads with a **Templates** tab (sections **My Reports** + **Shared Reports**) and a **Run History** tab |
| 2 | Click **+ New Report** → give it a Name → pick Data Source **Incidents** → tick a few Columns → Save | Report appears in **My Reports** with its Data Source and **Manual** schedule |
| 3 | Try to Save a report with **no columns and no group-by** selected | Save is blocked — you can't save an empty report |
| 4 | On your report click **Queries** → **+ New Query** → pick a date range (e.g. Last 7 days) and a couple of ATMs (`C1-ATM-001`…) → save | Query is listed under **Saved Queries** with its range and ATM count |
| 5 | Click **▶ Run** → choose your saved query (or **Custom**) → submit | You land on **Run History** and the run shows **Pending → Running → Completed** |
| 6 | On the completed run click **Preview**, then **Download** | Preview shows the first rows in-app; Download saves a CSV/JSON file |
| 7 | Back on the report click **Share** | Row gets a **Shared** badge and the button flips to **Unshare** |
| 8 | Log in as `customer_a`, open **Templates** | The report from step 7 appears under **Shared Reports** with only a **▶ Run** button — **no Edit/Delete** on it |
| 9 | Still as `customer_a`, check the toolbar | **+ New Report** is present (customers can build their own) and **My Reports** shows only reports you created — not `msp_a`'s |
| 10 | As `msp_a`, on your report click **Delete** → **Confirm?** | Report disappears from **My Reports**; no error/crash |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: transactions.browser
title: Transactions Browser
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Transactions Browser** (`transactions.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **transactions.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · **Settings** gear |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 · **Settings** gear |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…** and **C1-TCR-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Transactions** | Table loads with rows and columns **ATM · Date/Time · Type · Amount · Card · Result · Seq #** |
| 2 | Expand **Filters** (click **»**) and set **Device Type = TCR** | List shows only TCR rows; switch to **ATM** and only ATM rows show |
| 3 | In **ATM**, search and pick `C1-ATM-001` | List narrows to that one machine and a removable filter tag appears above the table |
| 4 | Set **Result = Fail**, then click **✕ Clear filters** | List shows only failed rows; Clear resets every filter and the full list returns |
| 5 | In **Card / Account**, type a partial number (e.g. `4240`) | List narrows to matching cards/accounts; card numbers show **masked** |
| 6 | Click any transaction row | A detail panel opens with a **Transaction Flow** timeline; **Records** and cheque images are viewable |
| 7 | In the detail panel click **Analyze** (Adoons) | A plain-language summary appears (or the button is hidden/disabled if Adoons is unavailable — **no crash**) |
| 8 | Toggle **Auto-refresh** off, then click the **↻** refresh button | The countdown stops when off; refresh reloads the list on demand |
| 9 | Set **Date Range = Custom range…** with dates older than 90 days | An **Archived Data** confirm dialog appears; **Continue** loads the data, **Cancel** aborts |
| 10 | Log in as `customer_a` | **No Settings gear** in the sidebar; the **ATM** filter lists **only C1** devices — no C2 or C3 |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: transactions.customer-journey
title: Customer Journey
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Customer Journey** (`transactions.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **transactions.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open the transaction list and click any transaction | The **Customer Journey** drawer opens on the right, showing the ATM, date/time, and transaction type in the header |
| 2 | Look at the chips under the header | **Card/Account**, **Amount**, **Result** (Approved/Declined), **Seq**, and **⏱ Dwell time** all show a value |
| 3 | Read the **Transaction Flow** timeline | Steps run top to bottom (Card Inserted → transaction → Host Approved/Declined → Cash Dispensed or Cash/Check Accepted → Card Ejected), colored green/red/amber |
| 4 | Open a transaction with a deposit and cheques | A **Cheque Images** section appears with front/back scans |
| 5 | Open a cash withdrawal | **Cash Dispensed** shows notes/denominations (e.g. `$20 × 5`) where available |
| 6 | Scroll to **Raw Block**, click **Copy** | Button label changes to **Copied!** and the raw journal text is on your clipboard |
| 7 | Click **Ask Adoons** at the bottom (if visible) | A verdict (successful/failed/suspicious) with a short narrative and step breakdown appears; button becomes **Re-analyze** |
| 8 | Close the drawer with the **✕** button, then reopen a transaction and press **Escape** | Both close the drawer with no error |
| 9 | Log in as `customer_a`, open the transaction list | You see **only C1** transactions — no C2 or C3 |
| 10 | As `customer_a`, open a Customer Journey drawer | Drawer opens and displays fully (read-only) — no edit/delete controls anywhere in the drawer |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: transactions.journal-parsing
title: Journal Parsing Rules
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Journal Parsing** in the Transactions SPA (`transactions.bcos.dev`). Click through in the UI and mark each row Pass or Fail. The screen lives under **Settings → Journal → Parsing → ATM**.
## Set up
Log in at **transactions.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · full Settings |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 · full Settings |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
For the Reparse test use a simulator ATM ID like **C1-ATM-001**.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open the **Settings** gear → **Journal** → **Parsing** → **ATM** | Page **Journal Parsing** loads with three panels: **Journal Parsing Rules**, **Journal / Vendor Types**, **Reparse Journals** |
| 2 | Look at the **Journal Parsing Rules** panel | Rules show as read-only sections labelled **Version**, **Timestamp Pattern**, **Transaction Rules**, **System Events** |
| 3 | Click **Reload Rules** | A green message like **"Rules reloaded (v…)"** appears with a version number |
| 4 | Click **Edit Rules** | The rules turn into an editable text box; the buttons change to **Cancel** and **Save & Apply** |
| 5 | Click **Cancel** | Editing closes, the grouped read-only view returns, nothing changed |
| 6 | **Edit Rules** again, make a tiny change, click **Save & Apply** | A green **"Saved and applied (v…)"** message shows and the version number is higher than before |
| 7 | Look at the **Journal / Vendor Types** panel | It lists type badges, or shows **"No vendor types defined"** — either way, no error |
| 8 | In **Reparse Journals**, type `C1-ATM-001` in the box | The button label updates to **"Reparse C1-ATM-001"** |
| 9 | Clear the box (blank), then click **Reparse All** | A green message like **"Queued N of M journal files for re-parse."** appears |
| 10 | Log in as `customer_a` and look at the left sidebar | Only **Transactions** shows — there is **no Settings gear**, so Journal Parsing can't be reached at all |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: transactions.processing-rules
title: Journal Processing Rules
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Journal Processing Rules** (Transactions app Settings, `transactions.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **transactions.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Can edit rules? |
|-------|------|-----------------|
| `bcos_a@bcos.dev` | Admin | Yes |
| `msp_a@msp1.bcos.dev` | MSP admin | Yes |
| `customer_a@customer1.bcos.dev` | Customer | No — read-only |
This screen is **global config** — the rules apply to the whole fleet, so there is no device picker or institution filter here. Open it from the sidebar: **Settings → Journal Processing Rules**. (Sim devices like `C1-ATM-001` are only needed if you want to sanity-check a rule's effect afterwards in the Transactions browser.)
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `bcos_a`, open **Settings → Journal Processing Rules** | Page loads with two panels — **Transaction Types** and **System Events** — each showing existing rows |
| 2 | In Transaction Types, click **+ Add Type**, enter Type Name `TEST_WD`, click **Add** | New `TEST_WD` row appears at the bottom of the list and a **"You have unsaved changes"** bar shows |
| 3 | Click **Save & Apply** | A green **"Saved and applied (v…)"** message appears and the unsaved-changes bar goes away |
| 4 | On any row click **Edit**, change a field, click **Save** | The row updates in place and the unsaved-changes bar returns |
| 5 | Use the **↑ / ↓** arrows to move a row | The row swaps position and the Order numbers renumber; the top row's **↑** and the bottom row's **↓** are greyed out (disabled) |
| 6 | Click **Delete** on the `TEST_WD` row you added | The row disappears and the unsaved-changes bar shows |
| 7 | In System Events, click **+ Add Event**, type a Pattern, pick an **Event Type** from the dropdown, click **Add** | New row appears showing your pattern and a coloured event-type badge |
| 8 | Make one more edit, then click **Reload** (do not Save) | Your unsaved edit is discarded and the last-saved rules reload |
| 9 | Log in as `customer_a`, open the same screen | The rules **do not load** (error message or empty grid) — a read-only customer cannot view or change rules; no Save takes effect |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,36 @@
---
module: transactions.reparse
title: Journal Reparse
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Journal Reparse** (Transactions SPA → **Settings → Journal Reparse**, `transactions.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **transactions.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions · can reparse |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 · can reparse |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
Test devices are the simulators: **C1-ATM-001…** (ATM journals) and **C1-TCR-001…** (TCR journals).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Settings → Journal Reparse** | Page loads with two tabs **ATM Journals / TCR Journals** and two sections **File Parse Status** and **Trigger Reparse** |
| 2 | In **File Parse Status**, type `C1-ATM-001` in the filter box and click **Refresh** | Table + status pills show only that ATM's files (or *"No journal files found"* if it has none) — no error |
| 3 | Look at the status pills and the table | Coloured pills (Parsed / Pending / Parsing / Error) plus a **Total** show, and the table lists **ATM · Date · Status · Transactions · Error** |
| 4 | In **Trigger Reparse**, leave the ATM ID blank, click **Reparse All**, then **Cancel** on the pop-up | A confirm pop-up appears warning it will reparse **every ATM**; after Cancel nothing runs and no success/error message shows |
| 5 | Type `C1-ATM-001` in the Trigger Reparse box, click **Reparse All**, then **Confirm Reparse** | Pop-up names **C1-ATM-001**; after confirming a green **✓ Queued X of Y files** message appears |
| 6 | Leave **Auto-refresh** on (top right) and watch the status | Files move **Pending → Parsing → Parsed** on their own and the pill counts update without you clicking Refresh |
| 7 | Click the **TCR Journals** tab | The filter clears, the list reloads, and it now shows only TCR files; the confirm pop-up here mentions **TCR** |
| 8 | Toggle the **Auto-refresh** switch off and on | When off the countdown (`(Ns)`) disappears; when on it counts down again |
| 9 | Log in as `customer_a`, open Journal Reparse, click **Reparse All → Confirm Reparse** | A red error alert appears and **no reparse runs** — read-only customers can't trigger it |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: vault.cit-visits
title: CIT Visits
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **CIT Visits** (`vault.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **vault.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1 + C2 + C3) |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
Visits are recorded against the simulator ATMs: **C1-ATM-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **CIT Visits** | Page loads with a table (ATM ID, Visit Date, Vendor, Reference, Slots, Cash Added, Cash Removed, Removals, Status) and a **visit count** at the top |
| 2 | Click the **▶** arrow to expand the **Filters** panel on the left, set **Status = Confirmed** | Table shows only **Confirmed** rows and a **Confirmed** tag appears above the table |
| 3 | Type an ATM ID (e.g. `C1-ATM-001`) into the **ATM ID** filter | Table narrows to that machine; an **ATM: …** tag appears; the count pill updates |
| 4 | Click the **×** on the ATM tag (or **✕ Clear all**) | That filter clears and the full list returns; **Clear all** removes every tag at once |
| 5 | Set a **From / To** date range | Only visits inside that range show; count updates — no error/crash |
| 6 | Click any visit **row** | A detail panel slides in from the right with the ATM ID + vendor header, **Cash Added / Cash Removed / Removals** stats, and a **Cassette Counts** table |
| 7 | In the panel, click **✓ Confirm** (or **! Dispute**) | The status badge updates, a success toast shows, and the row's **Status** in the table changes to match |
| 8 | In the panel, under **Notes** click **Edit**, type text, click **Save** | A "Notes saved" toast shows and the note text appears; **Cancel** discards instead |
| 9 | As `customer_a`, open **CIT Visits** | You see **only C1** ATM IDs — no C2 or C3 visits anywhere in the list or filters |
| 10 | As `msp_a`, scan the list | You see **C1 and C2** visits but **not C3** |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,37 @@
---
module: vault.dashboard
title: Dashboard
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for the **Vault Dashboard** (`vault.bcos.dev`). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **vault.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
CIT visits on the dashboard are keyed to simulator ATMs: **C1-ATM-001…** (and C2-/C3- for the other institutions).
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `customer_a`, open the **Vault Dashboard** | Header reads **Vault Dashboard**, four stat cards appear, then a **Recent Visits** card below |
| 2 | Read the four cards left to right | Labels are **Visits This Month**, **Pending Confirmation** (has an amber left stripe), **Cash Added YTD**, **Removals YTD** — YTD cards show money (e.g. `$…`), not a raw number |
| 3 | Look at the Recent Visits table headers | Columns are **ATM ID · Visit Date · Vendor · Reference · Cash Added · Removals · Status** |
| 4 | Scan a few visit rows | A visit with no reference / no removals shows a dash **—** in that cell (not blank or `null`) |
| 5 | Check the **Status** column | Each row shows a coloured pill: **Pending** (yellow), **Confirmed** (green), or **Disputed** (red) |
| 6 | Click any visit row | That visit's **detail** opens (cassette counts / removals) — the whole row is clickable |
| 7 | As `customer_a`, read the **ATM ID** column | Only **C1-** ATMs appear — no C2- or C3- rows |
| 8 | Look at the header/toolbar as `customer_a` | Dashboard is **view-only** — there is **no Add / Create / Refresh** button anywhere on the page |
| 9 | Log in as `bcos_a` and open the dashboard | Cards show non-zero totals and the table lists visits across **multiple** institutions (C1/C2/C3 ATM IDs) |
| 10 | Log in as `msp_a` and open the dashboard | Recent Visits table is **populated**, but the four cards may all read **0** — this is a known scoping quirk for multi-institution admins, **do not fail it** (report separately) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -0,0 +1,39 @@
---
module: vault.import
title: Import
tab: Testing
order: 35
audience: internal
---
Frontend test checklist for **Import CIT Data** in Vault (`vault.bcos.dev` → **Import** in the sidebar). Click through in the UI and mark each row Pass or Fail.
## Set up
Log in at **vault.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only |
| `customer_a@customer1.bcos.dev` | Customer | C1 only |
For upload tests, make a small CSV using a real sim ATM id (e.g. **C1-ATM-001**) — or just use the downloaded template and change the `atm_id` column to `C1-ATM-001`.
## What to test
| # | Do this | ✅ Pass if |
|---|---------|-----------|
| 1 | As `msp_a`, open **Import** | Page shows the **drag & drop upload box**, a **↓ Download Template** button, and an **Import History** table |
| 2 | Click **↓ Download Template** | A file `cit-import-template.csv` downloads to your computer |
| 3 | Expand **CSV Format Reference** | Section opens and shows the cassette-row and removal-row column layouts |
| 4 | Click **Browse File** and pick a valid `.csv` (atm_id = `C1-ATM-001`) | Box shows **Uploading…**, then the file appears at the **top** of Import History with status **Processing** |
| 5 | Wait a few seconds (no refresh) | Row flips to **Completed**, the **Records** column shows a visit count, and a green "Import complete" message appears |
| 6 | Try to upload a non-CSV file (e.g. a `.txt` or `.pdf`) | Upload is **rejected** with an "Only CSV files are accepted" message — nothing is added to the history |
| 7 | Upload a CSV where `visit_date` is a bad date (e.g. `not-a-date`) | Row shows status **Failed** and the **Error** column shows a short reason — page does **not** crash |
| 8 | If there are many imports, use the paging controls under the table | Page changes and row-count-per-page control both work — no error/crash |
| 9 | Log in as `customer_a`, open **Import** | You see the upload box **and** an Import History showing **only C1** files — no C2 or C3 imports |
| 10 | As `msp_a`, check the **By** column on completed imports | It shows the **email** of whoever uploaded each file |
> Note: Import has **no Add-button role gating** — every logged-in user (including `customer_a`) can upload for their own institution. Seeing an upload box as a customer is **expected**, not a bug.
**Report a fail with:** the row #, which login you used, and what you actually saw.