mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-15 18:13:38 +08:00
test: use random port for ng serve e2e tests
This commit is contained in:
parent
e2c7502730
commit
581602e8e7
@ -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.
|
||||
@ -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/)) {
|
||||
@ -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/)) {
|
||||
@ -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/)) {
|
||||
|
@ -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.');
|
||||
|
@ -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>/);
|
||||
|
@ -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>/);
|
||||
@ -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>/);
|
||||
|
@ -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/);
|
||||
|
@ -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>/)) {
|
||||
@ -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>/)) {
|
||||
@ -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>/)) {
|
||||
@ -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>/)) {
|
||||
|
@ -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 }),
|
||||
});
|
||||
|
||||
|
@ -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',
|
||||
@ -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 }),
|
||||
});
|
||||
|
||||
|
13
tests/legacy-cli/e2e/utils/network.ts
Normal file
13
tests/legacy-cli/e2e/utils/network.ts
Normal file
@ -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();
|
||||
});
|
||||
}
|
@ -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';
|
||||
|
||||
@ -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');
|
||||
|
@ -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;
|
||||
|
||||
@ -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();
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user