fix(setup): preserve overridden runner variables and test isolation on Windows
Support case-insensitive environment value lookup in ClientRegistrationIdentity while preserving JavaScript property order precedence with findLast(). Add unit regression coverage for ambient uppercase npm variables on Windows. Isolate USERPROFILE in cliSetup tests so child processes do not touch the host profile directory. Harden JSON decision extraction in runJourney against ConPTY trailing ANSI escape codes. Deterministically sequence multiselect prompt navigation before confirmation. Filter ambient runner variables case-insensitively before launching interactive setup completion tests.
This commit is contained in:
1 parent
93e75bc8fe
commit
2abfe53dbd
3 files changed
+32
-7
No files matched your search
@@ -13,8 +13,9 @@ const environmentValue = (
|
||||
platform: NodeJS.Platform,
|
||||
): string | undefined => {
|
||||
if (platform !== "win32") return environment[name];
|
||||
const key = Object.keys(environment).find(
|
||||
(candidate) => candidate.toLowerCase() === name,
|
||||
const target = name.toLowerCase();
|
||||
const key = Object.keys(environment).findLast(
|
||||
(candidate) => candidate.toLowerCase() === target,
|
||||
);
|
||||
return key === undefined ? undefined : environment[key];
|
||||
};
|
||||
|
||||
@@ -182,3 +182,12 @@ it.each([
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it("prioritizes overridden package runner environment variables over ambient keys with differing case on Windows", () => {
|
||||
const environment = {
|
||||
NPM_COMMAND: "run",
|
||||
npm_command: "exec",
|
||||
NPM_CONFIG_USER_AGENT: "npm/10.9.0 node/v24.11.0 win32 x64",
|
||||
};
|
||||
expect(invokingPackageRunner(environment, "win32")).toBe("npx");
|
||||
});
|
||||
@@ -179,7 +179,10 @@ describe("TTY setup dry run", () => {
|
||||
describe("interactive setup journey", () => {
|
||||
it("shows detected and absent clients without preselecting detected clients", async () => {
|
||||
const result = await runJourney(
|
||||
[step("Which agents should use REA?", "\u001b[B\r")],
|
||||
[
|
||||
step("Which agents should use REA?", "\u001b[B"),
|
||||
step("Not detected · configuration is still available", "\r"),
|
||||
],
|
||||
false,
|
||||
[actions[0]],
|
||||
);
|
||||
@@ -359,7 +362,14 @@ describe("interactive setup completion", () => {
|
||||
{
|
||||
cwd: process.cwd(),
|
||||
env: {
|
||||
...process.env,
|
||||
...Object.fromEntries(
|
||||
Object.entries(process.env).filter(
|
||||
([key]) =>
|
||||
!["npm_command", "npm_config_user_agent"].includes(
|
||||
key.toLowerCase(),
|
||||
),
|
||||
),
|
||||
),
|
||||
npm_command: npmCommand,
|
||||
npm_config_user_agent: userAgent,
|
||||
NO_COLOR: "1",
|
||||
@@ -427,6 +437,7 @@ const runJourney = async (
|
||||
env: {
|
||||
...process.env,
|
||||
HOME: isolatedHome,
|
||||
USERPROFILE: isolatedHome,
|
||||
NO_COLOR: "1",
|
||||
TERM: "xterm-256color",
|
||||
},
|
||||
@@ -464,9 +475,13 @@ const runJourney = async (
|
||||
finish(new Error(`Setup journey returned no decision:\n${output}`));
|
||||
return;
|
||||
}
|
||||
const serialized = output
|
||||
.slice(markerIndex + decisionMarker.length)
|
||||
.split(/\r?\n/u, 1)[0];
|
||||
const raw = output.slice(markerIndex + decisionMarker.length);
|
||||
const jsonStart = raw.indexOf("{");
|
||||
const jsonEnd = raw.lastIndexOf("}");
|
||||
const serialized =
|
||||
jsonStart !== -1 && jsonEnd !== -1 && jsonEnd > jsonStart
|
||||
? raw.slice(jsonStart, jsonEnd + 1)
|
||||
: raw.split(/\r?\n/u, 1)[0];
|
||||
if (serialized === undefined) {
|
||||
finish(
|
||||
new Error(`Setup journey returned an empty decision:\n${output}`),
|
||||
|
||||
Reference in new issue
Block a user