QA workflow
QA at this monorepo has two pillars: Linear tracks features / bugs / scenario libraries (this page), and Playwright + Bun Test run the automated checks (Running tests locally below).
Features, bugs, and QA test runs are tracked in Linear:
QA— prefixQA(e.g.QA-45) — holds the scenario library, rebuilt from scratch in Aug 2026 (the oldRECQteam and its issues were deleted)Product— prefixREC— planned but not yet created in the workspace
Where things live
Section titled “Where things live”| What | Where |
|---|---|
| Feature roadmap & status | Linear → Product team → Roadmap view (team not yet created) |
| Bugs | Linear → Product team → issues labeled bug (until it exists, file bugs in the QA team) |
| QA test scenarios (library + per-release) | Linear → QA team → project QA — Pre-PRD Coverage Library |
| Per-feature acceptance tests | Linear → Product team → the feature’s Project, labeled qa-acceptance (team not yet created) |
| Permanent shipped-features manifest | Features (“implemented” section) |
| Architecture & planning | Architecture, Roadmap |
Test scenario format
Section titled “Test scenario format”One Linear issue = one user-flow checklist (5–12 steps). Use the QA team’s issue template:
**Surface:** web | mobile (user/agent app) | worker | shared**Area:** auth | listings | leads | tours | search | ai | i18n | billing | chat | notifications | teams | engagement | profile | agents-directory | images | platform**Platform cadence:** (native scenarios only) smoke → both iOS + Android every pass; otherwise one platform per pass, alternating**Preconditions:** (e.g., logged-in agent with ≥1 published listing)**Test data:** (specific accounts or fixtures)
## Steps- [ ] 1. ...- [ ] 2. ... (5–12 total)
## Expected outcome- ...
## Edge cases to also probe (light touch)- ...
## Last run- vX.Y — PASS/FAIL — YYYY-MM-DD — testerIf you need more than 12 steps, split into two scenarios. Always record the test-data identifier used so failures are reproducible.
One scenario covers both platforms of a native app: qa-smoke native scenarios run on both iOS and Android every pass; all other native scenarios run on one platform and alternate per pass, with “repeat on the other platform” as a standing light-touch edge. Each native issue’s **Platform cadence:** line states which rule applies.
Labels
Section titled “Labels”| Label | Meaning |
|---|---|
qa-smoke | Must pass before any prod deploy. Target ~20–25 scenarios (currently exactly 25). |
qa-regression | Secondary coverage, run on demand. |
qa-acceptance | Feature-launch acceptance (lives on the Product team, not QA). |
qa-blocker | Currently failing → blocks next release. |
| Surface | web, mobile, worker, shared — native scenarios additionally carry mobile-user (ios-user + android/app-user) and/or mobile-agent (ios-agent + android/app-agent) for per-app run filtering |
| Area (one per scenario) | auth, listings, leads, tours, search, ai, i18n, billing, chat, notifications, teams, engagement, profile, agents-directory, images, platform (rental exists but is dormant while Rental Companion is deferred) |
Cadence
Section titled “Cadence”- Phase 1 — Pre-PRD launch (current): comprehensive. Run the Pre-PRD Coverage Library continuously as features land (rebuilt Aug 2026:
QA-1…QA-109— 3 setup issues + 106 scenarios, 25 smoke). - Phase 2 — Post-PRD launch: duplicate the
qa-smokesubset into aQA — Release vX.Yproject per release. The regression library runs on demand (e.g., before a risky migration).
Bug discipline
Section titled “Bug discipline”Every bug issue must include:
- Repro section — exact steps + environment + test account.
- A link to the failing QA scenario if one exists. If not, create one in the QA team before closing.
- A “Verified fixed” comment from a tester before the bug moves to
Done.
A bug is not Done until the matching QA scenario passes again.
Adding a new scenario
Section titled “Adding a new scenario”- In the Linear QA team, create an issue in the QA — Pre-PRD Coverage Library project using the template.
- Apply
qa+ surface + exactly one area label (native scenarios also getmobile-userand/ormobile-agent). - Apply
qa-smokeonly if the scenario is critical-path (sign-up, publish listing, payment, etc.). - Run it once against the current build; record the result in
Last run.
Promoting / demoting smoke
Section titled “Promoting / demoting smoke”A scenario earns qa-smoke after it catches a real regression in production. Scenarios that haven’t caught anything in N consecutive releases drop back to qa-regression.
This keeps the smoke set reflective of where production actually breaks, not where we thought it would.
Test data
Section titled “Test data”The roster is provisioned through the real UI by the three SETUP issues at the top of the library (QA-1 account roster, QA-2 baseline listings, QA-3 team fixture) — there is no DB seeder. Email convention: plus-addressing on one controlled inbox (meouchi.jp+<handle>@gmail.com) so Resend OTPs are readable.
| Account / fixture | Purpose |
|---|---|
qa-admin | ADMIN role — /dashboard/admin/* pages, Bull Board runs |
qa-agent-smoke | Primary agent (PREMIUM via admin grant, non-trial); owner of QA-L1…L6; LEAD of QA Realty |
qa-agent-2 / qa-agent-3 | QA Realty MEMBER / team-ADMIN — invites, permissions, SLA escalation tiers |
qa-agent-free | AGENT FREE, team-less — the FREE/upsell side of the plan gates + the native planGate envelope (the team-seats gate runs on QA Realty; the staging-quota/refund gate on qa-agent-smoke) |
qa-customer-smoke / qa-customer-2 | Primary customer / second participant (qa-customer-2 runs in Spanish) |
qa-homeowner | Dual-role with zero dashboard listings — the portal↔dashboard visibility-leak fixture |
| QA-L1…L6 | Baseline listings: single-unit · multi-unit · price-drop (backdated) · hidden-location · <80% DRAFT · RENT with full media |
QA Realty | Team fixture: SLA 30 min + 3-tier chain, branding, 3 members |
| Devices | 1× iOS 17+ and 1× Android API 26+ dev builds, push-capable |
| Full DB reset | cd packages/database && bun run db:reset (see Conventions → Monorepo) — drop + rerun the Kysely migration chain, then flush Valkey |
Record the exact ids (listing ids, team id) inside the SETUP issues once provisioned.
When QA gets too heavy
Section titled “When QA gets too heavy”If the QA team passes >50 scenarios per release, or you have multiple parallel testers running the same suite, graduate the QA library to Qase (Linear-integrated test management). Until then, Linear is enough.
Running tests locally
Section titled “Running tests locally”Web E2E — Playwright
Section titled “Web E2E — Playwright”From apps/svelte-web/:
bun run test:e2e # equivalent: bun run testFixtures live in apps/svelte-web/e2e/. The runner reads three env vars — see Settings → Environment variables for the canonical list:
E2E_TEST_USER_EMAILE2E_TEST_USER_PASSWORDPLAYWRIGHT_BASE_URL(defaults tohttp://localhost:5173)
The dev server must be reachable at PLAYWRIGHT_BASE_URL before the suite starts — either keep bun run dev running in a second terminal, or extend playwright.config.ts’s webServer block to boot it on demand.
Unit — Bun Test
Section titled “Unit — Bun Test”From the repo root:
bun test # one-shotbun test --watch # watch modebun test --coverage # with coverageThe repo-root package.json exposes these as test, test:watch, test:coverage scripts. Bun’s runner discovers *.test.ts files across the workspace automatically — no per-package configuration is needed.
Tests in CI
Section titled “Tests in CI”CI runs unit tests across packages/, apps/api, apps/worker, and apps/svelte-web/src, but no e2e stage. One change-aware workflow selects the relevant quality, test, web-build, native-drift, Android, and iOS jobs for every PR into development and every development push; deploys are handled separately by Dokploy’s GitHub App. Playwright E2E is an author-side gate: run it locally before pushing.
| Workflow | Job | Runs on |
|---|---|---|
ci.yml | quality, tests/invariants, web build, Core drift, Android/iOS matrices, final CI gate | change-selected PRs + development pushes |
_ios-check.yml / _android-check.yml | reusable native build implementations called by ci.yml | only affected apps |
knock.yml | Development sync and manual commit-specific promotion | Knock changes / manual dispatch |
See Deployment → CI/CD for the full pipeline shape. If a test job is added to the workflows later, surface it here and in the Deployment page.