diff --git a/.github/workflows/techdocs-e2e.yml b/.github/workflows/techdocs-e2e.yml index 8f166515ff..191274ec84 100644 --- a/.github/workflows/techdocs-e2e.yml +++ b/.github/workflows/techdocs-e2e.yml @@ -39,4 +39,4 @@ jobs: - name: techdocs-cli e2e test working-directory: packages/techdocs-cli - run: yarn test:e2e + run: yarn test:e2e:ci diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 0f18903282..a24a1be0f8 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -24,8 +24,9 @@ "build": "./scripts/build.sh", "clean": "backstage-cli clean", "lint": "backstage-cli lint", - "test": "backstage-cli test --testPathIgnorePatterns src/e2e.test.ts", - "test:e2e": "backstage-cli test --testPathPattern src/e2e.test.ts --runInBand" + "test": "backstage-cli test --testPathIgnorePatterns=src/e2e.test.ts", + "test:e2e": "backstage-cli test src/e2e.test.ts", + "test:e2e:ci": "backstage-cli test --watchAll=false --ci src/e2e.test.ts" }, "bin": { "techdocs-cli": "bin/techdocs-cli" @@ -41,6 +42,7 @@ "@types/serve-handler": "^6.1.0", "@types/webpack-env": "^1.15.3", "embedded-techdocs-app": "0.0.0", + "find-process": "^1.4.5", "nodemon": "^2.0.2", "ts-node": "^10.0.0" }, diff --git a/packages/techdocs-cli/src/commands/serve/serve.ts b/packages/techdocs-cli/src/commands/serve/serve.ts index 5fed2dd56e..1182c850b3 100644 --- a/packages/techdocs-cli/src/commands/serve/serve.ts +++ b/packages/techdocs-cli/src/commands/serve/serve.ts @@ -121,10 +121,5 @@ export default async function serve(cmd: Command) { ); }); - try { - await waitForSignal([mkdocsChildProcess]); - process.exit(0); - } catch { - process.exit(1); - } + await waitForSignal([mkdocsChildProcess]); } diff --git a/packages/techdocs-cli/src/e2e.test.ts b/packages/techdocs-cli/src/e2e.test.ts index e6cf4e84c5..088dbc44b8 100644 --- a/packages/techdocs-cli/src/e2e.test.ts +++ b/packages/techdocs-cli/src/e2e.test.ts @@ -14,13 +14,15 @@ * limitations under the License. */ -import { execSync, spawn } from 'child_process'; +import { execSync, spawn, SpawnOptionsWithoutStdio } from 'child_process'; import path from 'path'; +import findProcess from 'find-process'; + const executeCommand = ( command: string, args: string[], - options?: Object, + options?: SpawnOptionsWithoutStdio, ): Promise<{ exit: number; stdout: string; @@ -29,10 +31,9 @@ const executeCommand = ( return new Promise(resolve => { const stdout: Buffer[] = []; const stderr: Buffer[] = []; - const proc = - process.platform === 'win32' - ? spawn('cmd', ['/s', '/c', command, ...args], options) - : spawn(command, args, options); + + const shell = process.platform === 'win32'; + const proc = spawn(command, args, { ...options, shell }); proc.stdout?.on('data', data => { stdout.push(Buffer.from(data)); @@ -52,9 +53,25 @@ const executeCommand = ( }); }; +const timeout = 25000; + +jest.setTimeout(timeout * 2); + describe('end-to-end', () => { const cwd = path.resolve(__dirname, 'fixture'); + afterEach(async () => { + // On Windows the pid of a spawned process may be wrong + // Because of this, we should be kill the MKDocs after the test + // (e.g. https://github.com/nodejs/node/issues/4289#issuecomment-854270414) + if (process.platform === 'win32') { + const procs = await findProcess('name', 'mkdocs', true); + procs.forEach((proc: { pid: number }) => { + process.kill(proc.pid); + }); + } + }); + beforeAll(() => { execSync('yarn workspace @techdocs/cli link', { stdio: 'ignore' }); }); @@ -64,29 +81,26 @@ describe('end-to-end', () => { }); it('shows help text', async () => { - jest.setTimeout(30000); const proc = await executeCommand('techdocs-cli', ['--help']); expect(proc.stdout).toContain('Usage: techdocs-cli [options]'); expect(proc.exit).toEqual(0); }); it('can generate', async () => { - jest.setTimeout(30000); const proc = await executeCommand( 'techdocs-cli', ['generate', '--no-docker'], - { cwd, timeout: 25000 }, + { cwd, timeout }, ); expect(proc.stdout).toContain('Successfully generated docs'); expect(proc.exit).toEqual(0); }); it('can serve in mkdocs', async () => { - jest.setTimeout(30000); const proc = await executeCommand( 'techdocs-cli', ['serve:mkdocs', '--no-docker'], - { cwd, timeout: 25000 }, + { cwd, timeout }, ); expect(proc.stdout).toContain('Starting mkdocs server'); expect(proc.exit).toEqual(0); @@ -97,7 +111,7 @@ describe('end-to-end', () => { const proc = await executeCommand( 'techdocs-cli', ['serve', '--no-docker'], - { cwd, timeout: 25000 }, + { cwd, timeout }, ); expect(proc.stdout).toContain('Starting mkdocs server'); expect(proc.stdout).toContain('Serving docs in Backstage at'); diff --git a/scripts/techdocs-cli.js b/scripts/techdocs-cli.js index 90dcc40f39..7cc07f15fa 100644 --- a/scripts/techdocs-cli.js +++ b/scripts/techdocs-cli.js @@ -19,7 +19,7 @@ const { execSync } = require('child_process'); const args = process.argv.slice(2); -execSync(`yarn workspace @techdocs/cli build`, { stdio: 'inherit' }); +execSync(`yarn -s workspace @techdocs/cli build`, { stdio: 'inherit' }); execSync(`yarn workspace @techdocs/cli link`, { stdio: 'ignore' }); execSync(`techdocs-cli ${args.join(' ')}`, { stdio: 'inherit' }); execSync(`yarn workspace @techdocs/cli unlink`, { stdio: 'ignore' }); diff --git a/yarn.lock b/yarn.lock index f51a95fccd..b52b045573 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14667,6 +14667,15 @@ find-my-way@^2.2.2: safe-regex2 "^2.0.0" semver-store "^0.3.0" +find-process@^1.4.5: + version "1.4.5" + resolved "https://registry.npmjs.org/find-process/-/find-process-1.4.5.tgz#6a0e4c87a32ca927c05cbed7b9078d62ffaac1a4" + integrity sha512-v11rJYYISUWn+s8qZzgGnBvlzRKf3bOtlGFM8H0kw56lGQtOmLuLCzuclA5kehA2j7S5sioOWdI4woT3jDavAw== + dependencies: + chalk "^4.0.0" + commander "^5.1.0" + debug "^4.1.1" + find-root@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"