From 83cc5d1e4580c111c6c949d603f017a7ea50721c Mon Sep 17 00:00:00 2001 From: Brian Love Date: Tue, 19 May 2026 20:16:58 -0700 Subject: [PATCH] test(cockpit-deep-agents): aimock e2e for all 6 deep-agents caps Final product line. Brings cockpit aimock coverage to 24 of 32 caps (75%). All 6 deep-agents caps use composed , same shape as the langgraph caps: - da-planning, da-filesystem, da-subagents, da-memory, da-skills, da-sandboxes. Fixtures recorded via scripts/record-aimock-cap.sh; specs send "Hello" and assert the assistant bubble renders (smoke-level end-to-end coverage per cap). Registry + proxy changes: adds pythonPort to all 6 deep-agents caps (5310-5315) and aligns proxy.conf.json with the new ports. Same convention chat and langgraph caps follow. Coverage after this PR + #483 (render gap doc) merging: - Chat: 10/11 + c-debug documented = 11/11 handled. - Langgraph: 8/8. - Deep-agents: 6/6. - Render: 0/6 (aimock not applicable; documented in #483). - ag-ui-streaming: 0/1 (no Python backend by design). Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 6 ++++++ apps/cockpit/scripts/capability-registry.ts | 12 ++++++------ .../angular/e2e/da-filesystem.spec.ts | 8 ++++++++ .../angular/e2e/fixtures/da-filesystem.json | 12 ++++++++++++ .../angular/e2e/global-setup-impl.ts | 11 +++++++++++ .../angular/e2e/playwright.config.ts | 18 ++++++++++++++++++ .../filesystem/angular/e2e/tsconfig.json | 14 ++++++++++++++ .../filesystem/angular/project.json | 6 ++++++ .../filesystem/angular/proxy.conf.json | 6 ++++-- .../memory/angular/e2e/da-memory.spec.ts | 8 ++++++++ .../memory/angular/e2e/fixtures/da-memory.json | 18 ++++++++++++++++++ .../memory/angular/e2e/global-setup-impl.ts | 11 +++++++++++ .../memory/angular/e2e/playwright.config.ts | 18 ++++++++++++++++++ .../memory/angular/e2e/tsconfig.json | 14 ++++++++++++++ .../deep-agents/memory/angular/project.json | 6 ++++++ .../deep-agents/memory/angular/proxy.conf.json | 6 ++++-- .../planning/angular/e2e/da-planning.spec.ts | 8 ++++++++ .../angular/e2e/fixtures/da-planning.json | 18 ++++++++++++++++++ .../planning/angular/e2e/global-setup-impl.ts | 11 +++++++++++ .../planning/angular/e2e/playwright.config.ts | 18 ++++++++++++++++++ .../planning/angular/e2e/tsconfig.json | 14 ++++++++++++++ .../deep-agents/planning/angular/project.json | 6 ++++++ .../planning/angular/proxy.conf.json | 6 ++++-- .../sandboxes/angular/e2e/da-sandboxes.spec.ts | 8 ++++++++ .../angular/e2e/fixtures/da-sandboxes.json | 12 ++++++++++++ .../sandboxes/angular/e2e/global-setup-impl.ts | 11 +++++++++++ .../sandboxes/angular/e2e/playwright.config.ts | 18 ++++++++++++++++++ .../sandboxes/angular/e2e/tsconfig.json | 14 ++++++++++++++ .../deep-agents/sandboxes/angular/project.json | 6 ++++++ .../sandboxes/angular/proxy.conf.json | 6 ++++-- .../skills/angular/e2e/da-skills.spec.ts | 8 ++++++++ .../skills/angular/e2e/fixtures/da-skills.json | 12 ++++++++++++ .../skills/angular/e2e/global-setup-impl.ts | 11 +++++++++++ .../skills/angular/e2e/playwright.config.ts | 18 ++++++++++++++++++ .../skills/angular/e2e/tsconfig.json | 14 ++++++++++++++ .../deep-agents/skills/angular/project.json | 6 ++++++ .../deep-agents/skills/angular/proxy.conf.json | 6 ++++-- .../subagents/angular/e2e/da-subagents.spec.ts | 8 ++++++++ .../angular/e2e/fixtures/da-subagents.json | 18 ++++++++++++++++++ .../subagents/angular/e2e/global-setup-impl.ts | 11 +++++++++++ .../subagents/angular/e2e/playwright.config.ts | 18 ++++++++++++++++++ .../subagents/angular/e2e/tsconfig.json | 14 ++++++++++++++ .../deep-agents/subagents/angular/project.json | 6 ++++++ .../subagents/angular/proxy.conf.json | 6 ++++-- 44 files changed, 468 insertions(+), 18 deletions(-) create mode 100644 cockpit/deep-agents/filesystem/angular/e2e/da-filesystem.spec.ts create mode 100644 cockpit/deep-agents/filesystem/angular/e2e/fixtures/da-filesystem.json create mode 100644 cockpit/deep-agents/filesystem/angular/e2e/global-setup-impl.ts create mode 100644 cockpit/deep-agents/filesystem/angular/e2e/playwright.config.ts create mode 100644 cockpit/deep-agents/filesystem/angular/e2e/tsconfig.json create mode 100644 cockpit/deep-agents/memory/angular/e2e/da-memory.spec.ts create mode 100644 cockpit/deep-agents/memory/angular/e2e/fixtures/da-memory.json create mode 100644 cockpit/deep-agents/memory/angular/e2e/global-setup-impl.ts create mode 100644 cockpit/deep-agents/memory/angular/e2e/playwright.config.ts create mode 100644 cockpit/deep-agents/memory/angular/e2e/tsconfig.json create mode 100644 cockpit/deep-agents/planning/angular/e2e/da-planning.spec.ts create mode 100644 cockpit/deep-agents/planning/angular/e2e/fixtures/da-planning.json create mode 100644 cockpit/deep-agents/planning/angular/e2e/global-setup-impl.ts create mode 100644 cockpit/deep-agents/planning/angular/e2e/playwright.config.ts create mode 100644 cockpit/deep-agents/planning/angular/e2e/tsconfig.json create mode 100644 cockpit/deep-agents/sandboxes/angular/e2e/da-sandboxes.spec.ts create mode 100644 cockpit/deep-agents/sandboxes/angular/e2e/fixtures/da-sandboxes.json create mode 100644 cockpit/deep-agents/sandboxes/angular/e2e/global-setup-impl.ts create mode 100644 cockpit/deep-agents/sandboxes/angular/e2e/playwright.config.ts create mode 100644 cockpit/deep-agents/sandboxes/angular/e2e/tsconfig.json create mode 100644 cockpit/deep-agents/skills/angular/e2e/da-skills.spec.ts create mode 100644 cockpit/deep-agents/skills/angular/e2e/fixtures/da-skills.json create mode 100644 cockpit/deep-agents/skills/angular/e2e/global-setup-impl.ts create mode 100644 cockpit/deep-agents/skills/angular/e2e/playwright.config.ts create mode 100644 cockpit/deep-agents/skills/angular/e2e/tsconfig.json create mode 100644 cockpit/deep-agents/subagents/angular/e2e/da-subagents.spec.ts create mode 100644 cockpit/deep-agents/subagents/angular/e2e/fixtures/da-subagents.json create mode 100644 cockpit/deep-agents/subagents/angular/e2e/global-setup-impl.ts create mode 100644 cockpit/deep-agents/subagents/angular/e2e/playwright.config.ts create mode 100644 cockpit/deep-agents/subagents/angular/e2e/tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27c3de438..2492937fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -284,6 +284,12 @@ jobs: - { angular: cockpit-langgraph-subgraphs-angular, python: cockpit/langgraph/subgraphs/python } - { angular: cockpit-langgraph-time-travel-angular, python: cockpit/langgraph/time-travel/python } - { angular: cockpit-langgraph-deployment-runtime-angular, python: cockpit/langgraph/deployment-runtime/python } + - { angular: cockpit-deep-agents-planning-angular, python: cockpit/deep-agents/planning/python } + - { angular: cockpit-deep-agents-filesystem-angular, python: cockpit/deep-agents/filesystem/python } + - { angular: cockpit-deep-agents-subagents-angular, python: cockpit/deep-agents/subagents/python } + - { angular: cockpit-deep-agents-memory-angular, python: cockpit/deep-agents/memory/python } + - { angular: cockpit-deep-agents-skills-angular, python: cockpit/deep-agents/skills/python } + - { angular: cockpit-deep-agents-sandboxes-angular, python: cockpit/deep-agents/sandboxes/python } steps: - uses: actions/checkout@v6.0.2 - uses: actions/setup-node@v6.3.0 diff --git a/apps/cockpit/scripts/capability-registry.ts b/apps/cockpit/scripts/capability-registry.ts index 077ba68a4..88b9af3b1 100644 --- a/apps/cockpit/scripts/capability-registry.ts +++ b/apps/cockpit/scripts/capability-registry.ts @@ -24,12 +24,12 @@ export const capabilities: readonly Capability[] = [ { id: 'subgraphs', product: 'langgraph', topic: 'subgraphs', angularProject: 'cockpit-langgraph-subgraphs-angular', port: 4305, pythonPort: 5305, pythonDir: 'cockpit/langgraph/subgraphs/python', graphName: 'subgraphs' }, { id: 'time-travel', product: 'langgraph', topic: 'time-travel', angularProject: 'cockpit-langgraph-time-travel-angular', port: 4306, pythonPort: 5306, pythonDir: 'cockpit/langgraph/time-travel/python', graphName: 'time-travel' }, { id: 'deployment-runtime', product: 'langgraph', topic: 'deployment-runtime', angularProject: 'cockpit-langgraph-deployment-runtime-angular', port: 4307, pythonPort: 5307, pythonDir: 'cockpit/langgraph/deployment-runtime/python', graphName: 'deployment-runtime' }, - { id: 'da-planning', product: 'deep-agents', topic: 'planning', angularProject: 'cockpit-deep-agents-planning-angular', port: 4310, pythonDir: 'cockpit/deep-agents/planning/python', graphName: 'da-planning' }, - { id: 'da-filesystem', product: 'deep-agents', topic: 'filesystem', angularProject: 'cockpit-deep-agents-filesystem-angular', port: 4311, pythonDir: 'cockpit/deep-agents/filesystem/python', graphName: 'da-filesystem' }, - { id: 'da-subagents', product: 'deep-agents', topic: 'subagents', angularProject: 'cockpit-deep-agents-subagents-angular', port: 4312, pythonDir: 'cockpit/deep-agents/subagents/python', graphName: 'subagents' }, - { id: 'da-memory', product: 'deep-agents', topic: 'memory', angularProject: 'cockpit-deep-agents-memory-angular', port: 4313, pythonDir: 'cockpit/deep-agents/memory/python', graphName: 'da-memory' }, - { id: 'da-skills', product: 'deep-agents', topic: 'skills', angularProject: 'cockpit-deep-agents-skills-angular', port: 4314, pythonDir: 'cockpit/deep-agents/skills/python', graphName: 'da-skills' }, - { id: 'da-sandboxes', product: 'deep-agents', topic: 'sandboxes', angularProject: 'cockpit-deep-agents-sandboxes-angular', port: 4315, pythonDir: 'cockpit/deep-agents/sandboxes/python', graphName: 'da-sandboxes' }, + { id: 'da-planning', product: 'deep-agents', topic: 'planning', angularProject: 'cockpit-deep-agents-planning-angular', port: 4310, pythonPort: 5310, pythonDir: 'cockpit/deep-agents/planning/python', graphName: 'da-planning' }, + { id: 'da-filesystem', product: 'deep-agents', topic: 'filesystem', angularProject: 'cockpit-deep-agents-filesystem-angular', port: 4311, pythonPort: 5311, pythonDir: 'cockpit/deep-agents/filesystem/python', graphName: 'da-filesystem' }, + { id: 'da-subagents', product: 'deep-agents', topic: 'subagents', angularProject: 'cockpit-deep-agents-subagents-angular', port: 4312, pythonPort: 5312, pythonDir: 'cockpit/deep-agents/subagents/python', graphName: 'subagents' }, + { id: 'da-memory', product: 'deep-agents', topic: 'memory', angularProject: 'cockpit-deep-agents-memory-angular', port: 4313, pythonPort: 5313, pythonDir: 'cockpit/deep-agents/memory/python', graphName: 'da-memory' }, + { id: 'da-skills', product: 'deep-agents', topic: 'skills', angularProject: 'cockpit-deep-agents-skills-angular', port: 4314, pythonPort: 5314, pythonDir: 'cockpit/deep-agents/skills/python', graphName: 'da-skills' }, + { id: 'da-sandboxes', product: 'deep-agents', topic: 'sandboxes', angularProject: 'cockpit-deep-agents-sandboxes-angular', port: 4315, pythonPort: 5315, pythonDir: 'cockpit/deep-agents/sandboxes/python', graphName: 'da-sandboxes' }, // Render capabilities { id: 'r-spec-rendering', product: 'render', topic: 'spec-rendering', angularProject: 'cockpit-render-spec-rendering-angular', port: 4401, pythonDir: 'cockpit/render/spec-rendering/python', graphName: 'r-spec-rendering' }, { id: 'r-element-rendering', product: 'render', topic: 'element-rendering', angularProject: 'cockpit-render-element-rendering-angular', port: 4402, pythonDir: 'cockpit/render/element-rendering/python', graphName: 'r-element-rendering' }, diff --git a/cockpit/deep-agents/filesystem/angular/e2e/da-filesystem.spec.ts b/cockpit/deep-agents/filesystem/angular/e2e/da-filesystem.spec.ts new file mode 100644 index 000000000..c982b6a69 --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/da-filesystem.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-filesystem: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/filesystem/angular/e2e/fixtures/da-filesystem.json b/cockpit/deep-agents/filesystem/angular/e2e/fixtures/da-filesystem.json new file mode 100644 index 000000000..a5bccfada --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/fixtures/da-filesystem.json @@ -0,0 +1,12 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "Hello! How can I help you today? I can read or write files in the workspace\u2014tell me what you'd like to do (e.g., \"read file /path/to/file\" or \"write file /path/to/file with content ...\")." + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/filesystem/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/filesystem/angular/e2e/global-setup-impl.ts new file mode 100644 index 000000000..c951c32fe --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/filesystem/python', + langgraphPort: 5311, + angularProject: 'cockpit-deep-agents-filesystem-angular', + angularPort: 4311, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/filesystem/angular/e2e/playwright.config.ts b/cockpit/deep-agents/filesystem/angular/e2e/playwright.config.ts new file mode 100644 index 000000000..972651491 --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/playwright.config.ts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: '.', + testMatch: '**/*.spec.ts', + fullyParallel: false, + workers: 1, + retries: process.env.CI ? 2 : 0, + reporter: process.env.CI ? [['list'], ['html', { open: 'never' }]] : 'list', + use: { + baseURL: 'http://localhost:4311', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/filesystem/angular/e2e/tsconfig.json b/cockpit/deep-agents/filesystem/angular/e2e/tsconfig.json new file mode 100644 index 000000000..0b5aeecbf --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/filesystem/angular/project.json b/cockpit/deep-agents/filesystem/angular/project.json index 649cf78ea..2ee3af065 100644 --- a/cockpit/deep-agents/filesystem/angular/project.json +++ b/cockpit/deep-agents/filesystem/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsFilesystemAngularModule } from './cockpit/deep-agents/filesystem/angular/src/index.ts'; const mod = deepAgentsFilesystemAngularModule; if (mod.id !== 'deep-agents-filesystem-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Filesystem (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/filesystem/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/filesystem/angular/proxy.conf.json b/cockpit/deep-agents/filesystem/angular/proxy.conf.json index 8523362d7..3068de091 100644 --- a/cockpit/deep-agents/filesystem/angular/proxy.conf.json +++ b/cockpit/deep-agents/filesystem/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5311", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/memory/angular/e2e/da-memory.spec.ts b/cockpit/deep-agents/memory/angular/e2e/da-memory.spec.ts new file mode 100644 index 000000000..0b281ceb1 --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/da-memory.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-memory: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/memory/angular/e2e/fixtures/da-memory.json b/cockpit/deep-agents/memory/angular/e2e/fixtures/da-memory.json new file mode 100644 index 000000000..4bc44176f --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/fixtures/da-memory.json @@ -0,0 +1,18 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "Hi \u2014 hello! How can I help you today?" + } + }, + { + "match": {}, + "response": { + "content": "{}" + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/memory/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/memory/angular/e2e/global-setup-impl.ts new file mode 100644 index 000000000..d39996c18 --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/memory/python', + langgraphPort: 5313, + angularProject: 'cockpit-deep-agents-memory-angular', + angularPort: 4313, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/memory/angular/e2e/playwright.config.ts b/cockpit/deep-agents/memory/angular/e2e/playwright.config.ts new file mode 100644 index 000000000..08bdb31ba --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/playwright.config.ts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: '.', + testMatch: '**/*.spec.ts', + fullyParallel: false, + workers: 1, + retries: process.env.CI ? 2 : 0, + reporter: process.env.CI ? [['list'], ['html', { open: 'never' }]] : 'list', + use: { + baseURL: 'http://localhost:4313', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/memory/angular/e2e/tsconfig.json b/cockpit/deep-agents/memory/angular/e2e/tsconfig.json new file mode 100644 index 000000000..0b5aeecbf --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/memory/angular/project.json b/cockpit/deep-agents/memory/angular/project.json index 3a7df8372..b3f08ea6f 100644 --- a/cockpit/deep-agents/memory/angular/project.json +++ b/cockpit/deep-agents/memory/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsMemoryAngularModule } from './cockpit/deep-agents/memory/angular/src/index.ts'; const mod = deepAgentsMemoryAngularModule; if (mod.id !== 'deep-agents-memory-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Memory (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/memory/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/memory/angular/proxy.conf.json b/cockpit/deep-agents/memory/angular/proxy.conf.json index 8523362d7..020a0ca44 100644 --- a/cockpit/deep-agents/memory/angular/proxy.conf.json +++ b/cockpit/deep-agents/memory/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5313", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/planning/angular/e2e/da-planning.spec.ts b/cockpit/deep-agents/planning/angular/e2e/da-planning.spec.ts new file mode 100644 index 000000000..8d34bea08 --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/da-planning.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-planning: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/planning/angular/e2e/fixtures/da-planning.json b/cockpit/deep-agents/planning/angular/e2e/fixtures/da-planning.json new file mode 100644 index 000000000..e968eb99a --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/fixtures/da-planning.json @@ -0,0 +1,18 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "[{\"title\":\"Respond with a friendly greeting\",\"status\":\"pending\"},{\"title\":\"Ask how I can help\",\"status\":\"pending\"},{\"title\":\"Give examples of what I can do\",\"status\":\"pending\"},{\"title\":\"Suggest next steps/questions\",\"status\":\"pending\"}]\n\nStep 1 \u2014 Respond with a friendly greeting (completed):\nHello! Nice to meet you.\n\nStep 2 \u2014 Ask how I can help (completed):\nHow can I help you today?\n\nStep 3 \u2014 Give examples of what I can do (completed):\n- Answer questions or explain concepts\n- Help write or edit email, essays, or code\n- Brainstorm ideas or outline plans\n- Summarize articles or long text\n- Translate or proofread text\n- Solve math problems or debug code\n\nStep 4 \u2014 Suggest next steps/questions (completed):\nYou can tell me what you need right now (a question, a task, or a topic). If you prefer, pick one of the examples above and I\u2019ll get started." + } + }, + { + "match": {}, + "response": { + "content": "Plan (4 steps)\n1. Ask what you need.\n2. Clarify scope, format, and any constraints (deadline, length, tone, audience).\n3. Offer examples of how I can help and suggest a concrete first deliverable.\n4. Confirm and begin work.\n\nExecution\nStep 1 \u2014 Ask what you need:\nWhat would you like me to do right now?\n\nStep 2 \u2014 Clarify scope and constraints:\nIf you already have something specific, tell me: the goal, desired format (email, essay, code, plan, summary, slides, etc.), length, tone (formal/casual), audience, and any deadline. If you don\u2019t have constraints, say so.\n\nStep 3 \u2014 Examples and a suggested first deliverable:\nHere are quick examples of tasks I can do \u2014 pick one or describe your own:\n- Write or edit an email (provide recipient/context and key points).\n- Draft an essay or article (topic, thesis, word count).\n- Create a project plan or roadmap (objective, timeline).\n- Summarize an article or document (paste text or upload).\n- Debug or write code (language, repo/files, expected behavior).\n- Brainstorm ideas (product names, marketing angles, meeting agendas).\n\nSuggested first deliverable: I can produce a short sample (e.g., a 150\u2013300 word draft, a 5-item plan, or a 1-paragraph summary) so you can confirm style before I expand.\n\nStep 4 \u2014 Confirm and begin:\nTell me which task you want and any constraints, or choose one of the examples above. I\u2019ll start immediately." + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/planning/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/planning/angular/e2e/global-setup-impl.ts new file mode 100644 index 000000000..8eced5168 --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/planning/python', + langgraphPort: 5310, + angularProject: 'cockpit-deep-agents-planning-angular', + angularPort: 4310, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/planning/angular/e2e/playwright.config.ts b/cockpit/deep-agents/planning/angular/e2e/playwright.config.ts new file mode 100644 index 000000000..976b82461 --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/playwright.config.ts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: '.', + testMatch: '**/*.spec.ts', + fullyParallel: false, + workers: 1, + retries: process.env.CI ? 2 : 0, + reporter: process.env.CI ? [['list'], ['html', { open: 'never' }]] : 'list', + use: { + baseURL: 'http://localhost:4310', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/planning/angular/e2e/tsconfig.json b/cockpit/deep-agents/planning/angular/e2e/tsconfig.json new file mode 100644 index 000000000..0b5aeecbf --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/planning/angular/project.json b/cockpit/deep-agents/planning/angular/project.json index 42f115982..ce8ea0b69 100644 --- a/cockpit/deep-agents/planning/angular/project.json +++ b/cockpit/deep-agents/planning/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsPlanningAngularModule } from './cockpit/deep-agents/planning/angular/src/index.ts'; const mod = deepAgentsPlanningAngularModule; if (mod.id !== 'deep-agents-planning-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Planning (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/planning/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/planning/angular/proxy.conf.json b/cockpit/deep-agents/planning/angular/proxy.conf.json index 8523362d7..2c71ffe1d 100644 --- a/cockpit/deep-agents/planning/angular/proxy.conf.json +++ b/cockpit/deep-agents/planning/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5310", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/da-sandboxes.spec.ts b/cockpit/deep-agents/sandboxes/angular/e2e/da-sandboxes.spec.ts new file mode 100644 index 000000000..f57a22168 --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/da-sandboxes.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-sandboxes: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/fixtures/da-sandboxes.json b/cockpit/deep-agents/sandboxes/angular/e2e/fixtures/da-sandboxes.json new file mode 100644 index 000000000..8766ff233 --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/fixtures/da-sandboxes.json @@ -0,0 +1,12 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "Hello! How can I help you today?" + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/sandboxes/angular/e2e/global-setup-impl.ts new file mode 100644 index 000000000..2c61115f3 --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/sandboxes/python', + langgraphPort: 5315, + angularProject: 'cockpit-deep-agents-sandboxes-angular', + angularPort: 4315, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/playwright.config.ts b/cockpit/deep-agents/sandboxes/angular/e2e/playwright.config.ts new file mode 100644 index 000000000..2f07e56c9 --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/playwright.config.ts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: '.', + testMatch: '**/*.spec.ts', + fullyParallel: false, + workers: 1, + retries: process.env.CI ? 2 : 0, + reporter: process.env.CI ? [['list'], ['html', { open: 'never' }]] : 'list', + use: { + baseURL: 'http://localhost:4315', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/tsconfig.json b/cockpit/deep-agents/sandboxes/angular/e2e/tsconfig.json new file mode 100644 index 000000000..0b5aeecbf --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/sandboxes/angular/project.json b/cockpit/deep-agents/sandboxes/angular/project.json index 9b9f1ab66..948acc5f7 100644 --- a/cockpit/deep-agents/sandboxes/angular/project.json +++ b/cockpit/deep-agents/sandboxes/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsSandboxesAngularModule } from './cockpit/deep-agents/sandboxes/angular/src/index.ts'; const mod = deepAgentsSandboxesAngularModule; if (mod.id !== 'deep-agents-sandboxes-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Sandboxes (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/sandboxes/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/sandboxes/angular/proxy.conf.json b/cockpit/deep-agents/sandboxes/angular/proxy.conf.json index 8523362d7..c20d5a91a 100644 --- a/cockpit/deep-agents/sandboxes/angular/proxy.conf.json +++ b/cockpit/deep-agents/sandboxes/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5315", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/skills/angular/e2e/da-skills.spec.ts b/cockpit/deep-agents/skills/angular/e2e/da-skills.spec.ts new file mode 100644 index 000000000..51f60c011 --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/da-skills.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-skills: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/skills/angular/e2e/fixtures/da-skills.json b/cockpit/deep-agents/skills/angular/e2e/fixtures/da-skills.json new file mode 100644 index 000000000..210889f44 --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/fixtures/da-skills.json @@ -0,0 +1,12 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "Hello! How can I help you today? I can evaluate math expressions, count words in a text, or summarize content \u2014 which would you like?" + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/skills/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/skills/angular/e2e/global-setup-impl.ts new file mode 100644 index 000000000..bcf16b965 --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/skills/python', + langgraphPort: 5314, + angularProject: 'cockpit-deep-agents-skills-angular', + angularPort: 4314, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/skills/angular/e2e/playwright.config.ts b/cockpit/deep-agents/skills/angular/e2e/playwright.config.ts new file mode 100644 index 000000000..254316004 --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/playwright.config.ts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: '.', + testMatch: '**/*.spec.ts', + fullyParallel: false, + workers: 1, + retries: process.env.CI ? 2 : 0, + reporter: process.env.CI ? [['list'], ['html', { open: 'never' }]] : 'list', + use: { + baseURL: 'http://localhost:4314', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/skills/angular/e2e/tsconfig.json b/cockpit/deep-agents/skills/angular/e2e/tsconfig.json new file mode 100644 index 000000000..0b5aeecbf --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/skills/angular/project.json b/cockpit/deep-agents/skills/angular/project.json index 18cb12bdf..76d9384cc 100644 --- a/cockpit/deep-agents/skills/angular/project.json +++ b/cockpit/deep-agents/skills/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsSkillsAngularModule } from './cockpit/deep-agents/skills/angular/src/index.ts'; const mod = deepAgentsSkillsAngularModule; if (mod.id !== 'deep-agents-skills-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Skills (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/skills/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/skills/angular/proxy.conf.json b/cockpit/deep-agents/skills/angular/proxy.conf.json index 8523362d7..76e30cf6b 100644 --- a/cockpit/deep-agents/skills/angular/proxy.conf.json +++ b/cockpit/deep-agents/skills/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5314", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/subagents/angular/e2e/da-subagents.spec.ts b/cockpit/deep-agents/subagents/angular/e2e/da-subagents.spec.ts new file mode 100644 index 000000000..3d223b387 --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/da-subagents.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-subagents: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/subagents/angular/e2e/fixtures/da-subagents.json b/cockpit/deep-agents/subagents/angular/e2e/fixtures/da-subagents.json new file mode 100644 index 000000000..88d1f4888 --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/fixtures/da-subagents.json @@ -0,0 +1,18 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "toolCalls": [ + { + "name": "research_agent", + "arguments": "{\"topic\":\"How to respond to a simple greeting like 'Hello' in a friendly, concise way; suggested phrasing, tone, and follow-up questions to engage user\"}", + "id": "call_JAuyEoJ5ILdin2rB6kRACMpw" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/subagents/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/subagents/angular/e2e/global-setup-impl.ts new file mode 100644 index 000000000..708d88b88 --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/subagents/python', + langgraphPort: 5312, + angularProject: 'cockpit-deep-agents-subagents-angular', + angularPort: 4312, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/subagents/angular/e2e/playwright.config.ts b/cockpit/deep-agents/subagents/angular/e2e/playwright.config.ts new file mode 100644 index 000000000..b94680ee4 --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/playwright.config.ts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: '.', + testMatch: '**/*.spec.ts', + fullyParallel: false, + workers: 1, + retries: process.env.CI ? 2 : 0, + reporter: process.env.CI ? [['list'], ['html', { open: 'never' }]] : 'list', + use: { + baseURL: 'http://localhost:4312', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/subagents/angular/e2e/tsconfig.json b/cockpit/deep-agents/subagents/angular/e2e/tsconfig.json new file mode 100644 index 000000000..0b5aeecbf --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/subagents/angular/project.json b/cockpit/deep-agents/subagents/angular/project.json index 644ccc00f..819893e6e 100644 --- a/cockpit/deep-agents/subagents/angular/project.json +++ b/cockpit/deep-agents/subagents/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsSubagentsAngularModule } from './cockpit/deep-agents/subagents/angular/src/index.ts'; const mod = deepAgentsSubagentsAngularModule; if (mod.id !== 'deep-agents-subagents-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Subagents (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/subagents/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/subagents/angular/proxy.conf.json b/cockpit/deep-agents/subagents/angular/proxy.conf.json index 8523362d7..8985a469d 100644 --- a/cockpit/deep-agents/subagents/angular/proxy.conf.json +++ b/cockpit/deep-agents/subagents/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5312", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } }