Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions apps/cockpit/scripts/serve-example.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
import { backendCommand, COCKPIT_RUNTIME_ENV } from './serve-example';
import { findCapability, type Capability } from './capability-registry';
import { backendCommand, COCKPIT_RUNTIME_ENV, formatAllModeSummary } from './serve-example';
import { capabilities, findCapability, type Capability } from './capability-registry';

describe('backendCommand', () => {
it('uses uvicorn on the registry pythonPort for ag-ui caps', () => {
Expand Down Expand Up @@ -36,4 +36,9 @@ describe('backendCommand', () => {
it('exposes an empty runtime base URL so the cockpit iframe targets localhost', () => {
expect(COCKPIT_RUNTIME_ENV).toEqual({ NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL: '' });
});

it('formats the all-mode startup summary from the registry count', () => {
expect(formatAllModeSummary()).toBe(`\nStarting cockpit + all ${capabilities.length} examples\n`);
expect(formatAllModeSummary()).not.toContain('14 examples');
});
});
6 changes: 5 additions & 1 deletion apps/cockpit/scripts/serve-example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export function backendCommand(cap: Capability): string | null {
return `${enter} && uv run langgraph dev --port ${cap.pythonPort} --no-browser`;
}

export function formatAllModeSummary(): string {
return `\nStarting cockpit + all ${capabilities.length} examples\n`;
}

// Guard: only execute CLI/orchestration logic when run directly (not imported by tests).
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
const args = process.argv.slice(2);
Expand Down Expand Up @@ -47,7 +51,7 @@ if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {

if (allMode) {
capabilities.forEach((c) => run(c.id, `npx nx run ${c.angularProject}:serve:cockpit --port ${c.port}`, '33'));
console.log('\n🚀 Starting cockpit + all 14 examples\n');
console.log(formatAllModeSummary());
} else {
const cap = findCapability(capabilityArg!);
if (!cap) { console.error(`Unknown: ${capabilityArg}`); process.exit(1); }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

14 changes: 14 additions & 0 deletions cockpit/render/computed-functions/angular/e2e/global-setup-impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
import { resolve } from 'node:path';
import { portsFor } from '../../../../../cockpit/ports.mjs';
import { createGlobalSetup } from '@threadplane-internal/e2e-harness';

const ports = portsFor('cockpit-render-computed-functions-angular');

export default createGlobalSetup({
langgraphCwd: 'cockpit/render/computed-functions/python',
langgraphPort: ports.langgraph,
angularProject: 'cockpit-render-computed-functions-angular',
angularPort: ports.angular,
fixturesDir: resolve(__dirname, 'fixtures'),
});
21 changes: 21 additions & 0 deletions cockpit/render/computed-functions/angular/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
import { defineConfig, devices } from '@playwright/test';
import { portsFor } from '../../../../../cockpit/ports.mjs';

const { angular: angularPort } = portsFor('cockpit-render-computed-functions-angular');

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:${angularPort}`,
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'),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
import { expect, test } from '@playwright/test';

test.describe('Render Computed Functions Example', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
await page.waitForSelector('app-computed-functions', { state: 'attached' });
});

test('renders spec picker and timeline', async ({ page }) => {
await expect(page.locator('button', { hasText: 'Text Transforms' })).toBeVisible();
await expect(page.locator('streaming-timeline')).toBeVisible();
});

test('shows streaming JSON pane', async ({ page }) => {
await expect(page.locator('pre')).toBeVisible();
});
});
6 changes: 6 additions & 0 deletions cockpit/render/computed-functions/angular/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@
"cwd": "cockpit/render/computed-functions/angular",
"command": "npx tsx -e \"import { renderComputedFunctionsAngularModule } from './src/index.ts'; const module = renderComputedFunctionsAngularModule; if (module.id !== 'render-computed-functions-angular' || module.title !== 'Render Computed Functions (Angular)') { throw new Error('Unexpected module shape for ' + module.id); }\""
}
},
"e2e": {
"executor": "@nx/playwright:playwright",
"options": {
"config": "cockpit/render/computed-functions/angular/e2e/playwright.config.ts"
}
}
},
"tags": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

14 changes: 14 additions & 0 deletions cockpit/render/element-rendering/angular/e2e/global-setup-impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
import { resolve } from 'node:path';
import { portsFor } from '../../../../../cockpit/ports.mjs';
import { createGlobalSetup } from '@threadplane-internal/e2e-harness';

const ports = portsFor('cockpit-render-element-rendering-angular');

export default createGlobalSetup({
langgraphCwd: 'cockpit/render/element-rendering/python',
langgraphPort: ports.langgraph,
angularProject: 'cockpit-render-element-rendering-angular',
angularPort: ports.angular,
fixturesDir: resolve(__dirname, 'fixtures'),
});
21 changes: 21 additions & 0 deletions cockpit/render/element-rendering/angular/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
import { defineConfig, devices } from '@playwright/test';
import { portsFor } from '../../../../../cockpit/ports.mjs';

const { angular: angularPort } = portsFor('cockpit-render-element-rendering-angular');

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:${angularPort}`,
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'),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
import { expect, test } from '@playwright/test';

test.describe('Render Element Rendering Example', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
await page.waitForSelector('app-element-rendering', { state: 'attached' });
});

test('renders spec picker and timeline', async ({ page }) => {
await expect(page.locator('button', { hasText: 'Parent + Children' })).toBeVisible();
await expect(page.locator('streaming-timeline')).toBeVisible();
});

test('shows streaming JSON pane', async ({ page }) => {
await expect(page.locator('pre')).toBeVisible();
});
});
6 changes: 6 additions & 0 deletions cockpit/render/element-rendering/angular/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@
"cwd": "cockpit/render/element-rendering/angular",
"command": "npx tsx -e \"import { renderElementRenderingAngularModule } from './src/index.ts'; const module = renderElementRenderingAngularModule; if (module.id !== 'render-element-rendering-angular' || module.title !== 'Render Element Rendering (Angular)') { throw new Error('Unexpected module shape for ' + module.id); }\""
}
},
"e2e": {
"executor": "@nx/playwright:playwright",
"options": {
"config": "cockpit/render/element-rendering/angular/e2e/playwright.config.ts"
}
}
},
"tags": [
Expand Down
1 change: 1 addition & 0 deletions cockpit/render/registry/angular/e2e/fixtures/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

14 changes: 14 additions & 0 deletions cockpit/render/registry/angular/e2e/global-setup-impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
import { resolve } from 'node:path';
import { portsFor } from '../../../../../cockpit/ports.mjs';
import { createGlobalSetup } from '@threadplane-internal/e2e-harness';

const ports = portsFor('cockpit-render-registry-angular');

export default createGlobalSetup({
langgraphCwd: 'cockpit/render/registry/python',
langgraphPort: ports.langgraph,
angularProject: 'cockpit-render-registry-angular',
angularPort: ports.angular,
fixturesDir: resolve(__dirname, 'fixtures'),
});
21 changes: 21 additions & 0 deletions cockpit/render/registry/angular/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
import { defineConfig, devices } from '@playwright/test';
import { portsFor } from '../../../../../cockpit/ports.mjs';

const { angular: angularPort } = portsFor('cockpit-render-registry-angular');

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:${angularPort}`,
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'),
});
18 changes: 18 additions & 0 deletions cockpit/render/registry/angular/e2e/r-registry.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
import { expect, test } from '@playwright/test';

test.describe('Render Registry Example', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
await page.waitForSelector('app-registry', { state: 'attached' });
});

test('renders spec picker and timeline', async ({ page }) => {
await expect(page.locator('button', { hasText: 'Basic Types' })).toBeVisible();
await expect(page.locator('streaming-timeline')).toBeVisible();
});

test('shows streaming JSON pane', async ({ page }) => {
await expect(page.locator('pre')).toBeVisible();
});
});
6 changes: 6 additions & 0 deletions cockpit/render/registry/angular/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@
"cwd": "cockpit/render/registry/angular",
"command": "npx tsx -e \"import { renderRegistryAngularModule } from './src/index.ts'; const module = renderRegistryAngularModule; if (module.id !== 'render-registry-angular' || module.title !== 'Render Registry (Angular)') { throw new Error('Unexpected module shape for ' + module.id); }\""
}
},
"e2e": {
"executor": "@nx/playwright:playwright",
"options": {
"config": "cockpit/render/registry/angular/e2e/playwright.config.ts"
}
}
},
"tags": [
Expand Down
1 change: 1 addition & 0 deletions cockpit/render/repeat-loops/angular/e2e/fixtures/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

14 changes: 14 additions & 0 deletions cockpit/render/repeat-loops/angular/e2e/global-setup-impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
import { resolve } from 'node:path';
import { portsFor } from '../../../../../cockpit/ports.mjs';
import { createGlobalSetup } from '@threadplane-internal/e2e-harness';

const ports = portsFor('cockpit-render-repeat-loops-angular');

export default createGlobalSetup({
langgraphCwd: 'cockpit/render/repeat-loops/python',
langgraphPort: ports.langgraph,
angularProject: 'cockpit-render-repeat-loops-angular',
angularPort: ports.angular,
fixturesDir: resolve(__dirname, 'fixtures'),
});
21 changes: 21 additions & 0 deletions cockpit/render/repeat-loops/angular/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
import { defineConfig, devices } from '@playwright/test';
import { portsFor } from '../../../../../cockpit/ports.mjs';

const { angular: angularPort } = portsFor('cockpit-render-repeat-loops-angular');

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:${angularPort}`,
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'),
});
18 changes: 18 additions & 0 deletions cockpit/render/repeat-loops/angular/e2e/r-repeat-loops.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
import { expect, test } from '@playwright/test';

test.describe('Render Repeat Loops Example', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
await page.waitForSelector('app-repeat-loops', { state: 'attached' });
});

test('renders spec picker and timeline', async ({ page }) => {
await expect(page.locator('button', { hasText: 'Simple List' })).toBeVisible();
await expect(page.locator('streaming-timeline')).toBeVisible();
});

test('shows streaming JSON pane', async ({ page }) => {
await expect(page.locator('pre')).toBeVisible();
});
});
6 changes: 6 additions & 0 deletions cockpit/render/repeat-loops/angular/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@
"cwd": "cockpit/render/repeat-loops/angular",
"command": "npx tsx -e \"import { renderRepeatLoopsAngularModule } from './src/index.ts'; const module = renderRepeatLoopsAngularModule; if (module.id !== 'render-repeat-loops-angular' || module.title !== 'Render Repeat Loops (Angular)') { throw new Error('Unexpected module shape for ' + module.id); }\""
}
},
"e2e": {
"executor": "@nx/playwright:playwright",
"options": {
"config": "cockpit/render/repeat-loops/angular/e2e/playwright.config.ts"
}
}
},
"tags": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

14 changes: 14 additions & 0 deletions cockpit/render/spec-rendering/angular/e2e/global-setup-impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
import { resolve } from 'node:path';
import { portsFor } from '../../../../../cockpit/ports.mjs';
import { createGlobalSetup } from '@threadplane-internal/e2e-harness';

const ports = portsFor('cockpit-render-spec-rendering-angular');

export default createGlobalSetup({
langgraphCwd: 'cockpit/render/spec-rendering/python',
langgraphPort: ports.langgraph,
angularProject: 'cockpit-render-spec-rendering-angular',
angularPort: ports.angular,
fixturesDir: resolve(__dirname, 'fixtures'),
});
21 changes: 21 additions & 0 deletions cockpit/render/spec-rendering/angular/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
import { defineConfig, devices } from '@playwright/test';
import { portsFor } from '../../../../../cockpit/ports.mjs';

const { angular: angularPort } = portsFor('cockpit-render-spec-rendering-angular');

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:${angularPort}`,
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'),
});
18 changes: 18 additions & 0 deletions cockpit/render/spec-rendering/angular/e2e/r-spec-rendering.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
import { expect, test } from '@playwright/test';

test.describe('Render Spec Rendering Example', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
await page.waitForSelector('app-spec-rendering', { state: 'attached' });
});

test('renders spec picker and timeline', async ({ page }) => {
await expect(page.locator('button', { hasText: 'Heading + Text' })).toBeVisible();
await expect(page.locator('streaming-timeline')).toBeVisible();
});

test('shows streaming JSON pane', async ({ page }) => {
await expect(page.locator('pre')).toBeVisible();
});
});
6 changes: 6 additions & 0 deletions cockpit/render/spec-rendering/angular/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@
"cwd": "cockpit/render/spec-rendering/angular",
"command": "npx tsx -e \"import { renderSpecRenderingAngularModule } from './src/index.ts'; const module = renderSpecRenderingAngularModule; if (module.id !== 'render-spec-rendering-angular' || module.title !== 'Render Spec Rendering (Angular)') { throw new Error('Unexpected module shape for ' + module.id); }\""
}
},
"e2e": {
"executor": "@nx/playwright:playwright",
"options": {
"config": "cockpit/render/spec-rendering/angular/e2e/playwright.config.ts"
}
}
},
"tags": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading
Loading