From c06031ec35a05fc8da047924be468a8f1981f121 Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Wed, 8 Jun 2022 16:49:20 -0700 Subject: [PATCH] test: use random port for e2e express http server tests --- .../e2e/tests/i18n/ivy-localize-basehref.ts | 16 +++++++--- .../e2e/tests/i18n/ivy-localize-es2015.ts | 5 ++-- .../e2e/tests/i18n/ivy-localize-es5.ts | 5 ++-- .../i18n/ivy-localize-locale-data-augment.ts | 5 ++-- .../e2e/tests/i18n/ivy-localize-server.ts | 6 ++-- .../tests/i18n/ivy-localize-serviceworker.ts | 6 ++-- tests/legacy-cli/e2e/tests/i18n/setup.ts | 29 +++++++++++++++---- 7 files changed, 53 insertions(+), 19 deletions(-) diff --git a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-basehref.ts b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-basehref.ts index b55cffc22f8d..79854bfb193d 100644 --- a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-basehref.ts +++ b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-basehref.ts @@ -59,13 +59,17 @@ export default async function () { await ng('e2e', `--configuration=${lang}`, '--port=0'); // Execute Application E2E tests for a production build without dev server - const server = externalServer(outputPath, (baseHrefs[lang] as string) || '/'); + const { server, port, url } = await externalServer( + outputPath, + (baseHrefs[lang] as string) || '/', + ); try { await ng( 'e2e', + `--port=${port}`, `--configuration=${lang}`, '--dev-server-target=', - `--base-url=http://localhost:4200${baseHrefs[lang] || '/'}`, + `--base-url=${url}`, ); } finally { server.close(); @@ -89,13 +93,17 @@ export default async function () { await ng('e2e', `--configuration=${lang}`, '--port=0'); // Execute Application E2E tests for a production build without dev server - const server = externalServer(outputPath, '/test' + (baseHrefs[lang] || '/')); + const { server, port, url } = await externalServer( + outputPath, + '/test' + (baseHrefs[lang] || '/'), + ); try { await ng( 'e2e', + `--port=${port}`, `--configuration=${lang}`, '--dev-server-target=', - `--base-url=http://localhost:4200/test${baseHrefs[lang] || '/'}`, + `--base-url=${url}`, ); } finally { server.close(); diff --git a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-es2015.ts b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-es2015.ts index 00f276fbbe2b..7d44a05e0392 100644 --- a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-es2015.ts +++ b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-es2015.ts @@ -36,13 +36,14 @@ export default async function () { await ng('e2e', `--configuration=${lang}`, '--port=0'); // Execute Application E2E tests for a production build without dev server - const server = externalServer(outputPath, `/${lang}/`); + const { server, port, url } = await externalServer(outputPath, `/${lang}/`); try { await ng( 'e2e', + `--port=${port}`, `--configuration=${lang}`, '--dev-server-target=', - `--base-url=http://localhost:4200/${lang}/`, + `--base-url=${url}`, ); } finally { server.close(); diff --git a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-es5.ts b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-es5.ts index 8e996d396e85..5dbfbc402b7e 100644 --- a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-es5.ts +++ b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-es5.ts @@ -44,13 +44,14 @@ export default async function () { await ng('e2e', `--configuration=${lang}`, '--port=0'); // Execute Application E2E tests for a production build without dev server - const server = externalServer(outputPath, `/${lang}/`); + const { server, port, url } = await externalServer(outputPath, `/${lang}/`); try { await ng( 'e2e', + `--port=${port}`, `--configuration=${lang}`, '--dev-server-target=', - `--base-url=http://localhost:4200/${lang}/`, + `--base-url=${url}`, ); } finally { server.close(); diff --git a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-locale-data-augment.ts b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-locale-data-augment.ts index b1a9eaf307db..db45baf074b4 100644 --- a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-locale-data-augment.ts +++ b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-locale-data-augment.ts @@ -43,13 +43,14 @@ export default async function () { await ng('e2e', `--configuration=${lang}`, '--port=0'); // Execute Application E2E tests for a production build without dev server - const server = externalServer(outputPath, `/${lang}/`); + const { server, port, url } = await externalServer(outputPath, `/${lang}/`); try { await ng( 'e2e', + `--port=${port}`, `--configuration=${lang}`, '--dev-server-target=', - `--base-url=http://localhost:4200/${lang}/`, + `--base-url=${url}`, ); } finally { server.close(); diff --git a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-server.ts b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-server.ts index 82447344ad8e..91b598768302 100644 --- a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-server.ts +++ b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-server.ts @@ -2,6 +2,7 @@ import express from 'express'; import { join } from 'path'; import { getGlobalVariable } from '../../utils/env'; import { appendToFile, expectFileToMatch, writeFile } from '../../utils/fs'; +import { findFreePort } from '../../utils/network'; import { installWorkspacePackages } from '../../utils/packages'; import { ng } from '../../utils/process'; import { updateJsonFile } from '../../utils/project'; @@ -13,6 +14,7 @@ const snapshots = require('../../ng-snapshot/package.json'); export default async function () { // TODO: Re-enable pending further Ivy/Universal/i18n work return; + const port = await findFreePort(); // Setup i18n tests and config. await setupI18nConfig(); @@ -113,10 +115,10 @@ export default async function () { const { i18nApp } = (await import(serverBundle)) as { i18nApp(locale: string): express.Express; }; - const server = i18nApp(lang).listen(4200, 'localhost'); + const server = i18nApp(lang).listen(port, 'localhost'); try { // Execute without a devserver. - await ng('e2e', `--configuration=${lang}`, '--dev-server-target='); + await ng('e2e', `--port=${port}`, `--configuration=${lang}`, '--dev-server-target='); } finally { server.close(); } diff --git a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-serviceworker.ts b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-serviceworker.ts index 297e4225d179..e289585701fd 100644 --- a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-serviceworker.ts +++ b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-serviceworker.ts @@ -8,6 +8,7 @@ import { replaceInFile, writeFile, } from '../../utils/fs'; +import { findFreePort } from '../../utils/network'; import { installPackage } from '../../utils/packages'; import { ng } from '../../utils/process'; import { updateJsonFile } from '../../utils/project'; @@ -18,6 +19,7 @@ export default async function () { // TEMP: disable pending i18n updates // TODO: when re-enabling, use setupI18nConfig and helpers like other i18n tests. return; + const port = await findFreePort(); let localizeVersion = '@angular/localize@' + readNgVersion(); if (getGlobalVariable('argv')['ng-snapshots']) { @@ -156,7 +158,7 @@ export default async function () { // Ivy i18n doesn't yet work with `ng serve` so we must use a separate server. const app = express(); app.use(express.static(resolve(baseDir, lang))); - const server = app.listen(4200, 'localhost'); + const server = app.listen(port, 'localhost'); try { // Add E2E test for locale await writeFile( @@ -180,7 +182,7 @@ export default async function () { ); // Execute without a devserver. - await ng('e2e', '--dev-server-target='); + await ng('e2e', '--dev-server-target=', `--port=${port}`); } finally { server.close(); } diff --git a/tests/legacy-cli/e2e/tests/i18n/setup.ts b/tests/legacy-cli/e2e/tests/i18n/setup.ts index d7954d6e5d59..22db41566201 100644 --- a/tests/legacy-cli/e2e/tests/i18n/setup.ts +++ b/tests/legacy-cli/e2e/tests/i18n/setup.ts @@ -9,11 +9,12 @@ import { replaceInFile, writeFile, } from '../../utils/fs'; +import { findFreePort } from '../../utils/network'; import { installPackage } from '../../utils/packages'; import { ng } from '../../utils/process'; import { updateJsonFile } from '../../utils/project'; -import { expectToFail } from '../../utils/utils'; import { readNgVersion } from '../../utils/version'; +import { Server } from 'http'; // Configurations for each locale. export const baseDir = 'dist/test-project'; @@ -67,13 +68,31 @@ export const langTranslations = [ ]; export const sourceLocale = langTranslations[0].lang; -export const externalServer = (outputPath: string, baseUrl = '/') => { +export interface ExternalServer { + readonly server: Server; + readonly port: number; + readonly url: string; +} + +/** + * Create an `express` `http.Server` listening on a random port. + * + * Call .close() on the server return value to close the server. + */ +export async function externalServer(outputPath: string, baseUrl = '/'): Promise { + const port = await findFreePort(); + const app = express(); app.use(baseUrl, express.static(resolve(outputPath))); - // call .close() on the return value to close the server. - return app.listen(4200, 'localhost'); -}; + const server = app.listen(port, 'localhost'); + + return { + server, + port, + url: `http://localhost:${port}${baseUrl}`, + }; +} export const formats = { 'xlf': {