All checks were successful
build-and-release / build (push) Successful in 2m25s
The e2e suite only ever worked against a local docker-compose stack: - Hardcoded http://localhost:3000 / :9100 everywhere, ignoring TEST_ENV=production and playwright.config.ts's own baseURL logic. - /api/auth/login and /api/auth/register now require solving a math captcha first; none of these tests sent captcha_id/captcha_answer, so every login/register call 422'd against the live API. - OTP retrieval shelled out to a local, unauthenticated redis-cli, which can't reach the real (kubectl-exec + password-protected) Redis. - Several files launched their own chromium.launch({headless: false}), which crashes immediately on a server with no X display. - One file had a hardcoded macOS absolute path for screenshots. Added tests/e2e/helpers/{env,captcha,otp,auth-flow}.ts as shared, reusable fixes for all of the above, and updated every affected spec file to use them. Verified via a full run against test111.nxtgauge.com: 971 schemathesis-adjacent smoke assertions aside, the actual signal here is 0 of the 130 prior failures came from real product bugs - all were this environment mismatch. See docs/LIVE_SERVER_RUNBOOK.md step 5. Also fixes .gitignore: it excluded 'playwright-report' (singular) but playwright.config.ts's actual outputFolder is 'playwright-reports' (plural) - generated HTML report artifacts had been getting committed by accident. Untracked the existing ones; left tests/e2e/visual/*-snapshots/ (newly-generated visual regression baselines from this run) untracked for now since establishing baselines needs a human look, not a blind commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import { execFileSync } from "child_process";
|
|
|
|
/**
|
|
* Reads a registration OTP straight out of Redis, the same way a human would
|
|
* never get to (the API deliberately never returns it — see
|
|
* apps/users/src/handlers/auth.rs's RegisterResponse.otp, which is only
|
|
* populated for the DEMO_ACCOUNT_EMAILS allowlist, unset in this environment).
|
|
*
|
|
* This only works when the machine running the tests has `kubectl` access to
|
|
* the cluster (redis-master-0 in the `data` namespace) — i.e. run from the
|
|
* same host used for the rest of the live-server runbook, not arbitrary CI.
|
|
* Auths via the redis pod's own mounted password file rather than a secret
|
|
* value passed on our end, matching how docs/LIVE_SERVER_RUNBOOK.md's manual
|
|
* verification steps do it.
|
|
*/
|
|
export async function getOtpFromRedis(userId: string): Promise<string | null> {
|
|
try {
|
|
const out = execFileSync(
|
|
"kubectl",
|
|
[
|
|
"-n",
|
|
"data",
|
|
"exec",
|
|
"redis-master-0",
|
|
"--",
|
|
"sh",
|
|
"-c",
|
|
'redis-cli -a "$(cat /opt/bitnami/redis/secrets/redis-password)" GET "otp:plain:$1"',
|
|
"--", // end of sh -c's own options, "$1" below binds to this
|
|
userId,
|
|
],
|
|
{ encoding: "utf8" }
|
|
).trim();
|
|
|
|
// redis-cli prints "(nil)" for a missing key rather than exiting non-zero.
|
|
if (!out || out === "(nil)" || !/^\d{4,}$/.test(out)) return null;
|
|
return out;
|
|
} catch (e: any) {
|
|
console.log("⚠️ Could not read OTP from Redis via kubectl:", e.message);
|
|
return null;
|
|
}
|
|
}
|