Skip to content

Commit 7016e34

Browse files
authored
fix(tools): handle mixed-separator cwd on Windows in snap test output replacement (#707)
On Windows, cwd built with template literals has mixed separators (e.g., `C:\Users\...\Temp/test-name`) while Vite's error messages use all-backslash paths from path.resolve(). The cwd replacement in replaceUnstableOutput() failed to match, leaking full temp paths into snap test output. Fix by also trying the all-backslash form of cwd (and its parent) for replacement, with trailing-separator handling to normalize the path separator after the `<cwd>` placeholder.
1 parent 29c41a6 commit 7016e34

2 files changed

Lines changed: 48 additions & 3 deletions

File tree

packages/tools/src/__tests__/utils.spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,38 @@ Done in 171ms using pnpm v10.16.1
101101
expect(replaceUnstableOutput(output.trim(), cwd)).toMatchSnapshot();
102102
});
103103

104+
describe.skipIf(process.platform !== 'win32')('Windows cwd replacement', () => {
105+
test('mixed-separator cwd matches all-backslash output', () => {
106+
// Simulates the CI failure: cwd has mixed separators (template literal),
107+
// but Vite outputs all-backslash paths (path.resolve)
108+
const cwd =
109+
'C:\\Users\\RUNNER~1\\AppData\\Local\\Temp/vite-plus-test-abc/command-staged-broken-config';
110+
const output =
111+
'failed to load config from C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\vite-plus-test-abc\\command-staged-broken-config\\vite.config.ts';
112+
expect(replaceUnstableOutput(output, cwd)).toBe(
113+
'failed to load config from <cwd>/vite.config.ts',
114+
);
115+
});
116+
117+
test('all-backslash cwd matches all-backslash output', () => {
118+
const cwd = 'C:\\Users\\runner\\project';
119+
const output = 'error in C:\\Users\\runner\\project\\src\\main.ts';
120+
expect(replaceUnstableOutput(output, cwd)).toBe('error in <cwd>/src/main.ts');
121+
});
122+
123+
test('cwd at end of string without trailing separator', () => {
124+
const cwd = 'C:\\Users\\runner\\project';
125+
const output = 'path is C:\\Users\\runner\\project';
126+
expect(replaceUnstableOutput(output, cwd)).toBe('path is <cwd>');
127+
});
128+
129+
test('parent directory replacement with backslash paths', () => {
130+
const cwd = 'C:\\Users\\RUNNER~1\\Temp/vite-plus-test/my-test';
131+
const output = 'found C:\\Users\\RUNNER~1\\Temp\\vite-plus-test\\other\\file.ts';
132+
expect(replaceUnstableOutput(output, cwd)).toBe('found <cwd>/../other/file.ts');
133+
});
134+
});
135+
104136
test('replace tsdown output', () => {
105137
const output = `
106138
ℹ tsdown v0.15.1 powered by rolldown v0.15.1

packages/tools/src/utils.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,22 @@ export function replaceUnstableOutput(output: string, cwd?: string) {
1414
output = output.replaceAll(ANSI_ESCAPE_REGEX, '').replaceAll(/\r\n/g, '\n').replaceAll(/\r/g, '');
1515

1616
if (cwd) {
17-
output = output.replaceAll(cwd, '<cwd>');
18-
if (path.dirname(cwd) !== '/') {
19-
output = output.replaceAll(path.dirname(cwd), '<cwd>/..');
17+
// On Windows, cwd may have mixed separators (from template literals like `${tmp}/name`)
18+
// while output uses all-backslash paths (from path.resolve()). Replace the all-backslash
19+
// form of each path token, with trailing separator first so the separator after the
20+
// placeholder is normalized to forward slash.
21+
const replacePathToken = (rawPath: string, placeholder: string) => {
22+
if (process.platform === 'win32') {
23+
const backslash = rawPath.replaceAll('/', '\\');
24+
output = output.replaceAll(backslash + '\\', placeholder + '/');
25+
output = output.replaceAll(backslash, placeholder);
26+
}
27+
output = output.replaceAll(rawPath, placeholder);
28+
};
29+
replacePathToken(cwd, '<cwd>');
30+
const parent = path.dirname(cwd);
31+
if (parent !== '/') {
32+
replacePathToken(parent, '<cwd>/..');
2033
}
2134
}
2235
// On Windows, normalize path separators in file paths for consistent snapshots.

0 commit comments

Comments
 (0)