| name | windows-git-bash-testing |
| description | Windows and Git Bash testing compatibility for Vitest, Playwright, and MSW. PROACTIVELY activate for: (1) Vitest tests failing on Windows but passing on Linux, (2) Playwright on Windows with Git Bash quirks, (3) MSW intercept issues across shells, (4) path normalization in test fixtures, (5) browser binaries on Windows (Playwright install), (6) line-ending issues in test snapshots (CRLF vs LF), (7) cross-platform test scripts in package.json, (8) shell detection in pretest/posttest hooks, (9) CI-on-Windows debugging. Provides: cross-platform package.json scripts, snapshot normalization, Playwright Windows install, MSW shell-aware setup, and CI Windows debugging recipes. |
Windows and Git Bash Testing Compatibility Guide
Overview
This guide provides essential knowledge for running Vitest, Playwright, and MSW tests on Windows, particularly in Git Bash/MINGW environments. It addresses common path conversion issues, shell detection, and cross-platform test execution patterns.
Shell Detection in Test Environments
Detecting Git Bash/MINGW
When running tests in Git Bash or MINGW environments, use these detection methods:
Method 1: Environment Variable (Most Reliable)
function isGitBash() {
return !!(process.env.MSYSTEM);
}
function isWindows() {
return process.platform === 'win32';
}
function needsPathConversion() {
return isWindows() && isGitBash();
}
Method 2: Using uname in Setup Scripts
case "$(uname -s)" in
MINGW64*|MINGW32*|MSYS_NT*)
export TEST_ENV="mingw"
;;
CYGWIN*)
export TEST_ENV="cygwin"
;;
Linux*)
export TEST_ENV="linux"
;;
Darwin*)
export TEST_ENV="macos"
;;
esac
Method 3: Combined Detection for Test Configuration
import { execSync } from 'child_process';
function detectShell() {
if (process.env.MSYSTEM) {
return { type: 'mingw', subsystem: process.env.MSYSTEM };
}
try {
const uname = execSync('uname -s', { encoding: 'utf8' }).trim();
if (uname.startsWith('MINGW')) return { type: 'mingw' };
if (uname.startsWith('CYGWIN')) return { type: 'cygwin' };
if (uname === 'Darwin') return { type: 'macos' };
if (uname === 'Linux') return { type: 'linux' };
} catch {
}
return { type: , : process. };
}
shell = ();
.(, shell.);
Path Conversion Issues and Solutions
Common Path Conversion Problems
Git Bash automatically converts Unix-style paths to Windows paths, which can cause issues with test file paths, module imports, and test configuration.
Problem Examples:
/foo → C:/Program Files/Git/usr/foo
/foo:/bar → C:\msys64\foo;C:\msys64\bar
--dir=/foo → --dir=C:/msys64/foo
Solution 1: Disable Path Conversion
For test commands where path conversion causes issues:
MSYS_NO_PATHCONV=1 vitest run
export MSYS2_ARG_CONV_EXCL="--coverage.reporter"
vitest run --coverage.reporter=html
export MSYS_NO_PATHCONV=1
npm test
Solution 2: Use Native Windows Paths in Configuration
When specifying test file paths in configuration, use Windows-style paths:
export default defineConfig({
test: {
include: [
'tests/unit/**/*.test.js',
'tests/integration/**/*.test.js'
],
setupFiles: ['./tests/setup.js'],
coverage: {
reportsDirectory: './coverage'
}
}
});
Solution 3: Path Conversion Helper for Test Utilities
Create a helper for converting paths in test utilities:
import { execSync } from 'child_process';
export function toUnixPath(windowsPath) {
if (!needsPathConversion()) return windowsPath;
try {
return execSync(`cygpath -u "${windowsPath}"`, {
encoding: 'utf8'
}).trim();
} catch {
return windowsPath
.replace(/\\/g, '/')
.replace(/^([A-Z]):/, (_, drive) => `/${drive.toLowerCase()}`);
}
}
export function toWindowsPath(unixPath) {
if (!needsPathConversion()) return unixPath;
try {
return execSync(`cygpath -w "${unixPath}"`, {
encoding:
}).();
} {
unixPath
.(, )
.(, );
}
}
() {
!!(process.. ||
(process. === && process.. === ));
}
Usage in Tests:
import { toUnixPath, toWindowsPath } from '../helpers/paths.js';
test('loads config file', () => {
const configPath = toWindowsPath('/c/project/config.json');
const config = loadConfig(configPath);
expect(config).toBeDefined();
});
Test Execution Best Practices for Windows/Git Bash
1. NPM Scripts for Cross-Platform Compatibility
Define test scripts in package.json that work across all environments:
{
"scripts": {
"test": "vitest run",
"test:unit": "vitest run tests/unit",
"test:integration": "vitest run tests/integration",
"test:watch": "vitest watch",
"test:coverage": "vitest run --coverage",
"test:e2e": "playwright test",
"test:e2e:headed": "playwright test --headed",
"test:debug": "vitest run --reporter=verbose"
}
}
Always use npm scripts rather than direct vitest/playwright commands - this ensures consistent behavior across shells.
2. Relative Path Imports
Use relative paths in test files to avoid path conversion issues:
import { myFunction } from '../../src/utils.js';
import { server } from '../mocks/server.js';
import { myFunction } from '/c/project/src/utils.js';
3. Test File Discovery
Vitest and Playwright handle file patterns differently in Git Bash:
export default defineConfig({
test: {
include: ['tests/**/*.test.js', 'src/**/*.test.js'],
include: ['/c/project/tests/**/*.test.js']
}
});
export default defineConfig({
testDir: './tests/e2e',
testDir: '/c/project/tests/e2e'
});
4. Temporary File Handling
Git Bash uses Unix-style temp directories, which can cause issues:
import os from 'os';
import path from 'path';
function getTempDir() {
const tmpdir = os.tmpdir();
if (process.env.MSYSTEM && !tmpdir.startsWith('/')) {
return tmpdir.replace(/\\/g, '/');
}
return tmpdir;
}
const testTempDir = path.join(getTempDir(), 'my-tests');
Playwright-Specific Windows/Git Bash Considerations
1. Browser Installation in Git Bash
npx playwright install
2. Headed Mode in MINGW
When running headed tests in Git Bash, ensure DISPLAY variables are not set:
unset DISPLAY
npx playwright test --headed
3. Screenshot and Video Paths
Use relative paths for artifacts:
export default defineConfig({
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
outputDir: './test-results',
});
MSW (Mock Service Worker) in Git Bash
MSW generally works without issues in Git Bash, but be aware of:
1. Handler File Imports
Use relative imports in MSW setup:
import { handlers } from './handlers.js';
import { handlers } from '/c/project/tests/mocks/handlers.js';
2. Fetch Polyfill (Node.js)
Ensure Node.js version 18+ for native Fetch API support:
node --version
Common Windows/Git Bash Test Errors and Fixes
Error 1: "No such file or directory" in Git Bash
Symptom:
Error: /usr/bin/bash: line 1: C:UsersUsername...No such file
Cause: Path conversion issue, often with temp directories.
Fix:
MSYS_NO_PATHCONV=1 npm test
export CLAUDE_CODE_GIT_BASH_PATH="C:\\Program Files\\git\\bin\\bash.exe"
npm test
Error 2: Module Import Failures
Symptom:
Error: Cannot find module '../src/utils'
Cause: Path separator confusion (backslash vs forward slash).
Fix:
import path from 'path';
const utilsPath = path.resolve(__dirname, '../src/utils.js');
const utils = await import(utilsPath);
Error 3: Playwright Browser Launch Failure
Symptom:
Error: Failed to launch browser
Cause: Git Bash environment variables interfering with browser launch.
Fix:
unset DISPLAY
unset BROWSER
npx playwright test
Error 4: Coverage Report Path Issues
Symptom:
Error: Failed to write coverage to /c/project/coverage
Fix:
export default defineConfig({
test: {
coverage: {
reportsDirectory: './coverage',
reportsDirectory: '/c/project/coverage'
}
}
});
Testing Strategy for Multi-Platform Support
1. CI/CD Configuration
Test on multiple platforms in CI/CD:
name: Tests
on: [push, pull_request]
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [18, 20, 22]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm test
- run: npm run test:e2e
if: matrix.os == 'ubuntu-latest'
2. Shell-Specific Test Setup
Create shell-specific setup if needed:
import { detectShell } from './helpers/shell-detect.js';
const shell = detectShell();
if (shell.type === 'mingw') {
console.log('Running in Git Bash/MINGW environment');
process.env.FORCE_COLOR = '1';
}
3. Path-Safe Test Utilities
Create test utilities that work across all platforms:
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
export function getCurrentDir(importMetaUrl) {
return dirname(fileURLToPath(importMetaUrl));
}
export function testPath(...segments) {
return path.join(...segments).replace(/\\/g, '/');
}
Quick Reference
Shell Detection Commands
echo $MSYSTEM
uname -s
node -p process.platform
Path Conversion Quick Fixes
MSYS_NO_PATHCONV=1 vitest run
export MSYS_NO_PATHCONV=1
cygpath -u "C:\path"
cygpath -w "/c/path"
Recommended Test Execution (Git Bash on Windows)
npm test
npm run test:e2e
MSYS_NO_PATHCONV=1 vitest run
vitest run
Resources
Summary
When running tests on Windows with Git Bash:
- Use npm scripts for all test execution (most reliable)
- Use relative paths in configuration and imports
- Detect shell environment when needed for conditional setup
- Disable path conversion (MSYS_NO_PATHCONV=1) if issues occur
- Test on multiple platforms in CI/CD to catch platform-specific issues
- Avoid absolute paths starting with /c/ or C:\ in test files
- Use path.join() for programmatic path construction
Following these practices ensures tests run reliably across Windows Command Prompt, PowerShell, Git Bash, and Unix-like environments.