Hackorda Test Cases
These are the test cases for the cycle "Hackorda Onboarding — QA shake-down". Run every case in order. For each one:
- Read the Preconditions and make sure they're met.
- Run the Steps.
- Compare the result to Expected.
- If they don't match → file an issue. Use the Severity if fails as a starting point but adjust based on what you actually see.
- Tick the case in this doc and move on.
Read onboarding.md first if you haven't. The bug-report standards there apply to every case below.
Groups L–O cover features that shipped this month. Read feature-guide.md before running them — it explains the intended behaviour so you can tell a real bug from designed behaviour.
How to read a test case
TC-XX · Short title
Surface: Where in the app this lives
Preconditions: What must be true before you start
Steps:
1. Action
2. Action
Expected: What should happen
If fails: file as `<bug type>` / `<severity>`Group A — Auth & profile
TC-01 · Sign in with valid credentials
- Surface:
/sign-in - Preconditions: Logged out. You have a working account.
- Steps:
- Open
/sign-in - Type your email and password
- Click Sign in
- Open
- Expected: Redirects to
/app. Sidebar shows your name. - If fails: functional / critical
TC-02 · Sign in with wrong password
- Surface:
/sign-in - Preconditions: Logged out.
- Steps:
- Open
/sign-in - Enter a real email + a wrong password
- Click Sign in
- Open
- Expected: Inline error message appears. No redirect. No console errors.
- If fails: functional / high
TC-03 · Sign-out clears session
- Surface: Sidebar
- Preconditions: Logged in.
- Steps:
- Click your avatar in the sidebar footer
- Click Sign out
- Try to navigate to
/app/profiledirectly via URL
- Expected: Redirected to
/sign-in. No private data flashes during redirect. - If fails: security / critical
TC-04 · Profile page loads with my data
- Surface:
/app/profile - Preconditions: Logged in.
- Steps:
- Click Profile in the sidebar
- Expected: Page loads under 1.5 s. Your real name and email show. No placeholder/lorem text.
- If fails: functional / medium
TC-05 · 1Password prompt suppressed on entity forms
- Surface: Any form labeled with
data-1p-ignore(org create, product create, file-issue title) - Preconditions: 1Password browser extension installed.
- Steps:
- Open any entity-creation form (e.g.
/app/admin/organizations→ Add) - Click into the Name field
- Open any entity-creation form (e.g.
- Expected: No 1Password autofill prompt over the input.
- If fails: visual / low
Group B — Navigation & layout
TC-06 · Primary sidebar is keyboard-accessible
- Surface: Main app sidebar
- Preconditions: Logged in, on
/app. - Steps:
- Press Tab repeatedly from the top
- Each sidebar item should focus visibly
- Press Enter on a focused item
- Expected: Focus ring is visible on every item. Enter navigates. No items skipped.
- If fails: accessibility / high
TC-07 · QA section sidebar appears under /app/test-cycles/*
- Surface: Any
/app/test-cycles/...route - Preconditions: Logged in. You're a member of at least one cycle.
- Steps:
- Navigate to
/app/test-cycles
- Navigate to
- Expected: A second sidebar appears between the primary nav and the page content, showing My Cycles, All Issues, My Reports, plus the list of your cycles with status dots.
- If fails: visual / high
TC-08 · QA sidebar surfaces current cycle
- Surface:
/app/test-cycles/[id] - Preconditions: You're a member of an active cycle.
- Steps:
- Click into any of your cycles
- Expected: The QA sidebar shows a "Current cycle" group with the cycle name + status badge + Brief / File issue links. The list highlights the current cycle row.
- If fails: visual / medium
TC-09 · Breadcrumbs show entity names, not UUIDs
- Surface:
/app/test-cycles/[id]/issues/[issueId] - Preconditions: You have an issue you can open.
- Steps:
- Open any issue detail page
- Look at the breadcrumb at the top
- Expected: Crumbs read like
Test Cycles › <Cycle name> › Issues › <Issue title>. No raw4a3b...c91UUIDs. - If fails: content / medium
TC-10 · Theme toggle switches light/dark
- Surface: Sidebar footer
- Preconditions: Logged in.
- Steps:
- Note current theme
- Click the theme toggle at the bottom of the sidebar
- Reload the page
- Expected: Theme flips. After reload, the new theme persists. No flash of wrong theme during reload.
- If fails: visual / medium
Group C — Test cycles list & detail (meta!)
TC-11 · My Cycles page shows my assignments
- Surface:
/app/test-cycles - Preconditions: You're assigned to ≥1 cycle.
- Steps:
- Navigate to
/app/test-cycles
- Navigate to
- Expected: Each cycle shows: name, org, product, version, date range, status badge, your role badge. Clicking a row opens the cycle.
- If fails: functional / high
TC-12 · Status filter chips work
- Surface:
/app/test-cycles - Preconditions: You have cycles in ≥2 different statuses.
- Steps:
- Click Active in the chip row
- Then click All
- Expected: Filter narrows to active cycles, then expands back. Counts in chips match the list count.
- If fails: functional / medium
TC-13 · Cycle detail brief renders markdown
- Surface:
/app/test-cycles/[id] - Preconditions: Cycle has a description with markdown formatting.
- Steps:
- Open the cycle
- Look at the Brief tab
- Expected: Headings, lists, links render properly. No raw
**or[](). - If fails: visual / medium
TC-14 · External links list renders Notion/Linear chips
- Surface:
/app/test-cycles/[id]brief tab - Preconditions: Cycle has external links in metadata.
- Steps:
- Open Brief tab
- Expected: Linked resources show as chips with the right icon (Notion, Linear, GitHub, etc.) and clickable.
- If fails: visual / low
Group D — Filing an issue (the workhorse)
TC-15 · "File issue" blocked when cycle is not active
- Surface:
/app/test-cycles/[id]/issues/new - Preconditions: You're a member of a cycle in
planned,review,closed, orcancelledstate. - Steps:
- Try to navigate to the file-issue page
- Expected: UI surfaces a clear message that issues can't be filed in current state. The submit button is disabled, OR the page redirects with a toast.
- If fails: functional / high
TC-16 · Title under 5 chars blocks submit
- Surface:
/app/test-cycles/[id]/issues/new - Preconditions: Active cycle.
- Steps:
- Type "hi" in the title
- Pick severity, attach a screenshot
- Try File issue
- Expected: Submit stays disabled with a hint about minimum length.
- If fails: functional / medium
TC-17 · Severity picker visually selects
- Surface: File-issue form
- Preconditions: Form is open.
- Steps:
- Click each of Critical / High / Medium / Low in turn
- Expected: The clicked card outlines/fills as selected. Severity hint text below updates to match.
- If fails: visual / medium
TC-18 · Bug type is optional but stored
- Surface: File-issue form
- Preconditions: Active cycle.
- Steps:
- File an issue without picking a bug type
- File a second issue with type =
visual - Open both in All Issues view
- Expected: First has no bug-type chip; second shows pink "visual" chip next to the type badge.
- If fails: functional / medium
TC-19 · Screenshots dropzone rejects video
- Surface: File-issue form, screenshots dropzone
- Preconditions: —
- Steps:
- Drag a
.mp4file onto the Screenshots zone
- Drag a
- Expected: File is rejected (browser native filter via
accept="image/*"), or shown with an error. - If fails: functional / medium
TC-20 · Recordings dropzone shows video preview
- Surface: File-issue form, recordings dropzone
- Preconditions: You have an
.mp4clip. - Steps:
- Drop the video on the Recordings zone
- Expected: Tile shows the video poster frame. Hovering reveals an X to remove. File size renders correctly.
- If fails: visual / medium
TC-21 · Save draft writes to server
- Surface: File-issue form
- Preconditions: Active cycle. You're logged in.
- Steps:
- Type a title (≥5 chars)
- Click Save draft
- Expected: Toast says "Saved as draft". Redirects to
/app/issues/mine. An issue with statusdraftappears in your list. - If fails: functional / high
TC-22 · Draft auto-save survives refresh
- Surface: File-issue form
- Preconditions: No saved draft for this cycle yet.
- Steps:
- Type a long title and a few description lines
- Refresh the page
- Expected: Title and description re-populate from localStorage. Footer says "Auto-saved locally".
- If fails: functional / medium
TC-23 · Submitting clears the draft
- Surface: File-issue form
- Preconditions: A locally saved draft exists.
- Steps:
- Complete the form and click File issue
- After redirect, navigate back to
/app/test-cycles/[id]/issues/new
- Expected: The form is empty.
- If fails: functional / low
TC-24 · Required-fields meter goes 0 → 3
- Surface: File-issue form
- Preconditions: Empty form.
- Steps:
- Watch the Required to submit meter
- Add title, then severity, then an attachment one at a time
- Expected: Meter advances 0/3 → 1/3 → 2/3 → 3/3. At 3/3, File issue enables.
- If fails: visual / medium
TC-25 · Section completion checkmark appears
- Surface: File-issue form
- Preconditions: Empty form.
- Steps:
- Fill in all required fields in section 1
- Expected: The "1" step circle flips to a green checkmark. Section description disappears (no longer needed).
- If fails: visual / low
Group E — Issue detail & triage
TC-26 · Issue detail loads attachments inline
- Surface:
/app/test-cycles/[id]/issues/[issueId] - Preconditions: Issue has at least one screenshot attached.
- Steps:
- Open the issue
- Expected: Image renders inline. Click opens full-size in a new tab. Video plays in-page.
- If fails: functional / high
TC-27 · Comments post and appear in thread
- Surface: Issue detail
- Preconditions: You can comment (member of cycle, issue not closed).
- Steps:
- Type a comment
- Submit
- Expected: Comment appears immediately at the bottom with your name and current timestamp. Optimistic update — no full refresh needed.
- If fails: functional / medium
TC-28 · Tester can't change someone else's status
- Surface: Issue detail
- Preconditions: You're a
tester(not lead/admin). Issue was filed by someone else. - Steps:
- Try to change the status using whatever UI exists
- Expected: No status control is shown for that issue, OR API rejects the change with a clear message.
- If fails: security / high
TC-29 · Reporter can self-flip own draft to open
- Surface: Issue detail (your draft)
- Preconditions: You have a draft you reported.
- Steps:
- Open the draft from All Issues → Mine
- Submit / mark open
- Expected: Status flips
draft→openand the issue starts counting toward the cycle. - If fails: functional / high
TC-30 · Lead can quick-triage from the cycle issues tab
- Surface:
/app/admin/test-cycles/[id]Issues tab - Preconditions: You're admin or lead. There's an
openissue. - Steps:
- Click the Triage button on an open issue row
- Expected: Status flips to
triaged. Toast confirms. No page reload. - If fails: functional / high
Group F — All issues view (cross-cycle)
TC-31 · All Issues page lists every issue I can see
- Surface:
/app/issues - Preconditions: You're a member of multiple cycles with issues.
- Steps:
- Open the page
- Expected: Table shows issues from every cycle you have access to. Counts at the bottom match.
- If fails: functional / high
TC-32 · Mine filter shows only my reports
- Surface:
/app/issues - Preconditions: Some issues you reported, some you didn't.
- Steps:
- Click the Mine chip
- Expected: List narrows to issues you reported. URL gains
?mine=1. Refresh preserves the filter. - If fails: functional / medium
TC-33 · Severity + status filters compose
- Surface:
/app/issues - Preconditions: Mixed issues.
- Steps:
- Pick severity =
high - Then pick status =
open
- Pick severity =
- Expected: Both filters apply. Only high-severity, open issues show.
- If fails: functional / medium
TC-34 · Search across title / cycle / org / product
- Surface:
/app/issues - Preconditions: Some issues.
- Steps:
- Type a unique substring of an issue title in the search box
- Then type a product name
- Expected: Results narrow live. Empty match shows the empty state.
- If fails: functional / low
Group G — Quizzes (existing feature)
TC-35 · Start a quiz from the leaderboard
- Surface:
/app/quiz - Preconditions: Logged in.
- Steps:
- Click Quiz in the sidebar
- Pick any quiz
- Click Start
- Expected: Quiz session loads. First question visible. Timer if applicable.
- If fails: functional / high
TC-36 · Submitting an answer advances to next question
- Surface: Active quiz
- Preconditions: TC-35 passed.
- Steps:
- Pick any answer
- Click Submit
- Expected: Next question loads or end-screen appears. Score visible.
- If fails: functional / critical
TC-37 · Refresh during quiz preserves progress
- Surface: Active quiz
- Preconditions: Mid-quiz.
- Steps:
- Refresh the page
- Expected: Quiz resumes at the current question with answers preserved (or user is redirected to a clear "resume" screen).
- If fails: functional / high
Group H — Events & teams (existing)
TC-38 · Events list loads
- Surface:
/app/events - Preconditions: Logged in.
- Steps:
- Click Events in the sidebar
- Expected: List of events. Each has a name, date, status. No layout shift on load.
- If fails: functional / medium
TC-39 · Event detail shows hero image (or placeholder)
- Surface:
/app/events/[id] - Preconditions: An event exists.
- Steps:
- Click into any event
- Expected: Hero loads. Description renders. No broken image icons.
- If fails: visual / low
TC-40 · Browse teams page loads
- Surface:
/app/teams/browse - Preconditions: —
- Steps:
- Click Teams in sidebar
- Expected: Team list. Search works.
- If fails: functional / medium
Group I — Performance & responsiveness
TC-41 · Initial /app load under 2 seconds (cold cache)
- Surface:
/app - Preconditions: Hard refresh (
⌘⇧R). Throttle network to "Fast 3G" in devtools to be conservative. - Steps:
- Reload
/app - Watch Network tab
- Reload
- Expected: Largest Contentful Paint under ~2s on Fast 3G.
- If fails: performance / medium
TC-42 · No console errors on idle
- Surface: Any page
- Preconditions: Devtools open, console clear.
- Steps:
- Navigate to
/app - Wait 30 s without touching anything
- Navigate to
- Expected: No red errors. Warnings are OK but note them in a low-severity issue if you see new ones.
- If fails: functional / medium
TC-43 · Mobile layout — file-issue form on 375px width
- Surface:
/app/test-cycles/[id]/issues/newon mobile - Preconditions: Devtools mobile mode (iPhone 13) or real phone.
- Steps:
- Open the form on a 375px-wide viewport
- Try to fill it out — title, severity, attachments
- Expected: No horizontal scroll. Severity grid and bug type grid stack cleanly. Buttons in the sticky footer stay reachable.
- If fails: visual / high
TC-44 · 320px width doesn't break sidebar
- Surface:
/app/test-cycles - Preconditions: Devtools, 320px width.
- Steps:
- Resize and observe
- Expected: Section sidebar either collapses gracefully or hides behind a toggle. No content cut off.
- If fails: visual / medium
Group J — Accessibility
TC-45 · Severity picker reachable by keyboard
- Surface: File-issue form
- Preconditions: Form open.
- Steps:
- Tab into the severity picker
- Use arrow keys (or Tab) to move between options
- Press Space or Enter to select
- Expected: Each option focuses with a visible ring. Enter selects.
aria-checkedupdates. - If fails: accessibility / high
TC-46 · Filter chips have visible focus
- Surface: Any list page with chips (
/app/test-cycles,/app/issues) - Preconditions: —
- Steps:
- Tab to a chip
- Expected: Focus ring is visible (not absent, not 1px).
- If fails: accessibility / medium
TC-47 · Color is not the only signal for status
- Surface: Cycle status badges, severity badges, issue-status badges
- Preconditions: —
- Steps:
- Inspect every badge
- Expected: Each badge has a text label, not color alone (we already do this — this is a regression check).
- If fails: accessibility / medium
TC-48 · Alt text on screenshot thumbnails
- Surface: File-issue form, after attaching a screenshot
- Preconditions: Screenshot attached.
- Steps:
- Inspect the thumbnail's
<img>element in devtools
- Inspect the thumbnail's
- Expected:
altattribute is set to the file name (or descriptive text). - If fails: accessibility / low
Group K — Sad-path / weird-input
TC-49 · Upload an attachment > 100 MB
- Surface: Either dropzone
- Preconditions: A file >100 MB.
- Steps:
- Try to upload
- Expected: Inline error. No console crash.
- If fails: functional / medium
TC-50 · Paste a 5,000-char title
- Surface: File-issue form
- Preconditions: —
- Steps:
- Paste a very long string into the title
- Expected: Field accepts up to its max (500 chars per schema). Above that, graceful truncation or block.
- If fails: functional / low
TC-51 · Submit with cycle that just expired
- Surface: File-issue form
- Preconditions: A cycle whose
endsAtjust passed (within last few minutes). - Steps:
- Try to submit
- Expected: Server rejects with a clear "cycle is in review" message. UI doesn't show a generic 500.
- If fails: functional / high
TC-52 · Direct-URL access to a cycle I'm not assigned to
- Surface:
/app/test-cycles/<some-id-you-arent-in> - Preconditions: You know a cycle ID you're not a member of.
- Steps:
- Paste the URL and load
- Expected: Either redirects with a toast, OR shows a 403 page. Never exposes data from the foreign cycle.
- If fails: security / critical
Group L — Cycle close-out (batch export & bulk verification)
Surface for this group: the admin cycle detail page,
/app/admin/test-cycles/[id]. See feature-guide.md §A. All of these run on a plainadminaccount.
TC-53 · Linear checkboxes appear only when the product has a Linear integration
- Surface:
/app/admin/test-cycles/[id]Issues tab - Preconditions: Two TEST cycles you can open as admin — one whose product has a Linear integration configured, one whose product does not.
- Steps:
- Open the Issues tab on the cycle whose product has Linear configured
- Open the Issues tab on the cycle whose product has no Linear
- Expected: The Linear-configured cycle shows a checkbox on each issue row and an export toolbar above the list. The non-configured cycle shows no checkboxes and no toolbar — the tab looks unchanged.
- If fails: functional / high
TC-54 · Multi-select issues for export
- Surface:
/app/admin/test-cycles/[id]Issues tab - Preconditions: A TEST cycle whose product has Linear configured, with ≥3 issues.
- Steps:
- Tick the checkbox on two different issue rows
- Read the export toolbar
- Expected: Both rows show as selected. The toolbar reflects the selection count and the Export to Linear action is enabled.
- If fails: functional / medium
TC-55 · "Select all approved" picks approved, not-yet-exported issues
- Surface: Issues tab export toolbar
- Preconditions: A TEST cycle with a mix of issue states — some with an approved payout and not yet exported, some not approved, some already exported.
- Steps:
- Click Select all approved
- Expected: Only approved-payout issues that have not been exported are selected. Non-approved and already-exported issues stay unselected.
- If fails: functional / high
TC-56 · "Clear" deselects everything
- Surface: Issues tab export toolbar
- Preconditions: Several issues selected.
- Steps:
- Click Clear
- Expected: All checkboxes clear. The Export action disables again.
- If fails: functional / low
TC-57 · Export dialog opens with the selected issues
- Surface: Issues tab → Export dialog
- Preconditions: Two issues selected.
- Steps:
- Click Export to Linear
- Expected: A dialog opens pre-loaded with exactly the two selected issues. It offers a group vs separate mode choice.
- If fails: functional / high
TC-58 · Successful export clears the selection
- Surface: Issues tab → Export dialog
- Preconditions: A TEST cycle with Linear configured; issues selected and the export dialog open. Work only against the TEST product's Linear project.
- Steps:
- Choose a mode (group or separate)
- Confirm the export
- Wait for the success state
- Expected: Export succeeds. After it completes, the row checkboxes are all cleared.
- If fails: functional / medium
TC-59 · Bulk verification card lists every fixed issue
- Surface:
/app/admin/test-cycles/[id]Overview tab - Preconditions: A TEST cycle with ≥2 issues in status
fixedand at least one issue in another status. - Steps:
- Open the Overview tab
- Read the amber "Awaiting fix verification (N)" card
- Expected: The card lists exactly the
fixedissues. N matches that count. Issues in other statuses do not appear. Each row has Fix verified and Still broken actions. - If fails: functional / high
TC-60 · "Fix verified" promotes the issue and the row drops off
- Surface: Overview tab verification card
- Preconditions: A
fixedissue in the card. - Steps:
- Click Fix verified on a row
- Open that issue's detail page
- Expected: The row leaves the card immediately. The issue is now
verifiedand an audit comment recording the verification appears in its thread. - If fails: functional / high
TC-61 · "Still broken" requires a reason of ≥5 chars
- Surface: Overview tab verification card
- Preconditions: A
fixedissue in the card. - Steps:
- Click Still broken on a row — an expander opens
- Type "no" (under 5 chars) and try to confirm
- Then type a real reason (≥5 chars) and confirm
- Open that issue's detail page
- Expected: The short reason is blocked with a hint. The valid reason submits:
the row drops off the card, the issue goes back to
in_progress, and the reason is posted as a comment. - If fails: functional / medium
TC-62 · Verification card is hidden when nothing awaits verification
- Surface:
/app/admin/test-cycles/[id]Overview tab - Preconditions: A TEST cycle with no issues in status
fixed. - Steps:
- Open the Overview tab
- Expected: No "Awaiting fix verification" card is shown at all.
- If fails: visual / low
Group M — Cycle aging & list views
Surface for this group: the test-cycles list —
/app/test-cyclesand/app/admin/test-cycles. See feature-guide.md §B.
TC-63 · Aging pill shows status + age on every row
- Surface:
/app/test-cycles(or/app/admin/test-cycles) - Preconditions: You can see ≥2 TEST cycles in different statuses.
- Steps:
- Open the cycle list
- Read the aging pill on each cycle
- Expected: Every cycle shows a pill like
Active 2dorIn review 6d— current status plus days in that status. - If fails: visual / medium
TC-64 · Review aging pill escalates colour by age
- Surface: Cycle list, aging pill on
reviewcycles - Preconditions: TEST cycles in
reviewat different ages — ideally one under 3 days, one at 3–6 days, one at 7+ days. - Steps:
- Compare the pill colour on each
reviewcycle
- Compare the pill colour on each
- Expected: Under 3 days = neutral; 3–6 days = amber; 7+ days = red.
- If fails: visual / medium
TC-65 · Non-review cycles always show a neutral pill
- Surface: Cycle list, aging pill
- Preconditions: A TEST cycle in
active(or planned/closed) that has been in that status for 7+ days. - Steps:
- Read its aging pill
- Expected: The pill stays neutral — only
reviewcycles escalate to amber/red. - If fails: visual / low
TC-66 · Progress bar segments and label are correct
- Surface: Cycle list, progress bar on a card/row
- Preconditions: A TEST cycle with a mix of issues — some approved/paid, some rejected/duplicate, some still pending triage.
- Steps:
- Read the segmented progress bar and its label
- Expected: Green = approved + paid, grey = other resolved, amber = pending
triage. The label reads like
12 / 17 reviewed · 71%and the maths is right. - If fails: functional / medium
TC-67 · Cycle with no issues shows "No issues yet"
- Surface: Cycle list, progress area
- Preconditions: A TEST cycle with zero issues.
- Steps:
- Find that cycle in the list
- Expected: Instead of a progress bar, it shows "No issues yet".
- If fails: content / low
TC-68 · Cards view sort dropdown reorders the list
- Surface:
/app/test-cycles— Cards view - Preconditions: Several TEST cycles.
- Steps:
- Switch to Cards view
- Open the sort dropdown and pick each option in turn: Longest in review, Recently created, Ending soonest, Name A–Z
- Expected: Each option visibly reorders the cards in the expected direction.
- If fails: functional / medium
TC-69 · Review filter auto-switches sort to "Longest in review"
- Surface:
/app/test-cycles— Cards view - Preconditions: Cycles in ≥2 statuses including
review. Sort currently set to something other than "Longest in review". - Steps:
- Select the review status filter
- Read the sort dropdown
- Expected: The sort auto-switches to Longest in review.
- If fails: functional / low
TC-70 · Table view defaults to "Days in review" descending
- Surface:
/app/test-cycles— Table view - Preconditions: A mix of review and non-review TEST cycles.
- Steps:
- Switch to Table view without touching any column header
- Read the Days in review and Progress columns
- Expected: The table is sorted by Days in review descending by default. Non-review cycles sink below review cycles. A Progress column is present.
- If fails: functional / medium
TC-71 · Board view groups cycles into status columns, stalest-first
- Surface:
/app/test-cycles— Board view - Preconditions: TEST cycles spread across several statuses.
- Steps:
- Switch to Board view (the 4th toggle option)
- Check the columns and the card order inside one column
- Narrow the browser window
- Expected: One column per status (planned, active, review, closed, cancelled). Each cycle sits in its status column. Within a column, cards are sorted stalest-first (longest in status on top). Empty columns read "No cycles". On a narrow window the board scrolls horizontally.
- If fails: functional / high
TC-72 · Chosen view persists across reloads
- Surface:
/app/test-cycles— view toggle - Preconditions: —
- Steps:
- Switch to Board view
- Reload the page
- Expected: The list comes back in Board view, not the default.
- If fails: functional / low
TC-73 · Approximate age caveat for pre-existing review cycles
- Surface: Cycle list, aging pill
- Preconditions: A TEST cycle that was already in
reviewbefore the aging feature shipped. (The owner can confirm which cycles qualify.) - Steps:
- Read its aging pill day count
- Expected: The day count is approximate for such cycles — a small offset is expected and is not a bug. Cycles that change status after the feature shipped are exact. Only file an issue if the count is wildly wrong (e.g. negative, or off by weeks).
- If fails: functional / low
TC-74 · Desktop layout regression check
- Surface:
/app/test-cyclesand/app/admin/test-cyclesat desktop width - Preconditions: Normal desktop viewport.
- Steps:
- Open both list pages
- Cycle through Cards, Table, Timeline, Board views
- Expected: Desktop layout is unchanged by the aging/board work — no misaligned pills, broken bars, overflow, or shifted toolbars.
- If fails: visual / medium
Group N — Mobile close-out
Run this group at 375px width (devtools iPhone 13 or a real phone). See feature-guide.md §C — desktop layout should be unchanged.
TC-75 · Admin cycle detail page is usable at 375px
- Surface:
/app/admin/test-cycles/[id]on a 375px viewport - Preconditions: A TEST cycle you can open as admin.
- Steps:
- Open the cycle detail page at 375px
- Switch between the Overview and Issues tabs
- Expected: No horizontal scroll. Tabs, cards, and toolbars stack cleanly and stay reachable.
- If fails: visual / high
TC-76 · Triage rows and status controls work at 375px
- Surface:
/app/admin/test-cycles/[id]Issues tab on a 375px viewport - Preconditions: A TEST cycle with ≥1
openissue. - Steps:
- Find a triage row at 375px width
- Open and use its status control
- Expected: The row and its status control are fully visible and tappable. No clipping, no off-screen buttons.
- If fails: visual / high
TC-77 · Cycle list is usable at 375px
- Surface:
/app/test-cycleson a 375px viewport - Preconditions: Several TEST cycles.
- Steps:
- Open the list at 375px
- Cycle through Cards, Table, and Board views
- Expected: Aging pills and progress bars render cleanly. The Board scrolls horizontally. No content cut off.
- If fails: visual / medium
TC-78 · Tester issue screen is usable at 375px
- Surface:
/app/test-cycles/[id]/issues/[issueId]on a 375px viewport - Preconditions: An issue you can open.
- Steps:
- Open the issue detail page at 375px
- Expected: Attachments, the comment thread, and the comment box all fit the viewport. No horizontal scroll.
- If fails: visual / medium
TC-79 · Fix-verification screen is usable at 375px
- Surface:
/app/admin/test-cycles/[id]Overview tab verification card, at 375px - Preconditions: A TEST cycle with ≥1
fixedissue. - Steps:
- Open the Overview tab at 375px
- Open the Still broken expander on a row
- Expected: The verification card, its rows, the two actions, and the reason expander all fit the viewport and stay tappable.
- If fails: visual / high
Group O — Roles & payout integrity
Security-sensitive group — see feature-guide.md §D. Your account is a plain
admin. Cases that need a payout approved/paid, or the Audit Log opened, must be set up or run by the owner (a super-admin) — this is called out in each case's Preconditions. Run everything against TEST orgs/products/cycles only.
TC-80 · A plain admin CAN reject an issue
- Surface:
/app/admin/test-cycles/[id]Issues tab - Preconditions: Your plain
adminaccount. A TEST cycle with anopenissue. - Steps:
- Open the triage controls on an open issue
- Choose Reject
- Expected: The reject succeeds — rejecting an issue is allowed for a plain admin.
- If fails: functional / high
TC-81 · A plain admin CAN request info
- Surface:
/app/admin/test-cycles/[id]Issues tab - Preconditions: Your plain
adminaccount. A TEST cycle with anopenissue. - Steps:
- Open the triage controls on an open issue
- Choose Request info
- Expected: The request-info action succeeds — it is allowed for a plain admin.
- If fails: functional / high
TC-82 · A plain admin CANNOT approve a payout
- Surface:
/app/admin/test-cycles/[id]Issues tab - Preconditions: Your plain
adminaccount. A TEST cycle with an issue whose payout could be approved. - Steps:
- Look for the Approve payout decision on the triage controls
- If it is visible, attempt it
- Expected: Approving a payout is not available to a plain admin — the control is hidden/disabled, or the action is blocked with a permission error. No payout is approved.
- If fails: security / critical
TC-83 · A plain admin CANNOT disburse payouts
- Surface: Payout / batch-pay UI
- Preconditions: Your plain
adminaccount. - Steps:
- Navigate to the batch-pay / run-batch payout flow
- Attempt to disburse a payout batch
- Expected: Disbursing payouts is not available to a plain admin — blocked with a permission error. No money moves.
- If fails: security / critical
TC-84 · A plain admin CANNOT change a user's role
- Surface: Users admin page
- Preconditions: Your plain
adminaccount. - Steps:
- Open the users admin page
- Find the role control on any user row and try to change the role
- Expected: The role cannot be changed by a plain admin — see TC-89 for the read-only UI. Any API attempt is blocked with a permission error.
- If fails: security / high
TC-85 · A plain admin CANNOT see the Audit Log
- Surface: Sidebar /
/app/admin/audit - Preconditions: Your plain
adminaccount. - Steps:
- Look for an Audit Log entry in the sidebar
- Then navigate directly to
/app/admin/auditvia the URL bar
- Expected: No Audit Log sidebar entry is shown. Direct navigation is denied — a 403 or a redirect with a toast. No audit data is exposed.
- If fails: security / high
TC-86 · Self-approval is blocked even for a super-admin
- Surface:
/app/admin/test-cycles/[id]Issues tab, payout approve - Preconditions: Run by the owner / a super-admin account. A TEST cycle with an issue the super-admin reported themselves.
- Steps:
- As the super-admin who reported the issue, try to approve its payout
- Expected: The action is blocked with a permission error — nobody can approve a payout for an issue they reported, even a super-admin.
- If fails: security / critical
TC-87 · Self-payment is blocked even for a super-admin
- Surface: Payout / batch-pay UI
- Preconditions: Run by the owner / a super-admin account. A payout exists for an issue the super-admin reported themselves.
- Steps:
- As the super-admin who reported the issue, try to pay out / include that payout in a batch
- Expected: The action is blocked with a permission error — nobody can pay out a payout for an issue they reported, even a super-admin.
- If fails: security / critical
TC-88 · Sensitive actions create audit entries
- Surface:
/app/admin/audit - Preconditions: Run by the owner / a super-admin account. The owner has just performed at least one of: a payout decision, a batch payment, a role change, or a cycle status change — on TEST data.
- Steps:
- As the super-admin, open
/app/admin/audit - Find the action just performed
- As the super-admin, open
- Expected: The action shows in the trail with its actor and type. The log is filterable by action and by actor, and the filters narrow the list correctly.
- If fails: functional / high
TC-89 · Role management UI is read-only for a plain admin
- Surface: Users admin page
- Preconditions: Your plain
adminaccount. - Steps:
- Open the users admin page
- Look at the role shown for each user
- Expected: Each role appears as a read-only badge — not an interactive dropdown. There is no way to open a role picker.
- If fails: security / high
TC-90 · Role management UI is interactive for a super-admin
- Surface: Users admin page
- Preconditions: Run by the owner / a super-admin account.
- Steps:
- As the super-admin, open the users admin page
- Look at the role control on a user row
- Expected: The role is an interactive dropdown for a super-admin — the same control that renders as a read-only badge for a plain admin in TC-89.
- If fails: functional / medium
Done?
When you've ticked all 90 cases, write a one-page summary in the cycle's brief: how many cases passed, how many issues you filed, and three observations the team should hear at the next sync. That's your week-one deliverable.
Note that some Group O cases (TC-86, TC-87, TC-88, TC-90) must be run by the owner on a super-admin account — coordinate with them so those don't get skipped.