Skip to content

Commit

Permalink
chore(testing): add lerna-smoke-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesHenry committed Jan 13, 2023
1 parent abfa864 commit 3952d8f
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 0 deletions.
11 changes: 11 additions & 0 deletions e2e/lerna-smoke-tests/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable */
export default {
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
displayName: 'e2e-lerna-smoke-tests',
preset: '../../jest.preset.js',
};
11 changes: 11 additions & 0 deletions e2e/lerna-smoke-tests/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "e2e-lerna-smoke-tests",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "e2e/lerna-smoke-tests",
"projectType": "application",
"targets": {
"e2e": {},
"run-e2e-tests": {}
},
"implicitDependencies": ["nx", "devkit"]
}
58 changes: 58 additions & 0 deletions e2e/lerna-smoke-tests/src/lerna-smoke-tests.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {
cleanupProject,
newLernaWorkspace,
runLernaCLI,
updateJson,
} from '@nrwl/e2e/utils';

/**
* These minimal smoke tests are here to ensure that we do not break assumptions on the lerna side
* when making updates to nx or @nrwl/devkit.
*/
describe('Lerna Smoke Tests', () => {
beforeAll(() => newLernaWorkspace());
afterAll(() => cleanupProject());

// `lerna repair` builds on top of `nx repair` and runs all of its generators
describe('lerna repair', () => {
// If this snapshot fails it means that nx repair generators are making assumptions which don't hold true for lerna workspaces
it('should complete successfully on a new lerna workspace', async () => {
expect(runLernaCLI(`repair`)).toMatchInlineSnapshot(`
"
> Lerna No changes were necessary. This workspace is up to date!
"
`);
}, 1000000);
});

// `lerna run` delegates to the nx task runner behind the scenes
describe('lerna run', () => {
it('should complete successfully on a new lerna workspace', async () => {
runLernaCLI('create package-1 -y');
updateJson('packages/package-1/package.json', (json) => ({
...json,
scripts: {
...(json.scripts || {}),
'print-name': 'echo test-package-1',
},
}));

expect(runLernaCLI(`run print-name`)).toMatchInlineSnapshot(`
"
> package-1:print-name
> package-1@0.0.0 print-name
> echo test-package-1
test-package-1
> Lerna (powered by Nx) Successfully ran target print-name for project package-1
"
`);
}, 1000000);
});
});
13 changes: 13 additions & 0 deletions e2e/lerna-smoke-tests/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node", "jest"]
},
"include": [],
"files": [],
"references": [
{
"path": "./tsconfig.spec.json"
}
]
}
20 changes: 20 additions & 0 deletions e2e/lerna-smoke-tests/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.test.ts",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"**/*.d.ts",
"jest.config.ts"
]
}
114 changes: 114 additions & 0 deletions e2e/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,68 @@ export function newProject({
}
}

export function newLernaWorkspace({
name = uniq('lerna-proj'),
packageManager = getSelectedPackageManager(),
} = {}): string {
try {
const projScope = name;
projName = name;

const pm = getPackageManagerCommand({ packageManager });

createNonNxProjectDirectory(projScope);

if (process.env.NX_VERBOSE_LOGGING == 'true') {
logInfo(`NX`, `E2E test has created a lerna workspace: ${tmpProjPath()}`);
}

// We need to force the real latest version of lerna to depend on our locally published version of nx
// TODO: translate this for yarn and pnpm
updateJson(`package.json`, (json) => {
const nxVersion = getPublishedVersion();
json.overrides = {
...json.overrides,
nx: nxVersion,
'@nrwl/devkit': nxVersion,
};
return json;
});

/**
* Again, in order to ensure we override the required version relationships, we first install lerna as a devDep
* before running `lerna init`.
*/
packageInstall('lerna', projScope, getLatestLernaVersion(), 'dev');
execSync(pm.lernaInit, {
cwd: tmpProjPath(),
stdio: isVerbose() ? 'inherit' : 'pipe',
env: { CI: 'true', ...process.env },
encoding: 'utf-8',
});

// Temporary hack to prevent installing with `--frozen-lockfile`
if (isCI && packageManager === 'pnpm') {
updateFile(
'.npmrc',
'prefer-frozen-lockfile=false\nstrict-peer-dependencies=false\nauto-install-peers=true'
);
}

execSync(pm.install, {
cwd: tmpProjPath(),
stdio: isVerbose() ? 'inherit' : 'pipe',
env: { CI: 'true', ...process.env },
encoding: 'utf-8',
});

return projScope;
} catch (e) {
logError(`Failed to set up lerna workspace for e2e tests.`, e.message);
throw e;
}
}

const KILL_PORT_DELAY = 5000;

export async function killPort(port: number): Promise<boolean> {
Expand Down Expand Up @@ -629,6 +691,42 @@ export function runCLI(
}
}

export function runLernaCLI(
command: string,
opts: RunCmdOpts = {
silenceError: false,
env: undefined,
}
): string {
try {
const pm = getPackageManagerCommand();
const logs = execSync(`${pm.runLerna} ${command}`, {
cwd: opts.cwd || tmpProjPath(),
env: { CI: 'true', ...(opts.env || getStrippedEnvironmentVariables()) },
encoding: 'utf-8',
stdio: 'pipe',
maxBuffer: 50 * 1024 * 1024,
});
const r = stripConsoleColors(logs);

if (isVerbose()) {
console.log(logs);
}

return r;
} catch (e) {
if (opts.silenceError) {
return stripConsoleColors(e.stdout?.toString() + e.stderr?.toString());
} else {
logError(
`Original command: ${command}`,
`${e.stdout?.toString()}\n\n${e.stderr?.toString()}`
);
throw e;
}
}
}

/**
* Remove log colors for fail proof string search
* @param log
Expand Down Expand Up @@ -882,9 +980,12 @@ export function getPackageManagerCommand({
addProd: string;
addDev: string;
list: string;
lernaInit: string;
runLerna: string;
} {
const npmMajorVersion = getNpmMajorVersion();
const publishedVersion = getPublishedVersion();
const latestLernaVersion = getLatestLernaVersion();

return {
npm: {
Expand All @@ -899,6 +1000,10 @@ export function getPackageManagerCommand({
addProd: `npm install --legacy-peer-deps`,
addDev: `npm install --legacy-peer-deps -D`,
list: 'npm ls --depth 10',
lernaInit: `npx ${
+npmMajorVersion >= 7 ? '--yes' : ''
} lerna@${latestLernaVersion} init`,
runLerna: `npx lerna`,
},
yarn: {
// `yarn create nx-workspace` is failing due to wrong global path
Expand All @@ -911,6 +1016,8 @@ export function getPackageManagerCommand({
addProd: `yarn add`,
addDev: `yarn add -D`,
list: 'npm ls --depth 10',
lernaInit: `yarn global add lerna@${latestLernaVersion} && lerna init`,
runLerna: `yarn lerna`,
},
// Pnpm 3.5+ adds nx to
pnpm: {
Expand All @@ -923,6 +1030,8 @@ export function getPackageManagerCommand({
addProd: `pnpm add`,
addDev: `pnpm add -D`,
list: 'npm ls --depth 10',
lernaInit: `pnpm dlx lerna@${latestLernaVersion} init`,
runLerna: `pnpm exec lerna`,
},
}[packageManager.trim() as PackageManager];
}
Expand All @@ -932,6 +1041,11 @@ function getNpmMajorVersion(): string {
return npmMajorVersion;
}

function getLatestLernaVersion(): string {
const lernaVersion = execSync(`npm view lerna version`).toString().trim();
return lernaVersion;
}

export const packageManagerLockFile = {
npm: 'package-lock.json',
yarn: 'yarn.lock',
Expand Down

0 comments on commit 3952d8f

Please sign in to comment.