From d80fd07ea315717e9e23a627045be0c184849d2d Mon Sep 17 00:00:00 2001 From: Nicholas Cunningham Date: Fri, 17 May 2024 13:38:26 -0600 Subject: [PATCH] fix(node): Enable e2e test --- e2e/node/src/node-server.test.ts | 140 ++++++++++-------- .../setup-docker/setup-docker.spec.ts | 40 +---- .../generators/setup-docker/setup-docker.ts | 8 +- 3 files changed, 86 insertions(+), 102 deletions(-) diff --git a/e2e/node/src/node-server.test.ts b/e2e/node/src/node-server.test.ts index b39f95520e8993..27e370a583c3bd 100644 --- a/e2e/node/src/node-server.test.ts +++ b/e2e/node/src/node-server.test.ts @@ -14,11 +14,16 @@ import { } from '@nx/e2e/utils'; import { join } from 'path'; -xdescribe('Node Applications + webpack', () => { +describe('Node Applications + webpack', () => { let proj: string; beforeAll(() => { proj = newProject({ 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: 'pnpm', }); }); @@ -47,10 +52,10 @@ xdescribe('Node Applications + webpack', () => { } } - async function runE2eTests(appName: string) { - process.env.PORT = '5000'; + async function runE2eTests(appName: string, port: number = 5000) { + process.env.PORT = `${port}`; 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`); expect(result).toContain('Setting up...'); @@ -58,13 +63,11 @@ xdescribe('Node Applications + webpack', () => { expect(result).toContain('Successfully ran target e2e'); await promisifiedTreeKill(childProcess.pid, 'SIGKILL'); - await killPort(5000); + await killPort(port); process.env.PORT = ''; } - // Disabled due to flakiness of ajv disabled (Error: Cannot find module 'ajv/dist/compile/codegen') - // TODO: (nicholas) Re-enable when the flakiness is resolved - xit('should generate an app using webpack', async () => { + describe('frameworks', () => { const testLib1 = uniq('test1'); const testLib2 = uniq('test2'); const expressApp = uniq('expressapp'); @@ -72,76 +75,93 @@ xdescribe('Node Applications + webpack', () => { const koaApp = uniq('koaapp'); const nestApp = uniq('nest'); - runCLI(`generate @nx/node:lib ${testLib1}`); - runCLI(`generate @nx/node:lib ${testLib2} --importPath=@acme/test2`); - runCLI( - `generate @nx/node:app ${expressApp} --framework=express --no-interactive` - ); - runCLI( - `generate @nx/node:app ${fastifyApp} --framework=fastify --no-interactive` - ); - runCLI(`generate @nx/node:app ${koaApp} --framework=koa --no-interactive`); - runCLI( - `generate @nx/node:app ${nestApp} --framework=nest --bundler=webpack --no-interactive` - ); + beforeAll(() => { + runCLI(`generate @nx/node:lib ${testLib1}`); + runCLI(`generate @nx/node:lib ${testLib2} --importPath=@acme/test2`); + runCLI( + `generate @nx/node:app ${expressApp} --framework=express --port=7000 --no-interactive` + ); + runCLI( + `generate @nx/node:app ${fastifyApp} --framework=fastify --port=7001 --no-interactive` + ); + runCLI( + `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 - checkFilesDoNotExist(`apps/${expressApp}/webpack.config.js`); - checkFilesDoNotExist(`apps/${fastifyApp}/webpack.config.js`); - checkFilesDoNotExist(`apps/${koaApp}/webpack.config.js`); + addLibImport(expressApp, testLib1); + addLibImport(expressApp, testLib2, '@acme/test2'); + addLibImport(fastifyApp, testLib1); + addLibImport(fastifyApp, testLib2, '@acme/test2'); + addLibImport(koaApp, testLib1); + addLibImport(koaApp, testLib2, '@acme/test2'); - // Uses only webpack - checkFilesExist(`apps/${nestApp}/webpack.config.js`); + addLibImport(nestApp, testLib1); + addLibImport(nestApp, testLib2, '@acme/test2'); + }); - expect(() => runCLI(`lint ${expressApp}`)).not.toThrow(); - expect(() => runCLI(`lint ${fastifyApp}`)).not.toThrow(); - expect(() => runCLI(`lint ${koaApp}`)).not.toThrow(); - expect(() => runCLI(`lint ${nestApp}`)).not.toThrow(); + it('should generate an app defaults using webpack or esbuild', async () => { + // Use esbuild by default + checkFilesDoNotExist(`apps/${expressApp}/webpack.config.js`); + checkFilesDoNotExist(`apps/${fastifyApp}/webpack.config.js`); + checkFilesDoNotExist(`apps/${koaApp}/webpack.config.js`); - expect(() => runCLI(`lint ${expressApp}-e2e`)).not.toThrow(); - expect(() => runCLI(`lint ${fastifyApp}-e2e`)).not.toThrow(); - expect(() => runCLI(`lint ${koaApp}-e2e`)).not.toThrow(); - expect(() => runCLI(`lint ${nestApp}-e2e`)).not.toThrow(); + // Uses only webpack + checkFilesExist(`apps/${nestApp}/webpack.config.js`); - // Only Fastify generates with unit tests since it supports them without additional libraries. - expect(() => runCLI(`test ${fastifyApp}`)).not.toThrow(); + expect(() => runCLI(`lint ${expressApp}`)).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 - const nestMainContent = readFile(`apps/${nestApp}/src/main.ts`); - updateFile( - `apps/${nestApp}/src/main.ts`, - ` + expect(() => runCLI(`lint ${expressApp}-e2e`)).not.toThrow(); + expect(() => runCLI(`lint ${fastifyApp}-e2e`)).not.toThrow(); + 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(`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} // Make sure this is not replaced during build time console.log('env: ' + process.env['NODE_ENV']); ` - ); - runCLI(`build ${nestApp}`); - expect(readFile(`dist/apps/${nestApp}/main.js`)).toContain( - `'env: ' + process.env['NODE_ENV']` - ); + ); + runCLI(`build ${nestApp}`); + expect(readFile(`dist/apps/${nestApp}/main.js`)).toContain( + `'env: ' + process.env['NODE_ENV']` + ); + }, 300_000); - addLibImport(expressApp, testLib1); - addLibImport(expressApp, testLib2, '@acme/test2'); - addLibImport(fastifyApp, testLib1); - addLibImport(fastifyApp, testLib2, '@acme/test2'); - addLibImport(koaApp, testLib1); - addLibImport(koaApp, testLib2, '@acme/test2'); + it('should e2e test express app', async () => { + await runE2eTests(expressApp, 7000); + }); + + it('should e2e test fastify app', async () => { + await runE2eTests(fastifyApp, 7001); + }); - addLibImport(nestApp, testLib1); - addLibImport(nestApp, testLib2, '@acme/test2'); + it('should e2e test koa app', async () => { + await runE2eTests(koaApp, 7002); + }); - await runE2eTests(expressApp); - await runE2eTests(fastifyApp); - 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 () => { const expressApp = uniq('expressapp'); 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`); diff --git a/packages/node/src/generators/setup-docker/setup-docker.spec.ts b/packages/node/src/generators/setup-docker/setup-docker.spec.ts index 8a1d4e4e853caf..195ce2b7659796 100644 --- a/packages/node/src/generators/setup-docker/setup-docker.spec.ts +++ b/packages/node/src/generators/setup-docker/setup-docker.spec.ts @@ -1,11 +1,8 @@ import 'nx/src/internal-testing-utils/mock-project-graph'; -import { - ProjectConfiguration, - readProjectConfiguration, - Tree, -} from '@nx/devkit'; +import { readProjectConfiguration, Tree } from '@nx/devkit'; import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; +import { applicationGenerator } from '../application/application'; describe('setupDockerGenerator', () => { let tree: Tree; @@ -18,15 +15,6 @@ describe('setupDockerGenerator', () => { describe('integrated', () => { it('should create docker assets when --docker is passed', async () => { const projectName = 'integreated-api'; - // Since we mock the project graph, we need to mock the project configuration as well - mockReadCachedProjectConfiguration({ - name: projectName, - root: projectName, - }); - - const { applicationGenerator } = await import( - '../application/application' - ); await applicationGenerator(tree, { name: projectName, @@ -56,11 +44,7 @@ describe('setupDockerGenerator', () => { describe('standalone', () => { it('should create docker assets when --docker is passed', async () => { const projectName = 'standalone-api'; - mockReadCachedProjectConfiguration({ name: projectName, root: '' }); - const { applicationGenerator } = await import( - '../application/application' - ); await applicationGenerator(tree, { name: projectName, framework: 'fastify', @@ -86,23 +70,3 @@ describe('setupDockerGenerator', () => { }); }); }); - -const mockReadCachedProjectConfiguration = ( - projectConfig: ProjectConfiguration -) => { - jest.mock('nx/src/project-graph/project-graph', () => { - return { - ...jest.requireActual('nx/src/project-graph/project-graph'), - readCachedProjectConfiguration: jest.fn(() => { - return { - root: projectConfig.root, - targets: { - build: { - outputs: [`dist/${projectConfig.name}`], - }, - }, - }; - }), - }; - }); -}; diff --git a/packages/node/src/generators/setup-docker/setup-docker.ts b/packages/node/src/generators/setup-docker/setup-docker.ts index f0c3277cbfeb3c..5cc1697443505b 100644 --- a/packages/node/src/generators/setup-docker/setup-docker.ts +++ b/packages/node/src/generators/setup-docker/setup-docker.ts @@ -4,7 +4,6 @@ import { GeneratorCallback, joinPathFragments, logger, - ProjectConfiguration, readNxJson, readProjectConfiguration, runTasksInSerial, @@ -15,7 +14,6 @@ import { import { SetUpDockerOptions } from './schema'; import { join } from 'path'; import { interpolate } from 'nx/src/tasks-runner/utils'; -import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph'; function normalizeOptions( tree: Tree, @@ -30,14 +28,16 @@ function normalizeOptions( } function addDocker(tree: Tree, options: SetUpDockerOptions) { - // Inferred targets are only available in the project graph - const projectConfig = readCachedProjectConfiguration(options.project); + const projectConfig = readProjectConfiguration(tree, options.project); if ( !projectConfig || !projectConfig.targets || !projectConfig.targets[options.buildTarget] ) { + logger.error( + `Could not find the project ${options.project} or the build target ${options.buildTarget} in the workspace.` + ); return; }