e2e/README.md
This directory contains end-to-end (e2e) tests for Lerna-Lite, inspired by Lerna's e2e test infrastructure but adapted for Vitest.
E2E tests verify the complete functionality of Lerna-Lite commands by:
All tests run automatically in CI with Verdaccio.
Fixture Class (e2e-utils/src/fixture.ts)
Utility Functions (e2e-utils/src/utils.ts)
getE2eRoot() - Sets up the temporary e2e directorynormalizeEnvironment() - Normalizes paths and timestamps for snapshotsnormalizeCommandOutput() - Prepares command output for assertionsnormalizeCommitSHAs() - Replaces git SHAs for consistent snapshotsTest Configuration (e2e/vitest.config.ts)
e2e/
├── vitest.config.ts # Vitest configuration for e2e tests
├── setup.ts # Global test setup
├── tsconfig.json # TypeScript config for e2e tests
├── changed/ # E2E tests for changed command
│ └── changed.spec.ts
├── diff/ # E2E tests for diff command
│ └── diff.spec.ts
├── exec/ # E2E tests for exec command
│ └── exec.spec.ts
├── list/ # E2E tests for list command
└── list.spec.ts
├── publish/ # E2E tests for publish command
│ ├── publish-dry-run.spec.ts
│ ├── publish-npmrc-auth.spec.ts
│ └── publish-verdaccio.spec.ts
├── run/ # E2E tests for run command
│ └── run.spec.ts
├── version/ # E2E tests for version command
│ └── version.spec.ts
└── watch/ # E2E tests for watch command
└── watch.spec.ts
e2e-utils/
├── src/
│ ├── fixture.ts # Main Fixture class
│ ├── utils.ts # Utility functions
│ └── index.ts # Exports
├── package.json
└── tsconfig.json
pnpm test:e2e
This will:
pnpm test:e2e:watch
# Run only publish tests
vitest run --config ./e2e/vitest.config.ts e2e/publish
# Run only version tests
vitest run --config ./e2e/vitest.config.ts e2e/version
Enable debug mode to keep test fixtures and see detailed logs:
export LERNA_E2E_DEBUG=true # Linux/macOS
# or
$env:LERNA_E2E_DEBUG = "true" # PowerShell
pnpm test:e2e
This will:
debug.log in each fixture directoryTest fixtures are created in:
%TEMP%\lerna-lite-e2e/tmp/lerna-lite-e2eimport { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { Fixture } from '../../e2e-utils/src/index.js';
describe('my-feature', () => {
let fixture: Fixture;
beforeAll(async () => {
fixture = await Fixture.create({
e2eRoot: process.env.E2E_ROOT!,
name: 'my-feature-test',
packageManager: 'npm',
initializeGit: true,
lernaInit: true,
installDependencies: false,
});
});
afterAll(async () => {
await fixture.destroy();
});
it('should do something', async () => {
// Create packages
await fixture.createPackage({ name: 'my-package' });
// Run lerna commands
const output = await fixture.lerna('list');
// Make assertions
expect(output.combinedOutput).toContain('my-package');
});
});
// Create a new package
await fixture.createPackage({ name: 'package-name' });
// Execute arbitrary commands
await fixture.exec('git add .');
await fixture.exec('git commit -m "test"');
// Update package.json
await fixture.updateJson('packages/my-pkg/package.json', (json) => ({
...json,
version: '1.0.0',
}));
// Add scripts to a package
await fixture.addScriptsToPackage({
packagePath: 'packages/my-pkg',
scripts: {
'build': 'echo building',
},
});
// Create initial git commit
await fixture.createInitialGitCommit();
// Read files
const content = await fixture.readWorkspaceFile('package.json');
// Get workspace path
const path = fixture.getWorkspacePath('packages/my-pkg');
it('should publish to verdaccio', async () => {
await fixture.createPackage({ name: 'test-pkg', version: '1.0.0' });
await fixture.createInitialGitCommit();
await fixture.exec('git tag [email protected] -m "[email protected]"');
// Configure npm to use Verdaccio
await fixture.exec('echo "registry=http://localhost:4873/" > .npmrc');
const output = await fixture.lerna(
'publish from-git --registry=http://localhost:4873/ -y'
);
expect(output.combinedOutput).toContain('Successfully published');
});
import { normalizeEnvironment, normalizeCommandOutput, normalizeCommitSHAs } from '../../e2e-utils/src/index.js';
it('should match snapshot', async () => {
const output = await fixture.lerna('list');
expect(
normalizeCommandOutput(output.combinedOutput)
).toMatchSnapshot();
});
If tests timeout, the default timeout is 2 minutes per test. For slower systems, you can increase the timeout in e2e/vitest.config.ts.
If fixtures aren't being cleaned up properly:
# Linux/macOS
rm -rf /tmp/lerna-lite-e2e
# Windows PowerShell
Remove-Item -Recurse -Force "$env:TEMP\lerna-lite-e2e"
E2E tests are designed to run in CI environments and will automatically:
Example GitHub Actions workflow:
- name: Run E2E Tests
run: pnpm test:e2e
env:
CI: true
When adding new E2E tests:
e2e/ for the command being testedbeforeAll/afterAll for fixture setup/teardown