fix(node): Enable e2e test (#23508)
Re-enables e2e tests for node Docker changes to be merged first: https://github.com/nrwl/nx/pull/26365
This commit is contained in:
parent
929a57c127
commit
295c4229db
29
e2e/node/src/__snapshots__/node-server.test.ts.snap
Normal file
29
e2e/node/src/__snapshots__/node-server.test.ts.snap
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Node Applications + webpack should generate a Dockerfile 1`] = `
|
||||||
|
"# This file is generated by Nx.
|
||||||
|
#
|
||||||
|
# Build the docker image with \`npx nx docker-build docker-express-app\`.
|
||||||
|
# Tip: Modify "docker-build" options in project.json to change docker build args.
|
||||||
|
#
|
||||||
|
# Run the container with \`docker run -p 3000:3000 -t docker-express-app\`.
|
||||||
|
FROM docker.io/node:lts-alpine
|
||||||
|
|
||||||
|
ENV HOST=0.0.0.0
|
||||||
|
ENV PORT=3000
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN addgroup --system docker-express-app && \\
|
||||||
|
adduser --system -G docker-express-app docker-express-app
|
||||||
|
|
||||||
|
COPY dist/apps/docker-express-app docker-express-app/
|
||||||
|
RUN chown -R docker-express-app:docker-express-app .
|
||||||
|
|
||||||
|
# You can remove this install step if you build with \`--bundle\` option.
|
||||||
|
# The bundled output will include external dependencies.
|
||||||
|
RUN npm --prefix docker-express-app --omit=dev -f install
|
||||||
|
|
||||||
|
CMD [ "node", "docker-express-app" ]
|
||||||
|
"
|
||||||
|
`;
|
||||||
@ -2,6 +2,7 @@ import {
|
|||||||
checkFilesDoNotExist,
|
checkFilesDoNotExist,
|
||||||
checkFilesExist,
|
checkFilesExist,
|
||||||
cleanupProject,
|
cleanupProject,
|
||||||
|
getSelectedPackageManager,
|
||||||
killPort,
|
killPort,
|
||||||
newProject,
|
newProject,
|
||||||
promisifiedTreeKill,
|
promisifiedTreeKill,
|
||||||
@ -14,11 +15,19 @@ import {
|
|||||||
} from '@nx/e2e/utils';
|
} from '@nx/e2e/utils';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
xdescribe('Node Applications + webpack', () => {
|
describe('Node Applications + webpack', () => {
|
||||||
let proj: string;
|
let proj: string;
|
||||||
|
const selectedPm = getSelectedPackageManager();
|
||||||
|
|
||||||
|
// TODO(nicholas): Look into how this can work with npm instead of forcing pnpm.
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
proj = newProject({
|
proj = newProject({
|
||||||
packages: ['@nx/node'],
|
packages: ['@nx/node'],
|
||||||
|
// npm has resolution for ajv some packages require ajv6 and some require ajv8 and npm resolves it to ajv6 (Error: Cannot find module 'ajv/dist/compile/codegen')
|
||||||
|
// - ajv@6 (fork-ts-checker-webpack-plugin, terser-webpack-plugin, webpack)
|
||||||
|
// - ajv@8 (babel-loader)
|
||||||
|
// Solution is to use pnpm or run fix it via npm ex.(npm dedupe --force)
|
||||||
|
packageManager: selectedPm === 'npm' ? 'pnpm' : selectedPm,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -47,10 +56,10 @@ xdescribe('Node Applications + webpack', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runE2eTests(appName: string) {
|
async function runE2eTests(appName: string, port: number = 5000) {
|
||||||
process.env.PORT = '5000';
|
process.env.PORT = `${port}`;
|
||||||
const childProcess = await runCommandUntil(`serve ${appName}`, (output) => {
|
const childProcess = await runCommandUntil(`serve ${appName}`, (output) => {
|
||||||
return output.includes('http://localhost:5000');
|
return output.includes(`http://localhost:${port}`);
|
||||||
});
|
});
|
||||||
const result = runCLI(`e2e ${appName}-e2e --verbose`);
|
const result = runCLI(`e2e ${appName}-e2e --verbose`);
|
||||||
expect(result).toContain('Setting up...');
|
expect(result).toContain('Setting up...');
|
||||||
@ -58,13 +67,11 @@ xdescribe('Node Applications + webpack', () => {
|
|||||||
expect(result).toContain('Successfully ran target e2e');
|
expect(result).toContain('Successfully ran target e2e');
|
||||||
|
|
||||||
await promisifiedTreeKill(childProcess.pid, 'SIGKILL');
|
await promisifiedTreeKill(childProcess.pid, 'SIGKILL');
|
||||||
await killPort(5000);
|
await killPort(port);
|
||||||
process.env.PORT = '';
|
process.env.PORT = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disabled due to flakiness of ajv disabled (Error: Cannot find module 'ajv/dist/compile/codegen')
|
describe('frameworks', () => {
|
||||||
// TODO: (nicholas) Re-enable when the flakiness is resolved
|
|
||||||
xit('should generate an app using webpack', async () => {
|
|
||||||
const testLib1 = uniq('test1');
|
const testLib1 = uniq('test1');
|
||||||
const testLib2 = uniq('test2');
|
const testLib2 = uniq('test2');
|
||||||
const expressApp = uniq('expressapp');
|
const expressApp = uniq('expressapp');
|
||||||
@ -72,79 +79,98 @@ xdescribe('Node Applications + webpack', () => {
|
|||||||
const koaApp = uniq('koaapp');
|
const koaApp = uniq('koaapp');
|
||||||
const nestApp = uniq('nest');
|
const nestApp = uniq('nest');
|
||||||
|
|
||||||
runCLI(`generate @nx/node:lib ${testLib1}`);
|
beforeAll(() => {
|
||||||
runCLI(`generate @nx/node:lib ${testLib2} --importPath=@acme/test2`);
|
runCLI(`generate @nx/node:lib ${testLib1}`);
|
||||||
runCLI(
|
runCLI(`generate @nx/node:lib ${testLib2} --importPath=@acme/test2`);
|
||||||
`generate @nx/node:app ${expressApp} --framework=express --no-interactive`
|
runCLI(
|
||||||
);
|
`generate @nx/node:app ${expressApp} --framework=express --port=7000 --no-interactive`
|
||||||
runCLI(
|
);
|
||||||
`generate @nx/node:app ${fastifyApp} --framework=fastify --no-interactive`
|
runCLI(
|
||||||
);
|
`generate @nx/node:app ${fastifyApp} --framework=fastify --port=7001 --no-interactive`
|
||||||
runCLI(`generate @nx/node:app ${koaApp} --framework=koa --no-interactive`);
|
);
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nx/node:app ${nestApp} --framework=nest --bundler=webpack --no-interactive`
|
`generate @nx/node:app ${koaApp} --framework=koa --port=7002 --no-interactive`
|
||||||
);
|
);
|
||||||
|
runCLI(
|
||||||
|
`generate @nx/node:app ${nestApp} --framework=nest --port=7003 --bundler=webpack --no-interactive`
|
||||||
|
);
|
||||||
|
|
||||||
// Use esbuild by default
|
addLibImport(expressApp, testLib1);
|
||||||
checkFilesDoNotExist(`apps/${expressApp}/webpack.config.js`);
|
addLibImport(expressApp, testLib2, '@acme/test2');
|
||||||
checkFilesDoNotExist(`apps/${fastifyApp}/webpack.config.js`);
|
addLibImport(fastifyApp, testLib1);
|
||||||
checkFilesDoNotExist(`apps/${koaApp}/webpack.config.js`);
|
addLibImport(fastifyApp, testLib2, '@acme/test2');
|
||||||
|
addLibImport(koaApp, testLib1);
|
||||||
|
addLibImport(koaApp, testLib2, '@acme/test2');
|
||||||
|
|
||||||
// Uses only webpack
|
addLibImport(nestApp, testLib1);
|
||||||
checkFilesExist(`apps/${nestApp}/webpack.config.js`);
|
addLibImport(nestApp, testLib2, '@acme/test2');
|
||||||
|
});
|
||||||
|
|
||||||
expect(() => runCLI(`lint ${expressApp}`)).not.toThrow();
|
it('should generate an app defaults using webpack or esbuild', async () => {
|
||||||
expect(() => runCLI(`lint ${fastifyApp}`)).not.toThrow();
|
// Use esbuild by default
|
||||||
expect(() => runCLI(`lint ${koaApp}`)).not.toThrow();
|
checkFilesDoNotExist(`apps/${expressApp}/webpack.config.js`);
|
||||||
expect(() => runCLI(`lint ${nestApp}`)).not.toThrow();
|
checkFilesDoNotExist(`apps/${fastifyApp}/webpack.config.js`);
|
||||||
|
checkFilesDoNotExist(`apps/${koaApp}/webpack.config.js`);
|
||||||
|
|
||||||
expect(() => runCLI(`lint ${expressApp}-e2e`)).not.toThrow();
|
// Uses only webpack
|
||||||
expect(() => runCLI(`lint ${fastifyApp}-e2e`)).not.toThrow();
|
checkFilesExist(`apps/${nestApp}/webpack.config.js`);
|
||||||
expect(() => runCLI(`lint ${koaApp}-e2e`)).not.toThrow();
|
|
||||||
expect(() => runCLI(`lint ${nestApp}-e2e`)).not.toThrow();
|
|
||||||
|
|
||||||
// Only Fastify generates with unit tests since it supports them without additional libraries.
|
expect(() => runCLI(`lint ${expressApp}`)).not.toThrow();
|
||||||
expect(() => runCLI(`test ${fastifyApp}`)).not.toThrow();
|
expect(() => runCLI(`lint ${fastifyApp}`)).not.toThrow();
|
||||||
|
expect(() => runCLI(`lint ${koaApp}`)).not.toThrow();
|
||||||
|
expect(() => runCLI(`lint ${nestApp}`)).not.toThrow();
|
||||||
|
|
||||||
// https://github.com/nrwl/nx/issues/16601
|
expect(() => runCLI(`lint ${expressApp}-e2e`)).not.toThrow();
|
||||||
const nestMainContent = readFile(`apps/${nestApp}/src/main.ts`);
|
expect(() => runCLI(`lint ${fastifyApp}-e2e`)).not.toThrow();
|
||||||
updateFile(
|
expect(() => runCLI(`lint ${koaApp}-e2e`)).not.toThrow();
|
||||||
`apps/${nestApp}/src/main.ts`,
|
expect(() => runCLI(`lint ${nestApp}-e2e`)).not.toThrow();
|
||||||
`
|
|
||||||
|
// Only Fastify generates with unit tests since it supports them without additional libraries.
|
||||||
|
expect(() => runCLI(`test ${fastifyApp}`)).not.toThrow();
|
||||||
|
|
||||||
|
// https://github.com/nrwl/nx/issues/16601
|
||||||
|
const nestMainContent = readFile(`apps/${nestApp}/src/main.ts`);
|
||||||
|
updateFile(
|
||||||
|
`apps/${nestApp}/src/main.ts`,
|
||||||
|
`
|
||||||
${nestMainContent}
|
${nestMainContent}
|
||||||
// Make sure this is not replaced during build time
|
// Make sure this is not replaced during build time
|
||||||
console.log('env: ' + process.env['NODE_ENV']);
|
console.log('env: ' + process.env['NODE_ENV']);
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
runCLI(`build ${nestApp}`);
|
runCLI(`build ${nestApp}`);
|
||||||
expect(readFile(`dist/apps/${nestApp}/main.js`)).toContain(
|
expect(readFile(`dist/apps/${nestApp}/main.js`)).toContain(
|
||||||
`'env: ' + process.env['NODE_ENV']`
|
`'env: ' + process.env['NODE_ENV']`
|
||||||
);
|
);
|
||||||
|
}, 300_000);
|
||||||
|
|
||||||
addLibImport(expressApp, testLib1);
|
it('should e2e test express app', async () => {
|
||||||
addLibImport(expressApp, testLib2, '@acme/test2');
|
await runE2eTests(expressApp, 7000);
|
||||||
addLibImport(fastifyApp, testLib1);
|
});
|
||||||
addLibImport(fastifyApp, testLib2, '@acme/test2');
|
|
||||||
addLibImport(koaApp, testLib1);
|
|
||||||
addLibImport(koaApp, testLib2, '@acme/test2');
|
|
||||||
|
|
||||||
addLibImport(nestApp, testLib1);
|
it('should e2e test fastify app', async () => {
|
||||||
addLibImport(nestApp, testLib2, '@acme/test2');
|
await runE2eTests(fastifyApp, 7001);
|
||||||
|
});
|
||||||
|
|
||||||
await runE2eTests(expressApp);
|
it('should e2e test koa app', async () => {
|
||||||
await runE2eTests(fastifyApp);
|
await runE2eTests(koaApp, 7002);
|
||||||
await runE2eTests(koaApp);
|
});
|
||||||
await runE2eTests(nestApp);
|
|
||||||
}, 900_000);
|
it('should e2e test nest app', async () => {
|
||||||
|
await runE2eTests(nestApp, 7003);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should generate a Dockerfile', async () => {
|
it('should generate a Dockerfile', async () => {
|
||||||
const expressApp = uniq('expressapp');
|
const expressApp = 'docker-express-app'; // needs to be consistent for the Dockerfile snapshot
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nx/node:app ${expressApp} --framework=express --docker --no-interactive`
|
`generate @nx/node:app ${expressApp} --framework=express --docker --no-interactive`
|
||||||
);
|
);
|
||||||
|
|
||||||
checkFilesExist(`apps/${expressApp}/Dockerfile`);
|
checkFilesExist(`apps/${expressApp}/Dockerfile`);
|
||||||
|
const dockerFile = readFile(`apps/${expressApp}/Dockerfile`);
|
||||||
|
expect(dockerFile).toMatchSnapshot();
|
||||||
}, 300_000);
|
}, 300_000);
|
||||||
|
|
||||||
it('should support waitUntilTargets for serve target', async () => {
|
it('should support waitUntilTargets for serve target', async () => {
|
||||||
|
|||||||
@ -27,12 +27,22 @@ function normalizeOptions(
|
|||||||
|
|
||||||
function addDocker(tree: Tree, options: SetUpDockerOptions) {
|
function addDocker(tree: Tree, options: SetUpDockerOptions) {
|
||||||
const projectConfig = readProjectConfiguration(tree, options.project);
|
const projectConfig = readProjectConfiguration(tree, options.project);
|
||||||
|
|
||||||
|
const outputPath =
|
||||||
|
projectConfig.targets[options.buildTarget]?.options['outputPath'];
|
||||||
|
|
||||||
if (!projectConfig) {
|
if (!projectConfig) {
|
||||||
throw new Error(`Cannot find project configuration for ${options.project}`);
|
throw new Error(`Cannot find project configuration for ${options.project}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!outputPath && !options.outputPath) {
|
||||||
|
throw new Error(
|
||||||
|
`The output path for the project ${options.project} is not defined. Please provide it as an option to the generator.`
|
||||||
|
);
|
||||||
|
}
|
||||||
generateFiles(tree, join(__dirname, './files'), projectConfig.root, {
|
generateFiles(tree, join(__dirname, './files'), projectConfig.root, {
|
||||||
tmpl: '',
|
tmpl: '',
|
||||||
buildLocation: options.outputPath,
|
buildLocation: options.outputPath ?? outputPath,
|
||||||
project: options.project,
|
project: options.project,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user