Skip to content

Commit

Permalink
test: use random port for ng serve e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jbedard committed Jun 9, 2022
1 parent 4708ccd commit be4ea9e
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 42 deletions.
13 changes: 8 additions & 5 deletions tests/legacy-cli/e2e/tests/basic/rebuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import {
import { writeFile, writeMultipleFiles } from '../../utils/fs';
import { wait } from '../../utils/utils';
import fetch from 'node-fetch';
import { findFreePort } from '../../utils/network';

const validBundleRegEx = / Compiled successfully./;

export default function () {
export default async function () {
const port = await findFreePort();

return (
execAndWaitForOutputToMatch('ng', ['serve'], validBundleRegEx)
execAndWaitForOutputToMatch('ng', ['serve', '--port', String(port)], validBundleRegEx)
// Add a lazy module.
.then(() => ng('generate', 'module', 'lazy', '--routing'))
// Should trigger a rebuild with a new bundle.
Expand Down Expand Up @@ -136,7 +139,7 @@ export default function () {
]),
)
.then(() => wait(2000))
.then(() => fetch('http://localhost:4200/main.js'))
.then(() => fetch(`http://localhost:${port}/main.js`))
.then((response) => response.text())
.then((body) => {
if (!body.match(/\$\$_E2E_GOLDEN_VALUE_1/)) {
Expand All @@ -158,7 +161,7 @@ export default function () {
]),
)
.then(() => wait(2000))
.then(() => fetch('http://localhost:4200/main.js'))
.then(() => fetch(`http://localhost:${port}/main.js`))
.then((response) => response.text())
.then((body) => {
if (!body.match(/testingTESTING123/)) {
Expand All @@ -174,7 +177,7 @@ export default function () {
]),
)
.then(() => wait(2000))
.then(() => fetch('http://localhost:4200/main.js'))
.then(() => fetch(`http://localhost:${port}/main.js`))
.then((response) => response.text())
.then((body) => {
if (!body.match(/color:\s?blue/)) {
Expand Down
12 changes: 6 additions & 6 deletions tests/legacy-cli/e2e/tests/basic/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import { ngServe } from '../../utils/project';
export default async function () {
try {
// Serve works without HMR
await ngServe('--no-hmr');
await verifyResponse();
const noHmrPort = await ngServe('--no-hmr');
await verifyResponse(noHmrPort);
await killAllProcesses();

// Serve works with HMR
await ngServe('--hmr');
await verifyResponse();
const hmrPort = await ngServe('--hmr');
await verifyResponse(hmrPort);
} finally {
await killAllProcesses();
}
}

async function verifyResponse(): Promise<void> {
const response = await fetch('http://localhost:4200/');
async function verifyResponse(port: number): Promise<void> {
const response = await fetch(`http://localhost:${port}/`);

if (!/<app-root><\/app-root>/.test(await response.text())) {
throw new Error('Response does not match expected value.');
Expand Down
9 changes: 5 additions & 4 deletions tests/legacy-cli/e2e/tests/commands/serve/serve-path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ import fetch from 'node-fetch';
import { killAllProcesses } from '../../../utils/process';
import { ngServe } from '../../../utils/project';

export default function () {
export default async function () {
// TODO(architect): Delete this test. It is now in devkit/build-angular.

const port = await ngServe('--serve-path', 'test/');

return Promise.resolve()
.then(() => ngServe('--serve-path', 'test/'))
.then(() => fetch('http://localhost:4200/test', { headers: { 'Accept': 'text/html' } }))
.then(() => fetch(`http://localhost:${port}/test`, { headers: { 'Accept': 'text/html' } }))
.then(async (response) => {
assert.strictEqual(response.status, 200);
assert.match(await response.text(), /<app-root><\/app-root>/);
})
.then(() => fetch('http://localhost:4200/test/abc', { headers: { 'Accept': 'text/html' } }))
.then(() => fetch(`http://localhost:${port}/test/abc`, { headers: { 'Accept': 'text/html' } }))
.then(async (response) => {
assert.strictEqual(response.status, 200);
assert.match(await response.text(), /<app-root><\/app-root>/);
Expand Down
4 changes: 2 additions & 2 deletions tests/legacy-cli/e2e/tests/misc/fallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function () {
return (
Promise.resolve()
.then(() => ngServe())
.then(() => fetch('http://localhost:4200/', { headers: { 'Accept': 'text/html' } }))
.then((port) => fetch(`http://localhost:${port}/`, { headers: { 'Accept': 'text/html' } }))
.then(async (response) => {
assert.strictEqual(response.status, 200);
assert.match(await response.text(), /<app-root><\/app-root>/);
Expand All @@ -27,7 +27,7 @@ export default function () {
}),
)
.then(() => ngServe())
.then(() => fetch('http://localhost:4200/', { headers: { 'Accept': 'text/html' } }))
.then((port) => fetch(`http://localhost:${port}/`, { headers: { 'Accept': 'text/html' } }))
.then(async (response) => {
assert.strictEqual(response.status, 200);
assert.match(await response.text(), /<app-root><\/app-root>/);
Expand Down
2 changes: 1 addition & 1 deletion tests/legacy-cli/e2e/tests/misc/proxy-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default function () {
return Promise.resolve()
.then(() => writeFile(proxyConfigFile, JSON.stringify(proxyConfig, null, 2)))
.then(() => ngServe('--proxy-config', proxyConfigFile))
.then(() => fetch('http://localhost:4200/api/test'))
.then((port) => fetch(`http://localhost:${port}/api/test`))
.then(async (response) => {
assert.strictEqual(response.status, 200);
assert.match(await response.text(), /TEST_API_RETURN/);
Expand Down
10 changes: 5 additions & 5 deletions tests/legacy-cli/e2e/tests/misc/public-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ export default function () {
.filter((ni) => ni?.family === 'IPv4' && !ni?.internal)
.map((ni) => ni!.address)
.shift();
const publicHost = `${firstLocalIp}:4200`;
const publicHost = `${firstLocalIp}`;
const localAddress = `http://${publicHost}`;

return Promise.resolve()
.then(() => ngServe('--host=0.0.0.0', `--public-host=${publicHost}`))
.then(() => fetch(localAddress))
.then((port) => fetch(`${localAddress}:${port}`))
.then((response) => response.text())
.then((body) => {
if (!body.match(/<app-root><\/app-root>/)) {
Expand All @@ -25,7 +25,7 @@ export default function () {
})
.then(() => killAllProcesses())
.then(() => ngServe('--host=0.0.0.0', `--disable-host-check`))
.then(() => fetch(localAddress))
.then((port) => fetch(`${localAddress}:${port}`))
.then((response) => response.text())
.then((body) => {
if (!body.match(/<app-root><\/app-root>/)) {
Expand All @@ -35,7 +35,7 @@ export default function () {

.then(() => killAllProcesses())
.then(() => ngServe('--host=0.0.0.0', `--public-host=${localAddress}`))
.then(() => fetch(localAddress))
.then((port) => fetch(`${localAddress}:${port}`))
.then((response) => response.text())
.then((body) => {
if (!body.match(/<app-root><\/app-root>/)) {
Expand All @@ -44,7 +44,7 @@ export default function () {
})
.then(() => killAllProcesses())
.then(() => ngServe('--host=0.0.0.0', `--public-host=${firstLocalIp}`))
.then(() => fetch(localAddress))
.then((port) => fetch(`${localAddress}:${port}`))
.then((response) => response.text())
.then((body) => {
if (!body.match(/<app-root><\/app-root>/)) {
Expand Down
4 changes: 2 additions & 2 deletions tests/legacy-cli/e2e/tests/misc/ssl-default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ export default async function () {
// TODO(architect): Delete this test. It is now in devkit/build-angular.

try {
await ngServe('--ssl', 'true');
const port = await ngServe('--ssl', 'true');

const response = await fetch('https://localhost:4200/', {
const response = await fetch(`https://localhost:${port}/`, {
agent: new Agent({ rejectUnauthorized: false }),
});

Expand Down
4 changes: 2 additions & 2 deletions tests/legacy-cli/e2e/tests/misc/ssl-with-cert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default async function () {
// TODO(architect): Delete this test. It is now in devkit/build-angular.

try {
await ngServe(
const port = await ngServe(
'--ssl',
'true',
'--ssl-key',
Expand All @@ -18,7 +18,7 @@ export default async function () {
assetDir('ssl/server.crt'),
);

const response = await fetch('https://localhost:4200/', {
const response = await fetch(`https://localhost:${port}/`, {
agent: new Agent({ rejectUnauthorized: false }),
});

Expand Down
13 changes: 13 additions & 0 deletions tests/legacy-cli/e2e/utils/network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { AddressInfo, createServer } from 'net';

export function findFreePort() {
return new Promise<number>((resolve, reject) => {
const srv = createServer();
srv.once('listening', () => {
const port = (srv.address() as AddressInfo).port;
srv.close((e) => (e ? reject(e) : resolve(port)));
});
srv.once('error', (e) => srv.close(() => reject(e)));
srv.listen();
});
}
13 changes: 11 additions & 2 deletions tests/legacy-cli/e2e/utils/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { packages } from '../../../../lib/packages';
import { getGlobalVariable } from './env';
import { prependToFile, readFile, replaceInFile, writeFile } from './fs';
import { gitCommit } from './git';
import { findFreePort } from './network';
import { installWorkspacePackages } from './packages';
import { exec, execAndWaitForOutputToMatch, git, ng } from './process';

Expand All @@ -23,8 +24,16 @@ export function updateTsConfig(fn: (json: any) => any | void) {
return updateJsonFile('tsconfig.json', fn);
}

export function ngServe(...args: string[]) {
return execAndWaitForOutputToMatch('ng', ['serve', ...args], / Compiled successfully./);
export async function ngServe(...args: string[]) {
const port = await findFreePort();

await execAndWaitForOutputToMatch(
'ng',
['serve', '--port', String(port), ...args],
/ Compiled successfully./,
);

return port;
}
export async function prepareProjectForE2e(name: string) {
const argv: yargsParser.Arguments = getGlobalVariable('argv');
Expand Down
14 changes: 1 addition & 13 deletions tests/legacy-cli/e2e_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import * as path from 'path';
import { getGlobalVariable, setGlobalVariable } from './e2e/utils/env';
import { gitClean } from './e2e/utils/git';
import { createNpmRegistry } from './e2e/utils/registry';
import { AddressInfo, createServer } from 'net';
import { launchTestProcess } from './e2e/utils/process';
import { join } from 'path';
import { findFreePort } from './e2e/utils/network';

Error.stackTraceLimit = Infinity;

Expand Down Expand Up @@ -254,15 +254,3 @@ function printFooter(testName: string, type: 'setup' | 'initializer' | 'test', s
console.log(colors.green(`Last ${type} took `) + colors.bold.blue('' + t) + colors.green('s...'));
console.log('');
}

function findFreePort() {
return new Promise<number>((resolve, reject) => {
const srv = createServer();
srv.once('listening', () => {
const port = (srv.address() as AddressInfo).port;
srv.close((e) => (e ? reject(e) : resolve(port)));
});
srv.once('error', (e) => srv.close(() => reject(e)));
srv.listen();
});
}

0 comments on commit be4ea9e

Please sign in to comment.