test(reset-password): fix runResetPasswordCli deadlock vs the #6387 non-TTY CLI (CI shard-4 wedge)

#6387 (register reset-password subcommand + non-TTY stdin path) made bin/reset-password.mjs
read a piped (non-TTY) stdin all at once — first line is the password — and stop printing
the interactive 'Enter new password' / 'Confirm new password' prompts. The unchanged test
helper only wrote the password after SEEING those prompts and only closed stdin after the
confirm prompt, so against the non-TTY CLI it never fed input nor closed stdin: the child
blocked forever on stdin-end and the whole unit shard wedged at the 25min CI timeout
(cancelled 3x). Feed the password + child.stdin.end() immediately, matching the non-TTY
contract. Now deterministic: 3/3 pass locally in ~7s (no skip, real CLI run).
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-07 11:56:32 -03:00
parent c096464a33
commit 6f1aa2bb3f

View File

@@ -29,31 +29,23 @@ async function runResetPasswordCli(password: string) {
let stdout = "";
let stderr = "";
let answeredPassword = false;
let answeredConfirmation = false;
const answerPrompts = () => {
if (!answeredPassword && stdout.includes("Enter new password")) {
child.stdin.write(`${password}\n`);
answeredPassword = true;
}
if (answeredPassword && !answeredConfirmation && stdout.includes("Confirm new password")) {
child.stdin.write(`${password}\n`);
child.stdin.end();
answeredConfirmation = true;
}
};
child.stdout.setEncoding("utf8");
child.stderr.setEncoding("utf8");
child.stdout.on("data", (chunk) => {
stdout += chunk;
answerPrompts();
});
child.stderr.on("data", (chunk) => {
stderr += chunk;
});
// #6387: the CLI now reads a piped (non-TTY) stdin all at once — the first line is the
// password — instead of the old two interactive `Enter new password` / `Confirm new
// password` prompts. Feed the password and close stdin immediately; waiting for prompts
// the non-TTY path never prints deadlocks the child (was the v3.8.46 CI shard-4 wedge).
child.stdin.write(`${password}\n`);
child.stdin.end();
const code = await new Promise<number | null>((resolve, reject) => {
child.on("error", reject);
child.on("close", resolve);