From 38634de4c9d248198de93dca36607ef61effa657 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 30 Oct 2026 08:31:07 +0000 Subject: [PATCH 1/2] test: improve E2E test cleanup and assertion reliability --- tests/e2e.bzl | 2 + .../tests/architect_cli/direct_execution.ts | 2 +- .../config/config-global-validation.ts | 16 +++-- .../tests/commands/config/config-global.ts | 61 ++++++++++--------- .../serve/ssr-http-requests-assets.ts | 2 +- .../generate/component/component-child-dir.ts | 3 +- tests/e2e/tests/mcp/ai-tutor.ts | 21 ++++--- tests/e2e/tests/mcp/best-practices.ts | 27 ++++---- tests/e2e/tests/mcp/registers-tools.ts | 4 +- 9 files changed, 79 insertions(+), 59 deletions(-) diff --git a/tests/e2e.bzl b/tests/e2e.bzl index 6ea4a20275c1..d9df24b023df 100644 --- a/tests/e2e.bzl +++ b/tests/e2e.bzl @@ -59,6 +59,8 @@ WEBPACK_IGNORE_TESTS = [ "tests/build/chunk-optimizer-heuristic.js", "tests/build/chunk-optimizer-env.js", "tests/build/chunk-optimizer-animations.js", + "tests/build/prerender/error-component-render.js", + "tests/build/unix-esbuild-unsupported.js", ] def _to_glob(patterns): diff --git a/tests/e2e/tests/architect_cli/direct_execution.ts b/tests/e2e/tests/architect_cli/direct_execution.ts index b91010d46283..534c5c6f962d 100644 --- a/tests/e2e/tests/architect_cli/direct_execution.ts +++ b/tests/e2e/tests/architect_cli/direct_execution.ts @@ -1,4 +1,4 @@ -import * as assert from 'node:assert/strict'; +import assert from 'node:assert/strict'; import { exec } from '../../utils/process'; import { join } from 'node:path'; diff --git a/tests/e2e/tests/commands/config/config-global-validation.ts b/tests/e2e/tests/commands/config/config-global-validation.ts index 39fa611075a9..85be4d5b9f6c 100644 --- a/tests/e2e/tests/commands/config/config-global-validation.ts +++ b/tests/e2e/tests/commands/config/config-global-validation.ts @@ -1,6 +1,6 @@ import assert from 'node:assert/strict'; import { homedir } from 'node:os'; -import * as path from 'node:path'; +import { join } from 'node:path'; import { deleteFile, expectFileToExist } from '../../../utils/fs'; import { ng, silentNg } from '../../../utils/process'; import { expectToFail } from '../../../utils/utils'; @@ -22,10 +22,14 @@ export default async function () { ngError = await expectToFail(() => silentNg('config', 'cli.completion.prompted')); assert.match(ngError.message, /Value cannot be found\./); - await ng('config', '--global', 'cli.completion.prompted', 'true'); - const { stdout } = await silentNg('config', '--global', 'cli.completion.prompted'); - assert.match(stdout, /true/); + const globalConfigPath = join(homedir(), '.angular-config.json'); + try { + await ng('config', '--global', 'cli.completion.prompted', 'true'); + const { stdout } = await silentNg('config', '--global', 'cli.completion.prompted'); + assert.match(stdout, /true/); - await expectFileToExist(path.join(homedir(), '.angular-config.json')); - await deleteFile(path.join(homedir(), '.angular-config.json')); + await expectFileToExist(globalConfigPath); + } finally { + await deleteFile(globalConfigPath).catch(() => {}); + } } diff --git a/tests/e2e/tests/commands/config/config-global.ts b/tests/e2e/tests/commands/config/config-global.ts index 030d4b583d2c..c12c195de3fa 100644 --- a/tests/e2e/tests/commands/config/config-global.ts +++ b/tests/e2e/tests/commands/config/config-global.ts @@ -1,42 +1,47 @@ import assert from 'node:assert/strict'; import { homedir } from 'node:os'; -import * as path from 'node:path'; +import { join } from 'node:path'; import { deleteFile, expectFileToExist } from '../../../utils/fs'; import { ng } from '../../../utils/process'; import { expectToFail } from '../../../utils/utils'; export default async function () { - await expectToFail(() => - ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle'), - ); + const globalConfigPath = join(homedir(), '.angular-config.json'); - await ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle', 'false'); - let output = await ng( - 'config', - '--global', - 'schematics.@schematics/angular.component.inlineStyle', - ); - assert.match(output.stdout, /false\n?/); + try { + await expectToFail(() => + ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle'), + ); - // This test requires schema querying capabilities - // .then(() => expectToFail(() => { - // return ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle', 'INVALID_BOOLEAN'); - // })) + await ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle', 'false'); + let output = await ng( + 'config', + '--global', + 'schematics.@schematics/angular.component.inlineStyle', + ); + assert.match(output.stdout, /false\n?/); - const cwd = process.cwd(); - process.chdir('/'); - try { - await ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle', 'true'); - } finally { - process.chdir(cwd); - } + const cwd = process.cwd(); + process.chdir('/'); + try { + await ng( + 'config', + '--global', + 'schematics.@schematics/angular.component.inlineStyle', + 'true', + ); + } finally { + process.chdir(cwd); + } - output = await ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle'); - assert.match(output.stdout, /true\n?/); + output = await ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle'); + assert.match(output.stdout, /true\n?/); - await expectToFail(() => ng('config', '--global', 'cli.warnings.notreal', 'true')); + await expectToFail(() => ng('config', '--global', 'cli.warnings.notreal', 'true')); - await ng('config', '--global', 'cli.warnings.versionMismatch', 'false'); - await expectFileToExist(path.join(homedir(), '.angular-config.json')); - await deleteFile(path.join(homedir(), '.angular-config.json')); + await ng('config', '--global', 'cli.warnings.versionMismatch', 'false'); + await expectFileToExist(globalConfigPath); + } finally { + await deleteFile(globalConfigPath).catch(() => {}); + } } diff --git a/tests/e2e/tests/commands/serve/ssr-http-requests-assets.ts b/tests/e2e/tests/commands/serve/ssr-http-requests-assets.ts index 1e8e7853a718..3b3011b088a0 100644 --- a/tests/e2e/tests/commands/serve/ssr-http-requests-assets.ts +++ b/tests/e2e/tests/commands/serve/ssr-http-requests-assets.ts @@ -88,7 +88,7 @@ export default async function () { await killAllProcesses(); // With OpenSSl cert+key - writeMultipleFiles({ + await writeMultipleFiles({ 'server.key': `-----BEGIN PRIVATE KEY----- MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDOyBmVy61zEqfs oTPQ9gTX233/nlrVXtaUGJkbDR5actq0X+XQtZuIoO4JgRpiYz5/8XiY8AiaMdt3 diff --git a/tests/e2e/tests/generate/component/component-child-dir.ts b/tests/e2e/tests/generate/component/component-child-dir.ts index 6c7dc7506bab..e6ce6577a07a 100644 --- a/tests/e2e/tests/generate/component/component-child-dir.ts +++ b/tests/e2e/tests/generate/component/component-child-dir.ts @@ -14,7 +14,7 @@ export default async function () { // Generate a component inside the child directory await ng('generate', 'component', 'test-component'); - // Move back to the root of the workspacee + // Move back to the root of the workspace process.chdir(currentDirectory); // Ensure component is created in the correct location relative to the workspace root @@ -27,6 +27,7 @@ export default async function () { // Ensure unit test execute and pass await ng('test', '--watch=false'); } finally { + process.chdir(currentDirectory); // Windows CI may fail to clean up the created directory // Resolves: "Error: Running "cmd.exe /c git clean -df" returned error code 1" await rimraf(childDirectory); diff --git a/tests/e2e/tests/mcp/ai-tutor.ts b/tests/e2e/tests/mcp/ai-tutor.ts index 220b32fcc202..ed4d51a20c14 100644 --- a/tests/e2e/tests/mcp/ai-tutor.ts +++ b/tests/e2e/tests/mcp/ai-tutor.ts @@ -1,4 +1,3 @@ -import { chdir } from 'node:process'; import { exec, ProcessOutput, silentNpm } from '../../utils/process'; import assert from 'node:assert/strict'; @@ -28,13 +27,17 @@ export default async function () { `${MCP_INSPECTOR_PACKAGE_NAME}@${MCP_INSPECTOR_PACKAGE_VERSION}`, ); - // Ensure `get_best_practices` returns the markdown content - const { stdout: stdoutInsideWorkspace } = await runInspector( - '--method', - 'tools/call', - '--tool-name', - 'ai_tutor', - ); + try { + // Ensure `get_best_practices` returns the markdown content + const { stdout: stdoutInsideWorkspace } = await runInspector( + '--method', + 'tools/call', + '--tool-name', + 'ai_tutor', + ); - assert.match(stdoutInsideWorkspace, /# `airules.md` - Modern Angular Tutor 🧑‍🏫/); + assert.match(stdoutInsideWorkspace, /# `airules.md` - Modern Angular Tutor 🧑‍🏫/); + } finally { + await silentNpm('uninstall', '-g', MCP_INSPECTOR_PACKAGE_NAME); + } } diff --git a/tests/e2e/tests/mcp/best-practices.ts b/tests/e2e/tests/mcp/best-practices.ts index 55736c63795b..ba83733446dc 100644 --- a/tests/e2e/tests/mcp/best-practices.ts +++ b/tests/e2e/tests/mcp/best-practices.ts @@ -1,4 +1,3 @@ -import { chdir } from 'node:process'; import { exec, ProcessOutput, silentNpm } from '../../utils/process'; import assert from 'node:assert/strict'; @@ -28,16 +27,20 @@ export default async function () { `${MCP_INSPECTOR_PACKAGE_NAME}@${MCP_INSPECTOR_PACKAGE_VERSION}`, ); - // Ensure `get_best_practices` returns the markdown content - const { stdout: stdoutInsideWorkspace } = await runInspector( - '--method', - 'tools/call', - '--tool-name', - 'get_best_practices', - ); + try { + // Ensure `get_best_practices` returns the markdown content + const { stdout: stdoutInsideWorkspace } = await runInspector( + '--method', + 'tools/call', + '--tool-name', + 'get_best_practices', + ); - assert.match( - stdoutInsideWorkspace, - /You are an expert in TypeScript, Angular, and scalable web application development./, - ); + assert.match( + stdoutInsideWorkspace, + /You are an expert in TypeScript, Angular, and scalable web application development./, + ); + } finally { + await silentNpm('uninstall', '-g', MCP_INSPECTOR_PACKAGE_NAME); + } } diff --git a/tests/e2e/tests/mcp/registers-tools.ts b/tests/e2e/tests/mcp/registers-tools.ts index abc76a99f5d7..97e04459f440 100644 --- a/tests/e2e/tests/mcp/registers-tools.ts +++ b/tests/e2e/tests/mcp/registers-tools.ts @@ -28,6 +28,7 @@ export default async function () { `${MCP_INSPECTOR_PACKAGE_NAME}@${MCP_INSPECTOR_PACKAGE_VERSION}`, ); + const initialCwd = process.cwd(); // Ensure 'list_projects' is registered when inside an Angular workspace try { const { stdout: stdoutInsideWorkspace } = await runInspector('--method', 'tools/list'); @@ -42,8 +43,9 @@ export default async function () { assert.match(stdoutOutsideWorkspace, /"list_projects"/); assert.match(stdoutOutsideWorkspace, /"get_best_practices"/); - assert.match(stdoutInsideWorkspace, /"search_documentation"/); + assert.match(stdoutOutsideWorkspace, /"search_documentation"/); } finally { + chdir(initialCwd); await silentNpm('uninstall', '-g', MCP_INSPECTOR_PACKAGE_NAME); } } From 3f7131dc1053388b30b6fa6b228c531d09454eb4 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 30 Oct 2026 16:37:26 +0000 Subject: [PATCH 2/2] fixup! test: improve E2E test cleanup and assertion reliability --- tests/e2e.bzl | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e.bzl b/tests/e2e.bzl index d9df24b023df..6ff420ac176c 100644 --- a/tests/e2e.bzl +++ b/tests/e2e.bzl @@ -60,7 +60,6 @@ WEBPACK_IGNORE_TESTS = [ "tests/build/chunk-optimizer-env.js", "tests/build/chunk-optimizer-animations.js", "tests/build/prerender/error-component-render.js", - "tests/build/unix-esbuild-unsupported.js", ] def _to_glob(patterns):