From 9cc1fc8b2002c72da3e8755dda1e14ad4869e01a Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 9 Sep 2026 10:14:36 +0000 Subject: [PATCH 1/3] fix(@angular/build): disable strictPort when port 0 is used in dev-server When port 0 is specified, an ephemeral port is selected. Previously, strictPort was hardcoded to true, which caused Vite to fail immediately if the ephemeral port was occupied during rebuilds or rapid restarts. strictPort is now set to false when port 0 is requested, allowing Vite to fall back to an available port. --- packages/angular/build/src/builders/dev-server/options.ts | 8 +++++++- .../angular/build/src/builders/dev-server/vite/server.ts | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/options.ts b/packages/angular/build/src/builders/dev-server/options.ts index 5473da832449..7dfdc56a371d 100644 --- a/packages/angular/build/src/builders/dev-server/options.ts +++ b/packages/angular/build/src/builders/dev-server/options.ts @@ -13,7 +13,12 @@ import { normalizeCacheOptions } from '../../utils/normalize-cache'; import { ApplicationBuilderOptions } from '../application'; import { Schema as DevServerOptions } from './schema'; -export type NormalizedDevServerOptions = Awaited>; +export type NormalizedDevServerOptions = Omit< + Awaited>, + 'strictPort' +> & { + strictPort?: boolean; +}; /** * Normalize the user provided options by creating full paths for all path based options @@ -122,6 +127,7 @@ export async function normalizeOptions( buildTarget, host: host ?? 'localhost', port, + strictPort: port !== 0, poll, open, verbose, diff --git a/packages/angular/build/src/builders/dev-server/vite/server.ts b/packages/angular/build/src/builders/dev-server/vite/server.ts index 7dd62aed37b6..fb7870bd2d27 100644 --- a/packages/angular/build/src/builders/dev-server/vite/server.ts +++ b/packages/angular/build/src/builders/dev-server/vite/server.ts @@ -56,7 +56,7 @@ async function createServerConfig( ssrFiles, }, port: serverOptions.port, - strictPort: true, + strictPort: serverOptions.strictPort ?? true, host: serverOptions.host, open: serverOptions.open, allowedHosts: serverOptions.allowedHosts, From 843adb6ae21d67c3c59da0b5171cbef7ad0a41a9 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 9 Sep 2026 10:14:41 +0000 Subject: [PATCH 2/3] test(@angular-devkit/build-angular): prevent flakiness in live-reload proxies dev-server test Ignore proxy connection errors when the browser reloads or disconnects, and replace fixed setTimeout delays with waitForAppLiveReload polling helper to avoid navigation race conditions. --- .../serve-live-reload-proxies_spec.ts | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts index 2ebd9e27d6c4..748fa01108af 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts @@ -101,12 +101,33 @@ async function createProxy(target: string, secure: boolean, ws = true): Promise< }, }).listen(proxyPort); + server.on('error', () => { + // Ignore proxy connection errors that occur when the browser reloads or disconnects. + }); + return { server, url: `${secure ? 'https' : 'http'}://localhost:${proxyPort}`, }; } +async function waitForAppLiveReload(page: Page): Promise { + const startTime = Date.now(); + while (Date.now() - startTime < 30_000) { + try { + const text = await page.evaluate(() => document.querySelector('p')?.innerText); + if (text === 'app-live-reload') { + return; + } + } catch { + // Ignore execution context destruction errors during page navigation. + } + await setTimeoutPromise(100); + } + + throw new Error('Timed out waiting for page to reload with updated text.'); +} + async function goToPageAndWaitForWS(page: Page, url: string): Promise { const baseUrl = url.replace(/^http/, 'ws'); const socksRequest = baseUrl.at(-1) === '/' ? `${baseUrl}ng-cli-ws` : `${baseUrl}/ng-cli-ws`; @@ -203,8 +224,7 @@ describeServeBuilder( async ({ result }) => { expect(result?.success).toBeTrue(); - // Wait for page to reload. - await setTimeoutPromise(500); + await waitForAppLiveReload(page); const innerText = await page.evaluate(() => document.querySelector('p').innerText); expect(innerText).toBe('app-live-reload'); @@ -238,8 +258,7 @@ describeServeBuilder( async ({ result }) => { expect(result?.success).toBeTrue(); - // Wait for page to reload. - await setTimeoutPromise(500); + await waitForAppLiveReload(page); const innerText = await page.evaluate( () => document.querySelector('p').innerText, @@ -281,8 +300,7 @@ describeServeBuilder( async ({ result }) => { expect(result?.success).toBeTrue(); - // Wait for page to reload. - await setTimeoutPromise(500); + await waitForAppLiveReload(page); const innerText = await page.evaluate( () => document.querySelector('p').innerText, From 150361238aa337aad8201659e4d77562cc43869a Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 9 Sep 2026 13:50:48 +0000 Subject: [PATCH 3/3] test(@angular/build): fix flakiness in dev-server rebuild error detection test --- .../builders/dev-server/tests/behavior/build-errors_spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts index 9608e0dc976e..a17c0a198e14 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts @@ -38,8 +38,8 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT expectNoLog(logs, 'Unexpected character "EOF"'); }, ], - { outputLogsOnFailure: false }, + { outputLogsOnFailure: false, timeout: 60_000 }, ); - }); + }, 90_000); }); });