@_deep4wee/agent-lens 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +331 -227
  2. package/dist/cli.js +1068 -911
  3. package/dist/cli.js.map +1 -1
  4. package/dist/cli.mjs +1277 -1033
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/dsl-BIjVN1M0.d.mts +204 -0
  7. package/dist/dsl-BIjVN1M0.d.ts +204 -0
  8. package/dist/index.d.mts +131 -178
  9. package/dist/index.d.ts +131 -178
  10. package/dist/index.js +1506 -8
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +1479 -3
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/plugins/a11y-tree/index.d.mts +11 -0
  15. package/dist/plugins/a11y-tree/index.d.ts +11 -0
  16. package/dist/plugins/a11y-tree/index.js +190 -0
  17. package/dist/plugins/a11y-tree/index.js.map +1 -0
  18. package/dist/plugins/a11y-tree/index.mjs +155 -0
  19. package/dist/plugins/a11y-tree/index.mjs.map +1 -0
  20. package/dist/plugins/desktop-webview2/index.d.mts +14 -0
  21. package/dist/plugins/desktop-webview2/index.d.ts +14 -0
  22. package/dist/plugins/desktop-webview2/index.js +258 -0
  23. package/dist/plugins/desktop-webview2/index.js.map +1 -0
  24. package/dist/plugins/desktop-webview2/index.mjs +221 -0
  25. package/dist/plugins/desktop-webview2/index.mjs.map +1 -0
  26. package/dist/plugins/live-controller/index.d.mts +35 -0
  27. package/dist/plugins/live-controller/index.d.ts +35 -0
  28. package/dist/plugins/live-controller/index.js +303 -0
  29. package/dist/plugins/live-controller/index.js.map +1 -0
  30. package/dist/plugins/live-controller/index.mjs +261 -0
  31. package/dist/plugins/live-controller/index.mjs.map +1 -0
  32. package/dist/plugins/mock-ipc/index.d.mts +30 -0
  33. package/dist/plugins/mock-ipc/index.d.ts +30 -0
  34. package/dist/plugins/mock-ipc/index.js +210 -0
  35. package/dist/plugins/mock-ipc/index.js.map +1 -0
  36. package/dist/plugins/mock-ipc/index.mjs +181 -0
  37. package/dist/plugins/mock-ipc/index.mjs.map +1 -0
  38. package/dist/plugins/visual-diff/index.d.mts +30 -0
  39. package/dist/plugins/visual-diff/index.d.ts +30 -0
  40. package/dist/plugins/visual-diff/index.js +163 -0
  41. package/dist/plugins/visual-diff/index.js.map +1 -0
  42. package/dist/plugins/visual-diff/index.mjs +127 -0
  43. package/dist/plugins/visual-diff/index.mjs.map +1 -0
  44. package/docs/plugins.md +415 -0
  45. package/package.json +40 -2
  46. package/skills/agent-lens/SKILL.md +130 -43
  47. package/skills/agent-lens/examples/07-live-controller-interactive-loop.md +108 -0
  48. package/skills/agent-lens/examples/08-accessibility-semantic-inspection.md +80 -0
  49. package/skills/agent-lens/examples/09-visual-regression-and-pixel-diffing.md +66 -0
  50. package/skills/agent-lens/examples/10-authoring-custom-agent-plugins.md +85 -0
  51. package/skills/agent-lens/references/plugin-development.md +165 -0
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/api/dsl.ts","../src/features/capture/capture.ts","../src/features/reporter/reporter.ts","../src/features/console-tracker/consoleTracker.ts","../src/shared/lib/playwrightLoader.ts","../src/shared/drivers/desktopDriver.ts","../src/features/mock-ipc/mockIpc.ts","../src/shared/lib/config.ts","../src/shared/drivers/previewDriver.ts","../src/shared/lib/processManager.ts","../src/features/runner/runner.ts","../src/features/snap/snap.ts","../src/app/cli.ts"],"sourcesContent":["import type { Page, BrowserContext } from 'playwright';\nimport type { ConsoleEntry } from '../../features/console-tracker/consoleTracker';\nimport type { MockIpcResponseType } from '../../features/mock-ipc/mockIpc';\n\nexport interface ViewportPreset {\n name: string;\n width: number;\n height: number;\n}\n\nexport const VIEWPORT_PRESETS = {\n /** Minimum supported window size (e.g., ) */\n MIN_SUPPORTED: { name: 'min-supported', width: 1024, height: 768 } as ViewportPreset,\n /** Standard default window size (e.g., ) */\n DEFAULT: { name: 'default', width: 1200, height: 800 } as ViewportPreset,\n /** Wide screen for checking grids and tables */\n WIDE: { name: 'wide', width: 1600, height: 900 } as ViewportPreset,\n /** Full HD */\n FULL_HD: { name: 'full-hd', width: 1920, height: 1080 } as ViewportPreset,\n};\n\nexport interface MockRouteEntry {\n url: string;\n method?: string;\n status?: number;\n body: any;\n delayMs?: number;\n headers?: Record<string, string>;\n}\n\nexport interface CaptureOptions {\n selector?: string;\n fullPage?: boolean;\n mask?: string[];\n}\n \n\nexport interface CaptureBurstOptions {\n /** Total duration of burst animation capture in milliseconds */\n durationMs: number;\n /** Interval between frames in milliseconds (default: 80ms) */\n intervalMs?: number;\n /** Restrict capture to a specific element */\n selector?: string;\n}\n\nexport interface SnapshotMetadata {\n index: number;\n name: string;\n fileName: string;\n filePath: string;\n relativeUri: string;\n viewport: { width: number; height: number };\n timestamp: string;\n isBurstFrame?: boolean;\n burstGroup?: string;\n frameIndex?: number;\n selector?: string;\n}\n\nexport interface TestContext {\n page: Page;\n context: BrowserContext;\n targetMode: 'desktop' | 'preview';\n currentViewport: { width: number; height: number };\n \n // --- Snapshots ---\n\n /** Capture a single high-quality snapshot of the window or element */\n capture: (name: string, options?: CaptureOptions) => Promise<SnapshotMetadata>;\n \n /** Capture a series of frames for animations (Framer Motion, modals, lists) */\n captureBurst: (name: string, options: CaptureBurstOptions) => Promise<SnapshotMetadata[]>;\n \n // --- Navigation ---\n\n /** \n * Dynamically navigate to another page during the test.\n * Example: await ctx.navigate('/settings');\n */\n navigate: (route: string) => Promise<void>;\n\n // --- Viewport ---\n\n /** Change window / viewport size */\n resize: (width: number, height: number) => Promise<void>;\n \n /** Set one of the standard presets (MIN_SUPPORTED, DEFAULT, WIDE) */\n setPreset: (preset: ViewportPreset) => Promise<void>;\n\n /** \n * Dynamically resize the window so it perfectly fits the specified element (or body).\n * Useful when an agent wants to test an isolated component without background clutter.\n */\n resizeToFit: (selector?: string, padding?: number) => Promise<void>;\n \n // --- Waiting ---\n\n /** Wait the specified amount of milliseconds */\n wait: (ms: number) => Promise<void>;\n \n /** Wait for the selector to appear in the DOM */\n waitForSelector: (selector: string, timeoutMs?: number) => Promise<void>;\n \n // --- Interaction ---\n\n /** Left-click the element */\n click: (selector: string) => Promise<void>;\n \n /** Right-click the element (Context Menu) */\n rightClick: (selector: string) => Promise<void>;\n \n /** Type text into an input field */\n type: (selector: string, text: string) => Promise<void>;\n \n /** Select an option in a <select> by its value */\n selectOption: (selector: string, value: string) => Promise<void>;\n \n /** Hover the cursor to check highlights / tooltips */\n hover: (selector: string) => Promise<void>;\n \n /** Scroll the element (or window) down by the specified number of pixels */\n scroll: (selector: string, deltaY: number) => Promise<void>;\n \n // --- Logging ---\n\n /** Log a step for the agent */\n log: (message: string) => void;\n\n // --- Mock IPC & Network Routes (preview mode only) ---\n\n /**\n * Set a mock response for an IPC action.\n * Changes the data returned by window.__mockIpc.invoke or hybrid bridges in preview mode.\n * Ignored in desktop mode (IPC goes through real backend).\n */\n setMockIpc: (action: string, data: any, options?: { type?: MockIpcResponseType; delayMs?: number }) => Promise<void>;\n\n /**\n * Mock an HTTP REST or GraphQL network request in preview mode.\n * Intercepts fetch/axios calls matching the URL pattern and returns mock data.\n *\n * Example:\n * await ctx.setMockRoute('/api/user', { id: 1, name: 'Agent' });\n * await ctx.setMockRoute('**\\/api/items*', [], { status: 200, delayMs: 50 });\n */\n setMockRoute: (\n url: string,\n body: any,\n options?: { method?: string; status?: number; delayMs?: number; headers?: Record<string, string> }\n ) => Promise<void>;\n\n // --- Console Errors ---\n \n\n /** Return all intercepted console.error and pageerror logs */\n getConsoleErrors: () => ConsoleEntry[];\n\n /** Return all intercepted console.warn logs */\n getConsoleWarnings: () => ConsoleEntry[];\n\n /** Returns true if there are critical errors in the console */\n hasConsoleErrors: () => boolean;\n\n // --- DOM Assertions ---\n\n /** Get the visible text of a specific element */\n readText: (selector: string) => Promise<string | null>;\n \n /** Get ALL visible text on the page (useful for quick analysis without Vision) */\n getPageText: () => Promise<string>;\n \n /** Check if the element is visible on the screen */\n isVisible: (selector: string) => Promise<boolean>;\n\n /** Count the number of elements matching the selector */\n getElementCount: (selector: string) => Promise<number>;\n}\n\nexport interface VisualScenario {\n /** Unique scenario identifier (kebab-case) */\n id: string;\n /** Human-readable title for the report */\n title: string;\n /** Description of what is being tested */\n description?: string;\n /** Initial route to navigate to (e.g., '/instances', '/settings') */\n route?: string;\n /** List of viewport sizes to test */\n viewports?: ViewportPreset[];\n /**\n * Initial IPC mock data for preview mode.\n * Applied BEFORE navigation to the route.\n */\n mockIpc?: Array<{ action: string; data: any; type?: MockIpcResponseType; delayMs?: number }>;\n /**\n * Initial HTTP REST/GraphQL route mocks for preview mode.\n * Applied BEFORE navigation to the route.\n */\n mockRoutes?: MockRouteEntry[];\n /**\n * Optional setup hook: executed before the browser navigates and scenario runs.\n * Ideal for preparing mock files, test directories, or initial state.\n */\n \n setup?: () => Promise<void> | void;\n /** The main body of the scenario */\n run: (ctx: TestContext) => Promise<void>;\n /**\n * Optional teardown hook: guaranteed to execute in finally, even if run() fails.\n * Ideal for cleaning up test artifacts, cache directories, or temporary state.\n */\n teardown?: () => Promise<void> | void;\n}\n\nexport function defineVisualTest(scenario: VisualScenario): VisualScenario {\n return scenario;\n}\n","import fs from 'fs';\r\nimport path from 'path';\r\nimport type { Page } from 'playwright';\r\nimport type { CaptureOptions, CaptureBurstOptions, SnapshotMetadata } from '../../shared/api/dsl';\r\n\r\nexport class CaptureEngine {\r\n private outputDir: string;\r\n private currentStepIndex: number = 0;\r\n private recordedSnapshots: SnapshotMetadata[] = [];\r\n\r\n constructor(outputDir: string) {\r\n this.outputDir = outputDir;\r\n if (!fs.existsSync(this.outputDir)) {\r\n fs.mkdirSync(this.outputDir, { recursive: true });\r\n }\r\n }\r\n\r\n public getSnapshots(): SnapshotMetadata[] {\r\n return this.recordedSnapshots;\r\n }\r\n\r\n public getOutputDir(): string {\r\n return this.outputDir;\r\n }\r\n\r\n /**\r\n */\r\n public async takeSnapshot(\r\n page: Page,\r\n name: string,\r\n viewport: { width: number; height: number },\r\n options?: CaptureOptions\r\n ): Promise<SnapshotMetadata> {\r\n this.currentStepIndex += 1;\r\n const paddedIndex = String(this.currentStepIndex).padStart(2, '0');\r\n const sanitizedName = name.replace(/[^a-zA-Z0-9_\\-]/g, '_');\r\n const fileName = `${paddedIndex}_${sanitizedName}_${viewport.width}x${viewport.height}.png`;\r\n const filePath = path.join(this.outputDir, fileName);\r\n\r\n if (options?.selector) {\r\n const element = await page.waitForSelector(options.selector, { timeout: 5000 });\r\n await element.screenshot({ path: filePath });\r\n } else {\r\n await page.screenshot({ path: filePath, fullPage: options?.fullPage ?? false });\r\n }\r\n\r\n const metadata: SnapshotMetadata = {\r\n index: this.currentStepIndex,\r\n name,\r\n fileName,\r\n filePath,\r\n relativeUri: `./${fileName}`,\r\n viewport,\r\n timestamp: new Date().toISOString(),\r\n selector: options?.selector\r\n };\r\n\r\n this.recordedSnapshots.push(metadata);\r\n return metadata;\r\n }\r\n\r\n /**\r\n */\r\n public async takeBurst(\r\n page: Page,\r\n name: string,\r\n viewport: { width: number; height: number },\r\n options: CaptureBurstOptions\r\n ): Promise<SnapshotMetadata[]> {\r\n this.currentStepIndex += 1;\r\n const stepIndex = this.currentStepIndex;\r\n const paddedIndex = String(stepIndex).padStart(2, '0');\r\n const sanitizedName = name.replace(/[^a-zA-Z0-9_\\-]/g, '_');\r\n\r\n const duration = Math.max(options.durationMs, 50);\r\n const interval = Math.max(options.intervalMs ?? 80, 20);\r\n const totalFrames = Math.ceil(duration / interval);\r\n\r\n const burstSnapshots: SnapshotMetadata[] = [];\r\n const burstGroup = sanitizedName;\r\n\r\n for (let frame = 0; frame <= totalFrames; frame++) {\r\n const elapsedMs = frame * interval;\r\n const paddedFrame = String(frame + 1).padStart(2, '0');\r\n const fileName = `${paddedIndex}_burst_${sanitizedName}_f${paddedFrame}_${elapsedMs}ms.png`;\r\n const filePath = path.join(this.outputDir, fileName);\r\n\r\n if (options.selector) {\r\n const element = await page.$(options.selector);\r\n if (element) {\r\n await element.screenshot({ path: filePath });\r\n } else {\r\n await page.screenshot({ path: filePath });\r\n }\r\n } else {\r\n await page.screenshot({ path: filePath });\r\n }\r\n\r\n const meta: SnapshotMetadata = {\r\n index: stepIndex,\r\n name: `${name} (frame ${frame + 1}, +${elapsedMs}ms)`,\r\n fileName,\r\n filePath,\r\n relativeUri: `./${fileName}`,\r\n viewport,\r\n timestamp: new Date().toISOString(),\r\n isBurstFrame: true,\r\n burstGroup,\r\n frameIndex: frame + 1,\r\n selector: options.selector\r\n };\r\n\r\n burstSnapshots.push(meta);\r\n this.recordedSnapshots.push(meta);\r\n\r\n if (frame < totalFrames) {\r\n await new Promise((r) => setTimeout(r, interval));\r\n }\r\n }\r\n\r\n return burstSnapshots;\r\n }\r\n}\r\n","import fs from 'fs';\nimport path from 'path';\nimport type { SnapshotMetadata, VisualScenario } from '../../shared/api/dsl';\nimport type { ConsoleEntry } from '../console-tracker/consoleTracker';\n\nexport interface ReportData {\n \n scenario: VisualScenario;\n snapshots: SnapshotMetadata[];\n consoleErrors: ConsoleEntry[];\n consoleWarnings: ConsoleEntry[];\n outputDir: string;\n targetMode: 'desktop' | 'preview';\n durationMs: number;\n}\n\nexport class VisualReporter {\n public static generateReport(data: ReportData): string {\n const {\n scenario,\n snapshots,\n consoleErrors,\n consoleWarnings,\n outputDir,\n targetMode,\n durationMs\n } = data;\n\n const manifestPath = path.join(outputDir, 'manifest.json');\n const reportPath = path.join(outputDir, 'report.md');\n\n const manifest = {\n scenarioId: scenario.id,\n title: scenario.title,\n description: scenario.description,\n targetMode,\n durationMs,\n totalSnapshots: snapshots.length,\n consoleErrors: consoleErrors.length,\n consoleWarnings: consoleWarnings.length,\n createdAt: new Date().toISOString(),\n snapshots,\n errors: consoleErrors,\n warnings: consoleWarnings\n };\n fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n\n const rows: string[] = [];\n \n const regularSnapshots = snapshots.filter((s) => !s.isBurstFrame);\n const burstGroups = new Map<string, SnapshotMetadata[]>();\n\n snapshots.filter((s) => s.isBurstFrame && s.burstGroup).forEach((s) => {\n const list = burstGroups.get(s.burstGroup!) || [];\n list.push(s);\n burstGroups.set(s.burstGroup!, list);\n });\n\n for (const snap of regularSnapshots) {\n const relativeLink = snap.relativeUri || `./${snap.fileName}`;\n rows.push(\n `| **${String(snap.index).padStart(2, '0')}** | \\`${snap.viewport.width}x${snap.viewport.height}\\` | ${snap.name} | [${snap.fileName}](${relativeLink}) |`\n );\n }\n\n let burstSections = '';\n if (burstGroups.size > 0) {\n burstSections += `\\n### šŸŽ¬ Animation Bursts\\n\\n`;\n for (const [group, frames] of burstGroups.entries()) {\n burstSections += `#### Animation: \\`${group}\\` (${frames.length} frames)\\n\\n`;\n burstSections += `| Frame | Viewport | File | Preview |\\n| :--- | :--- | :--- | :--- |\\n`;\n for (const frame of frames) {\n const relativeLink = frame.relativeUri || `./${frame.fileName}`;\n burstSections += `| Frame ${frame.frameIndex} | \\`${frame.viewport.width}x${frame.viewport.height}\\` | [${frame.fileName}](${relativeLink}) | ![](${relativeLink}) |\\n`;\n }\n burstSections += `\\n`;\n }\n }\n \n\n const healthStatus = this.getHealthStatus(consoleErrors, consoleWarnings);\n let consoleSections = '';\n\n if (consoleErrors.length > 0) {\n consoleSections += `\\n## šŸ”“ Console Errors (${consoleErrors.length})\\n\\n`;\n consoleSections += `> [!CAUTION]\\n> Found **${consoleErrors.length}** JavaScript errors during the test. This might indicate broken components, missing data, or unhandled exceptions.\\n\\n`;\n consoleSections += `| # | Time | Error | URL |\\n| :-: | :--- | :--- | :--- |\\n`;\n consoleErrors.forEach((err, i) => {\n const time = err.timestamp.split('T')[1]?.slice(0, 8) || '';\n const text = err.text.replace(/\\|/g, '\\\\|').slice(0, 200);\n const url = err.url.replace(/\\|/g, '\\\\|');\n consoleSections += `| ${i + 1} | \\`${time}\\` | ${text} | \\`${url}\\` |\\n`;\n });\n\n const withStack = consoleErrors.filter(e => e.stack);\n if (withStack.length > 0) {\n consoleSections += `\\n<details>\\n<summary>šŸ“‹ Stack Traces (${withStack.length})</summary>\\n\\n`;\n withStack.forEach((err, i) => {\n consoleSections += `**Error ${i + 1}:** \\`${err.text.slice(0, 100)}\\`\\n\\`\\`\\`\\n${err.stack}\\n\\`\\`\\`\\n\\n`;\n });\n consoleSections += `</details>\\n`;\n }\n }\n\n if (consoleWarnings.length > 0) {\n consoleSections += `\\n## 🟔 Console Warnings (${consoleWarnings.length})\\n\\n`;\n consoleSections += `| # | Warning |\\n| :-: | :--- |\\n`;\n consoleWarnings.slice(0, 20).forEach((warn, i) => {\n const text = warn.text.replace(/\\|/g, '\\\\|').slice(0, 200);\n consoleSections += `| ${i + 1} | ${text} |\\n`;\n });\n if (consoleWarnings.length > 20) {\n consoleSections += `\\n*...and ${consoleWarnings.length - 20} more warnings (full list in manifest.json)*\\n`;\n }\n }\n\n const reportContent = `# šŸ“ø Visual Test Report: ${scenario.title}\n\n> **Scenario ID:** \\`${scenario.id}\\` \n> **Target Mode:** \\`${targetMode.toUpperCase()}\\` (${targetMode === 'desktop' ? 'Native Desktop App / WebView2' : 'Fast Web Preview'}) \n> **Execution Duration:** ${(durationMs / 1000).toFixed(2)} s \n> **Total Snapshots Captured:** ${snapshots.length} \n> **Health Status:** ${healthStatus} \n> **Artifacts Folder:** \\`${outputDir}\\`\n\n---\n\n## šŸ–¼ļø Primary Snapshot Overview\n\n| # | Viewport | Step Description | File Reference |\n| :-: | :--- | :--- | :--- |\n${rows.join('\\n')}\n\n${burstSections}\n${consoleSections}\n---\n\n## šŸ“‹ AI Agent Verification Checklist:\n- [ ] **Console Errors**: ${consoleErrors.length === 0 ? 'āœ… No errors found' : `āŒ ${consoleErrors.length} errors — MUST REVIEW`}\n- [ ] **Visual Layout Check**: Inspect snapshots (e.g. view_image on \\`./01_${regularSnapshots[0]?.fileName || 'quick_snap'}\\`) for layout shifts or clipped elements.\n- [ ] **Responsiveness at \\`1024x768\\`**: Elements do not overflow the screen, no unwanted horizontal scroll.\n \n- [ ] **Typography & Spacing**: Spacing matches the design system and layout grids.\n- [ ] **Color Palette & Theme**: Background tints and button accent colors match the concept.\n- [ ] **Component States**: Modals open centered, dropdowns do not overlap with other layers (z-index).\n- [ ] **Localization**: Verify that there are no raw i18n keys (text with dots like \\`sidebar.home\\` instead of \"Home\").\n\n`;\n\n fs.writeFileSync(reportPath, reportContent, 'utf-8');\n return reportPath;\n }\n\n private static getHealthStatus(errors: ConsoleEntry[], warnings: ConsoleEntry[]): string {\n if (errors.length === 0 && warnings.length === 0) {\n return 'āœ… Healthy — no errors or warnings';\n }\n if (errors.length === 0 && warnings.length > 0) {\n return `āš ļø Warnings (${warnings.length}) — no critical errors`;\n }\n return `āŒ ERRORS (${errors.length} errors, ${warnings.length} warnings) — requires attention`;\n }\n}\n","import type { Page, ConsoleMessage } from 'playwright';\r\n\r\nexport interface ConsoleEntry {\r\n level: 'error' | 'warning' | 'info' | 'log' | 'debug';\r\n text: string;\r\n url: string;\r\n timestamp: string;\r\n stack?: string;\r\n}\r\n\r\nexport class ConsoleTracker {\r\n private entries: ConsoleEntry[] = [];\r\n private attached = false;\r\n\r\n public attach(page: Page): void {\r\n if (this.attached) return;\r\n this.attached = true;\r\n\r\n page.on('console', (msg: ConsoleMessage) => {\r\n const type = msg.type(); // 'log' | 'error' | 'warning' | 'info' | 'debug' | 'trace' | ...\r\n const level = this.mapConsoleType(type);\r\n\r\n const entry: ConsoleEntry = {\r\n level,\r\n text: msg.text(),\r\n url: page.url(),\r\n timestamp: new Date().toISOString()\r\n };\r\n\r\n this.entries.push(entry);\r\n\r\n if (level === 'error') {\r\n console.log(`šŸ”“ [Console ERROR] ${msg.text()}`);\r\n } else if (level === 'warning') {\r\n if (!this.isIgnoredWarning(msg.text())) {\r\n console.log(`🟔 [Console WARN] ${msg.text()}`);\r\n }\r\n }\r\n });\r\n\r\n page.on('pageerror', (error: Error) => {\r\n const entry: ConsoleEntry = {\r\n level: 'error',\r\n text: error.message,\r\n url: page.url(),\r\n timestamp: new Date().toISOString(),\r\n stack: error.stack\r\n };\r\n\r\n this.entries.push(entry);\r\n console.log(`šŸ’„ [Page ERROR] ${error.message}`);\r\n });\r\n }\r\n\r\n public getErrors(): ConsoleEntry[] {\r\n return this.entries.filter(e => e.level === 'error');\r\n }\r\n\r\n public getWarnings(): ConsoleEntry[] {\r\n return this.entries\r\n .filter(e => e.level === 'warning')\r\n .filter(e => !this.isIgnoredWarning(e.text));\r\n }\r\n\r\n public getAll(): ConsoleEntry[] {\r\n return [...this.entries];\r\n }\r\n\r\n public get errorCount(): number {\r\n return this.getErrors().length;\r\n }\r\n\r\n public get warningCount(): number {\r\n return this.getWarnings().length;\r\n }\r\n\r\n public get hasErrors(): boolean {\r\n return this.errorCount > 0;\r\n }\r\n\r\n public clear(): void {\r\n this.entries = [];\r\n }\r\n\r\n\r\n private mapConsoleType(type: string): ConsoleEntry['level'] {\r\n switch (type) {\r\n case 'error': return 'error';\r\n case 'warning': return 'warning';\r\n case 'info': return 'info';\r\n case 'debug': return 'debug';\r\n default: return 'log';\r\n }\r\n }\r\n\r\n\r\n private isIgnoredWarning(text: string): boolean {\r\n const ignoredPatterns = [\r\n 'findDOMNode is deprecated',\r\n // Chromium DevTools\r\n 'DevTools',\r\n // Playwright injection\r\n '__playwright',\r\n '[vite]',\r\n // React 18 hydration warnings\r\n 'Extra attributes from the server',\r\n 'Download the React DevTools',\r\n ];\r\n return ignoredPatterns.some(pattern => text.includes(pattern));\r\n }\r\n}\r\n","import { chromium as baseChromium, type ChromiumBrowser, type BrowserType } from 'playwright';\r\n\r\n/**\r\n * Safe Playwright Chromium loader that wraps browser initialization with helpful diagnostic messages.\r\n */\r\nexport const chromium: BrowserType<ChromiumBrowser> = new Proxy(baseChromium, {\r\n get(target, prop, receiver) {\r\n if (prop === 'launch') {\r\n return async (...args: Parameters<typeof baseChromium.launch>) => {\r\n try {\r\n return await target.launch(...args);\r\n } catch (err: any) {\r\n if (\r\n err.message?.includes(\"Executable doesn't exist\") ||\r\n err.message?.includes('playwright install') ||\r\n err.message?.includes('browser has not been downloaded')\r\n ) {\r\n console.error(\"\\nāŒ [AgentLens] Playwright Chromium browser binary is missing!\");\r\n console.error(\"šŸ‘‰ Please install it by running: npx playwright install chromium\\n\");\r\n }\r\n throw err;\r\n }\r\n };\r\n }\r\n const val = Reflect.get(target, prop, receiver);\r\n return typeof val === 'function' ? val.bind(target) : val;\r\n }\r\n});","import { spawn, type ChildProcess } from 'child_process';\nimport http from 'http';\nimport path from 'path';\nimport fs from 'fs';\nimport type { Browser, BrowserContext, Page } from 'playwright';\nimport { chromium } from '../lib/playwrightLoader';\nimport treeKill from 'tree-kill';\n\nexport interface DesktopDriverOptions {\n \n \n port?: number;\n executablePath?: string;\n autoLaunch?: boolean;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\nexport class DesktopDriver {\n private port: number;\n private executablePath?: string;\n private autoLaunch: boolean;\n private args: string[];\n private env: Record<string, string>;\n private cwd?: string;\n\n private childProcess: ChildProcess | null = null;\n private browser: Browser | null = null;\n private context: BrowserContext | null = null;\n private page: Page | null = null;\n private processStderr: string = '';\n private processExited: boolean = false;\n private exitCode: number | null = null;\n\n constructor(options?: DesktopDriverOptions) {\n this.port = options?.port || 9222;\n this.autoLaunch = options?.autoLaunch ?? true;\n this.executablePath = options?.executablePath;\n this.args = options?.args || [];\n this.env = options?.env || {};\n this.cwd = options?.cwd;\n }\n\n private async isPortAvailable(): Promise<boolean> {\n return new Promise((resolve) => {\n const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {\n resolve(res.statusCode === 200);\n });\n req.on('error', () => resolve(false));\n req.setTimeout(800, () => {\n req.destroy();\n resolve(false);\n });\n });\n }\n\n private async waitForPort(timeoutMs: number = 25000): Promise<void> {\n const startTime = Date.now();\n while (Date.now() - startTime < timeoutMs) {\n if (this.processExited) {\n throw new Error(\n `[DesktopDriver] Process terminated prematurely with exit code ${this.exitCode}.\\nStderr: ${this.processStderr.trim() || '(none)'}`\n );\n }\n\n if (await this.isPortAvailable()) {\n return;\n }\n await new Promise((r) => setTimeout(r, 400));\n }\n throw new Error(\n `Timeout waiting for WebView2/Chromium CDP port ${this.port}. Last stderr:\\n${this.processStderr.trim() || '(no stderr output)'}`\n );\n }\n\n public async start(initialViewport = { width: 1200, height: 800 }): Promise<{ page: Page; context: BrowserContext; browser: Browser }> {\n const alreadyRunning = await this.isPortAvailable();\n\n if (!alreadyRunning) {\n if (!this.autoLaunch) {\n throw new Error(\n `App is not running on port ${this.port} and autoLaunch is false. Start app with WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--remote-debugging-port=${this.port}`\n );\n }\n\n if (!this.executablePath) {\n throw new Error(\n `[DesktopDriver] No executablePath provided and nothing is running on port ${this.port}. Specify --exe=<path> in CLI or executablePath in config.`\n );\n }\n\n const resolvedExe = path.resolve(process.cwd(), this.executablePath);\n if (!fs.existsSync(resolvedExe)) {\n throw new Error(\n `[DesktopDriver] Desktop executable not found at: ${resolvedExe}. Please build your native project first.`\n );\n }\n\n console.log(`[DesktopDriver] Launching: ${resolvedExe}`);\n \n // Ensure remote debugging port is passed as CLI flag for Electron / Chromium binaries\n const finalArgs = [...this.args];\n const hasDebugPort = finalArgs.some((a) => a.startsWith('--remote-debugging-port='));\n if (!hasDebugPort) {\n finalArgs.push(`--remote-debugging-port=${this.port}`);\n }\n\n // Also set WebView2 environment variable for .NET / Photino Windows apps\n const mergedEnv = {\n ...process.env,\n ...this.env,\n WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS: `--remote-debugging-port=${this.port}`\n };\n\n this.processStderr = '';\n this.processExited = false;\n this.exitCode = null;\n\n this.childProcess = spawn(resolvedExe, finalArgs, {\n env: mergedEnv,\n cwd: this.cwd || path.dirname(resolvedExe),\n stdio: ['ignore', 'ignore', 'pipe'],\n detached: false\n });\n ;\n\n this.processStderr = '';\n this.processExited = false;\n this.exitCode = null;\n\n this.childProcess = spawn(resolvedExe, this.args, {\n env: mergedEnv,\n cwd: this.cwd || path.dirname(resolvedExe),\n stdio: ['ignore', 'ignore', 'pipe'],\n detached: false\n });\n\n this.childProcess.stderr?.on('data', (chunk) => {\n this.processStderr += chunk.toString();\n });\n\n this.childProcess.on('exit', (code) => {\n this.processExited = true;\n this.exitCode = code;\n });\n\n this.childProcess.on('error', (err) => {\n console.error('[DesktopDriver] Failed to spawn process:', err);\n });\n\n console.log(`[DesktopDriver] Waiting for CDP debugging port on ${this.port}...`);\n await this.waitForPort();\n } else {\n console.log(`[DesktopDriver] Attached to already running process on port ${this.port}`);\n }\n\n console.log(`[DesktopDriver] Connecting Playwright CDP to http://127.0.0.1:${this.port}...`);\n this.browser = await chromium.connectOverCDP(`http://127.0.0.1:${this.port}`);\n \n const contexts = this.browser.contexts();\n this.context = contexts[0] || (await this.browser.newContext());\n\n const pages = this.context.pages();\n if (pages.length > 0) {\n this.page = pages[0];\n } else {\n this.page = await this.context.waitForEvent('page', { timeout: 10000 });\n }\n\n if (initialViewport) {\n await this.page.setViewportSize(initialViewport).catch(() => {});\n }\n\n return { page: this.page, context: this.context, browser: this.browser };\n }\n\n public async stop(): Promise<void> {\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n\n if (this.childProcess && !this.childProcess.killed && this.childProcess.pid) {\n console.log('[DesktopDriver] Terminating spawned desktop process tree...');\n const pid = this.childProcess.pid;\n await new Promise<void>((resolve) => {\n treeKill(pid, 'SIGTERM', () => resolve());\n });\n this.childProcess = null;\n }\n \n }\n}\n","/**\n * Generic Mock IPC Registry for Preview Mode\n * \n * Injects a global `window.__mockIpc` that web apps or mocked electron/tauri APIs can call.\n */\n\nexport type MockIpcResponseType = 'SUCCESS' | 'ERROR';\n\nexport interface MockIpcEntry {\n action: string;\n data: any;\n type?: MockIpcResponseType;\n delayMs?: number;\n}\n\nexport class MockIpcRegistry {\n private mocks = new Map<string, MockIpcEntry>();\n\n public set(action: string, data: any, options?: { type?: MockIpcResponseType; delayMs?: number }): void {\n this.mocks.set(action, {\n action,\n data,\n type: options?.type ?? 'SUCCESS',\n delayMs: options?.delayMs ?? 20\n });\n }\n\n public setBatch(entries: Array<{ action: string; data: any; type?: MockIpcResponseType; delayMs?: number }>): void {\n for (const entry of entries) {\n this.set(entry.action, entry.data, { type: entry.type, delayMs: entry.delayMs });\n }\n }\n\n public remove(action: string): void {\n this.mocks.delete(action);\n }\n\n public clear(): void {\n this.mocks.clear();\n }\n\n public get(action: string): MockIpcEntry | null {\n return this.mocks.get(action) ?? null;\n }\n\n public toSerializable(): Record<string, { data: any; type: string; delayMs: number }> {\n const result: Record<string, { data: any; type: string; delayMs: number }> = {};\n for (const [action, entry] of this.mocks.entries()) {\n result[action] = {\n data: entry.data,\n type: entry.type ?? 'SUCCESS',\n delayMs: entry.delayMs ?? 20\n };\n }\n return result;\n }\n\n public get size(): number {\n return this.mocks.size;\n }\n}\n\nexport function generateMockIpcScript(registry: MockIpcRegistry): string {\n const mocksJson = JSON.stringify(registry.toSerializable());\n\n return `\n (() => {\n const __mockTable = ${mocksJson};\n\n window.__visualRunnerMocks = __mockTable;\n\n // Generic IPC mock bridge for modern web applications\n window.__mockIpc = {\n invoke: (action, payload) => {\n return new Promise((resolve, reject) => {\n const mock = window.__visualRunnerMocks[action];\n\n if (mock) {\n setTimeout(() => {\n if (mock.type === 'ERROR') {\n reject(new Error(mock.data));\n } else {\n resolve(mock.data);\n }\n }, mock.delayMs || 20);\n } else {\n console.warn('[Mock IPC] No mock for action:', action, '— returning empty SUCCESS');\n setTimeout(() => resolve(null), 20);\n }\n });\n }\n };\n\n // Safe fallback bridge for hybrid webviews (Photino / CEF / WebView2)\n try {\n if (!window.external) {\n (window as any).external = {};\n }\n (window.external as any).sendMessage = (msg) => {\n try {\n const parsed = typeof msg === 'string' ? JSON.parse(msg) : msg;\n const action = parsed.Action || parsed.action;\n const id = parsed.Id || parsed.id;\n const mock = (window as any).__visualRunnerMocks[action];\n\n if (mock) {\n const response = { Id: id, Type: mock.type || 'SUCCESS', Data: mock.data };\n setTimeout(() => {\n const cb = (window as any).__mockCallback;\n if (typeof cb === 'function') cb(JSON.stringify(response));\n }, mock.delayMs || 20);\n } else {\n setTimeout(() => {\n const cb = (window as any).__mockCallback;\n if (typeof cb === 'function') cb(JSON.stringify({ Id: id, Type: 'SUCCESS', Data: null }));\n }, 20);\n }\n } catch (e) {\n console.error('[Mock IPC] Failed to process message:', e);\n }\n };\n\n (window.external as any).receiveMessage = (callback) => {\n (window as any).__mockCallback = callback;\n };\n } catch {\n // Ignored if window.external is read-only in strict Chromium sandboxes\n }\n\n console.log('[Visual Runner] Mock IPC bridge initialized with', Object.keys((window as any).__visualRunnerMocks).length, 'mocked actions');\n })();\n \n `;\n}\n","import path from 'path';\nimport fs from 'fs';\n\nexport interface AgentLensConfigFile {\n mode?: 'desktop' | 'preview';\n port?: number;\n headed?: boolean;\n detach?: boolean;\n buildCommand?: string;\n autoBuild?: boolean;\n startCommand?: string;\n startCwd?: string;\n cleanArtifacts?: boolean;\n url?: string;\n executablePath?: string;\n clean?: string | string[];\n scenarios?: string;\n wwwroot?: string;\n outDir?: string;\n env?: Record<string, string>;\n}\n\nexport function loadConfig(cwd: string = process.cwd()): AgentLensConfigFile {\n const jsonConfigPath = path.join(cwd, 'agent-lens.json');\n if (fs.existsSync(jsonConfigPath)) {\n try {\n const raw = fs.readFileSync(jsonConfigPath, 'utf-8');\n return JSON.parse(raw);\n } catch (e: any) {\n console.warn(`āš ļø [Config] Failed to parse agent-lens.json: ${e.message}`);\n }\n }\n\n const packageJsonPath = path.join(cwd, 'package.json');\n if (fs.existsSync(packageJsonPath)) {\n try {\n const raw = fs.readFileSync(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(raw);\n if (pkg.agentLens && typeof pkg.agentLens === 'object') {\n return pkg.agentLens;\n }\n } catch {\n // ignore\n }\n }\n\n return {};\n}\n\nexport function detectStartCwd(providedCwd?: string): string | undefined {\n if (providedCwd) {\n const resolved = path.resolve(process.cwd(), providedCwd);\n if (fs.existsSync(resolved)) {\n return providedCwd;\n }\n }\n\n const rootPkgPath = path.join(process.cwd(), 'package.json');\n let rootHasDevScript = false;\n if (fs.existsSync(rootPkgPath)) {\n try {\n const rootPkg = JSON.parse(fs.readFileSync(rootPkgPath, 'utf-8'));\n rootHasDevScript = Boolean(rootPkg.scripts?.dev || rootPkg.scripts?.start);\n } catch {\n // ignore\n }\n }\n\n if (rootHasDevScript) {\n return undefined;\n }\n\n const candidates = ['Frontend', 'frontend', 'client', 'web', 'ui', 'apps/web', 'src/frontend'];\n for (const candidate of candidates) {\n const candidatePkg = path.join(process.cwd(), candidate, 'package.json');\n if (fs.existsSync(candidatePkg)) {\n return `./${candidate}`;\n }\n }\n\n return undefined;\n}\n\nexport function resolveWwwrootDir(customDir?: string): string {\n if (customDir) {\n return path.resolve(process.cwd(), customDir);\n }\n\n const candidates = [\n 'dist',\n 'build',\n 'out',\n 'wwwroot',\n 'Frontend/dist',\n 'frontend/dist',\n 'client/dist'\n ];\n\n for (const c of candidates) {\n const candidatePath = path.resolve(process.cwd(), c);\n if (fs.existsSync(candidatePath) && fs.existsSync(path.join(candidatePath, 'index.html'))) {\n return candidatePath;\n }\n }\n\n for (const c of candidates) {\n const candidatePath = path.resolve(process.cwd(), c);\n if (fs.existsSync(candidatePath)) {\n return candidatePath;\n }\n }\n\n return path.resolve(process.cwd(), 'dist');\n}","import http from 'http';\nimport fs from 'fs';\nimport path from 'path';\nimport type { Browser, BrowserContext, Page } from 'playwright';\nimport { chromium } from '../lib/playwrightLoader';\nimport { MockIpcRegistry, generateMockIpcScript } from '../../features/mock-ipc/mockIpc';\nimport type { MockRouteEntry } from '../api/dsl';\nimport { resolveWwwrootDir } from '../lib/config';\n \n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf'\n};\n\nexport interface PreviewDriverOptions {\n wwwrootDir?: string;\n headed?: boolean;\n url?: string;\n}\n\nexport class PreviewDriver {\n private server: http.Server | null = null;\n private browser: Browser | null = null;\n private context: BrowserContext | null = null;\n private page: Page | null = null;\n private serverPort: number = 0;\n private options: PreviewDriverOptions;\n private _baseUrl: string = '';\n private initialRouteMocks: MockRouteEntry[] = [];\n\n public readonly mockRegistry: MockIpcRegistry;\n \n\n constructor(options?: PreviewDriverOptions) {\n this.options = options || {};\n if (!this.options.url) {\n this.options.wwwrootDir = resolveWwwrootDir(this.options.wwwrootDir);\n }\n this.mockRegistry = new MockIpcRegistry();\n }\n\n public get baseUrl(): string {\n return this._baseUrl;\n }\n\n public async start(initialViewport = { width: 1200, height: 800 }): Promise<{ page: Page; context: BrowserContext; browser: Browser }> {\n let targetUrl = this.options.url;\n\n if (!targetUrl) {\n if (!fs.existsSync(this.options.wwwrootDir!)) {\n throw new Error(`Directory not found at: ${this.options.wwwrootDir}. Please build your frontend project first or pass --url=<url>.`);\n }\n\n await new Promise<void>((resolve, reject) => {\n this.server = http.createServer((req, res) => {\n let reqUrl = req.url?.split('?')[0] || '/';\n if (reqUrl === '/') reqUrl = '/index.html';\n\n let safePath = path.normalize(path.join(this.options.wwwrootDir!, reqUrl));\n if (!safePath.startsWith(this.options.wwwrootDir!)) {\n res.writeHead(403);\n return res.end('Forbidden');\n }\n\n if (!fs.existsSync(safePath) || fs.statSync(safePath).isDirectory()) {\n // SPA fallback to index.html\n safePath = path.join(this.options.wwwrootDir!, 'index.html');\n }\n\n const ext = path.extname(safePath).toLowerCase();\n const contentType = MIME_TYPES[ext] || 'application/octet-stream';\n\n try {\n const content = fs.readFileSync(safePath);\n res.writeHead(200, { 'Content-Type': contentType });\n res.end(content);\n } catch (e: any) {\n res.writeHead(500);\n res.end(`Server error: ${e.message}`);\n }\n });\n\n this.server.listen(0, '127.0.0.1', () => {\n const addr = this.server?.address();\n if (typeof addr === 'object' && addr?.port) {\n this.serverPort = addr.port;\n this._baseUrl = `http://127.0.0.1:${this.serverPort}`;\n resolve();\n } else {\n reject(new Error('Failed to acquire port for static preview server'));\n }\n });\n });\n\n targetUrl = `${this._baseUrl}/index.html`;\n } else {\n this._baseUrl = targetUrl;\n console.log(`🌐 [PreviewDriver] Connecting directly to live URL: ${targetUrl}`);\n }\n\n this.browser = await chromium.launch({\n headless: !this.options.headed,\n args: ['--no-sandbox', '--disable-setuid-sandbox']\n });\n\n this.context = await this.browser.newContext({\n viewport: initialViewport,\n deviceScaleFactor: 1\n });\n\n if (this.mockRegistry.size > 0) {\n const mockScript = generateMockIpcScript(this.mockRegistry);\n await this.context.addInitScript(mockScript);\n }\n\n this.page = await this.context.newPage();\n\n if (this.initialRouteMocks.length > 0) {\n for (const entry of this.initialRouteMocks) {\n await this.addRouteMock(entry);\n }\n }\n\n await this.page.goto(targetUrl, { waitUntil: 'domcontentloaded' });\n\n return { page: this.page, context: this.context, browser: this.browser };\n }\n\n public async addRouteMock(entry: MockRouteEntry): Promise<void> {\n if (!this.page) {\n this.initialRouteMocks.push(entry);\n return;\n }\n\n await this.page.route(entry.url, async (route) => {\n const req = route.request();\n if (entry.method && req.method().toUpperCase() !== entry.method.toUpperCase()) {\n return route.continue();\n }\n\n if (entry.delayMs) {\n await new Promise((r) => setTimeout(r, entry.delayMs));\n }\n\n const isJson = typeof entry.body === 'object' && entry.body !== null;\n await route.fulfill({\n status: entry.status ?? 200,\n contentType: isJson ? 'application/json' : 'text/plain; charset=utf-8',\n body: isJson ? JSON.stringify(entry.body) : String(entry.body ?? ''),\n headers: entry.headers\n });\n });\n }\n\n public async setupRouteMocks(routes: MockRouteEntry[]): Promise<void> {\n for (const r of routes) {\n await this.addRouteMock(r);\n }\n }\n \n\n public async updateMockIpc(action: string, data: any, options?: { type?: string; delayMs?: number }): Promise<void> {\n if (!this.page) {\n throw new Error('PreviewDriver not started. Call start() first.');\n }\n\n this.mockRegistry.set(action, data, options as any);\n\n await this.page.evaluate(\n ({ action, mock }) => {\n if (!(window as any).__visualRunnerMocks) {\n (window as any).__visualRunnerMocks = {};\n }\n (window as any).__visualRunnerMocks[action] = mock;\n },\n {\n action,\n mock: {\n data,\n type: options?.type ?? 'SUCCESS',\n delayMs: options?.delayMs ?? 20\n }\n }\n );\n }\n\n public async stop(): Promise<void> {\n if (this.context) {\n await this.context.close().catch(() => {});\n this.context = null;\n }\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n if (this.server) {\n await new Promise<void>((resolve) => {\n this.server?.close(() => resolve());\n });\n this.server = null;\n }\n }\n}\n","import { spawn, type ChildProcess } from 'child_process';\nimport treeKill from 'tree-kill';\n\nexport interface ProcessStartOptions {\n \n cwd?: string;\n env?: NodeJS.ProcessEnv;\n}\n\nexport class ProcessManager {\n private childProcess: ChildProcess | null = null;\n private isStopped = false;\n\n public async start(command: string, options?: ProcessStartOptions): Promise<void> {\n const cwd = options?.cwd || process.cwd();\n console.log(`šŸš€ [ProcessManager] Starting command: \"${command}\" in ${cwd}`);\n\n this.childProcess = spawn(command, {\n cwd,\n env: { ...process.env, ...options?.env },\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n this.childProcess.stdout?.on('data', (chunk) => {\n const line = chunk.toString().trim();\n if (line) {\n // Subprocess stdout output handled silently unless needed\n }\n });\n\n this.childProcess.stderr?.on('data', (chunk) => {\n const line = chunk.toString().trim();\n if (line && !line.includes('ExperimentalWarning')) {\n // Forward warning if necessary\n }\n });\n\n this.childProcess.on('exit', (code, signal) => {\n if (!this.isStopped && code !== 0 && code !== null) {\n console.warn(`āš ļø [ProcessManager] Subprocess exited prematurely with code ${code}, signal ${signal}`);\n }\n });\n }\n\n public async waitForUrl(url: string, timeoutMs = 30000): Promise<boolean> {\n console.log(`ā³ [ProcessManager] Waiting for ${url} to respond...`);\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n if (this.childProcess && this.childProcess.exitCode !== null) {\n throw new Error(\n `[ProcessManager] Server process exited with code ${this.childProcess.exitCode} while waiting for ${url}`\n );\n }\n\n try {\n const response = await fetch(url, { signal: AbortSignal.timeout(1000) });\n if (response.status) {\n console.log(`āœ… [ProcessManager] Target ${url} is ready (status: ${response.status})!`);\n return true;\n }\n } catch {\n // Retry on connection refused or timeout\n }\n\n await new Promise((r) => setTimeout(r, 500));\n }\n\n throw new Error(`[ProcessManager] Timeout after ${timeoutMs}ms waiting for ${url} to respond.`);\n }\n\n public async stop(): Promise<void> {\n if (this.isStopped || !this.childProcess || !this.childProcess.pid) {\n return;\n }\n\n this.isStopped = true;\n const pid = this.childProcess.pid;\n console.log(`šŸ›‘ [ProcessManager] Terminating process tree for PID ${pid}...`);\n\n await new Promise<void>((resolve) => {\n treeKill(pid, 'SIGTERM', (err) => {\n if (err) {\n try {\n treeKill(pid, 'SIGKILL');\n } catch {\n // ignore\n }\n }\n resolve();\n });\n });\n\n this.childProcess = null;\n }\n}","import path from 'path';\r\nimport fs from 'fs';\r\nimport type { Page, BrowserContext } from 'playwright';\r\nimport {\r\n type VisualScenario,\r\n type TestContext,\r\n type ViewportPreset,\r\n VIEWPORT_PRESETS,\r\n type CaptureOptions,\r\n type CaptureBurstOptions\r\n} from '../../shared/api/dsl';\r\nimport { CaptureEngine } from '../capture/capture';\r\nimport { VisualReporter } from '../reporter/reporter';\r\nimport { ConsoleTracker } from '../console-tracker/consoleTracker';\r\nimport { DesktopDriver } from '../../shared/drivers/desktopDriver';\r\nimport { PreviewDriver } from '../../shared/drivers/previewDriver';\r\nimport { ProcessManager } from '../../shared/lib/processManager';\r\n\r\nexport interface RunOptions {\r\n scenario: VisualScenario;\r\n targetMode?: 'desktop' | 'preview';\r\n artifactsRoot?: string;\r\n autoLaunchDesktop?: boolean;\r\n port?: number;\r\n wwwrootDir?: string;\r\n executablePath?: string;\r\n desktopArgs?: string[];\r\n desktopEnv?: Record<string, string>;\r\n cleanPaths?: string[];\r\n url?: string;\r\n startCommand?: string;\r\n startCwd?: string;\r\n cleanArtifacts?: boolean;\r\n headed?: boolean;\r\n detach?: boolean;\r\n globalMocks?: any[];\r\n}\r\n\r\nexport interface RunResult {\r\n scenarioId: string;\r\n targetMode: 'desktop' | 'preview';\r\n success: boolean;\r\n totalSnapshots: number;\r\n consoleErrors: number;\r\n consoleWarnings: number;\r\n reportPath: string;\r\n artifactsDir: string;\r\n error?: string;\r\n}\r\n\r\nexport async function runVisualScenario(options: RunOptions): Promise<RunResult> {\r\n const { scenario } = options;\r\n const targetMode = options.targetMode || 'preview';\r\n const startTime = Date.now();\r\n\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\r\n const artifactsRoot = options.artifactsRoot || path.resolve(process.cwd(), 'artifacts');\r\n\r\n if (options.cleanArtifacts && fs.existsSync(artifactsRoot)) {\r\n console.log(`🧹 [Clean Artifacts] Purging previous artifact runs in ${artifactsRoot}...`);\r\n const entries = fs.readdirSync(artifactsRoot, { withFileTypes: true });\r\n for (const entry of entries) {\r\n fs.rmSync(path.join(artifactsRoot, entry.name), { recursive: true, force: true });\r\n }\r\n }\r\n\r\n const scenarioArtifactsDir = path.join(artifactsRoot, `${scenario.id}_${timestamp}`);\r\n \r\n if (!fs.existsSync(scenarioArtifactsDir)) {\r\n fs.mkdirSync(scenarioArtifactsDir, { recursive: true });\r\n }\r\n\r\n const captureEngine = new CaptureEngine(scenarioArtifactsDir);\r\n const consoleTracker = new ConsoleTracker();\r\n const defaultViewport = scenario.viewports?.[0] || VIEWPORT_PRESETS.DEFAULT;\r\n let currentViewport = { width: defaultViewport.width, height: defaultViewport.height };\r\n\r\n let desktopDriver: DesktopDriver | null = null;\r\n let previewDriver: PreviewDriver | null = null;\r\n let processManager: ProcessManager | null = null;\r\n\r\n try {\r\n let page: Page;\r\n let context: BrowserContext;\r\n\r\n console.log(`\\n========================================`);\r\n console.log(`šŸš€ Starting Visual Test: ${scenario.title}`);\r\n console.log(`šŸŽÆ Mode: ${targetMode.toUpperCase()}`);\r\n console.log(`šŸ“ Artifacts: ${scenarioArtifactsDir}`);\r\n console.log(`========================================\\n`);\r\n\r\n if (options.startCommand) {\r\n processManager = new ProcessManager();\r\n await processManager.start(options.startCommand, { cwd: options.startCwd });\r\n const waitTarget = options.url || 'http://localhost:5173';\r\n await processManager.waitForUrl(waitTarget);\r\n }\r\n\r\n if (typeof scenario.setup === 'function') {\r\n console.log(`šŸ”§ [Scenario Setup] Executing setup hook...`);\r\n await scenario.setup();\r\n }\r\n\r\n if (targetMode === 'desktop') {\r\n desktopDriver = new DesktopDriver({\r\n port: options.port || 9222,\r\n autoLaunch: options.autoLaunchDesktop ?? true,\r\n executablePath: options.executablePath,\r\n args: options.desktopArgs,\r\n env: options.desktopEnv\r\n });\r\n const res = await desktopDriver.start(currentViewport);\r\n page = res.page;\r\n context = res.context;\r\n } else {\r\n previewDriver = new PreviewDriver({\r\n wwwrootDir: options.wwwrootDir,\r\n url: options.url,\r\n headed: options.headed\r\n });\r\n\r\n // Apply declarative mockIpc from scenario and global mocks before start\r\n const mergedMocks = [...(options.globalMocks || []), ...(scenario.mockIpc || [])];\r\n if (mergedMocks.length > 0) {\r\n console.log(`šŸ“¦ [Mock IPC] Applying ${mergedMocks.length} mocks`);\r\n previewDriver.mockRegistry.setBatch(mergedMocks);\r\n }\r\n\r\n if (scenario.mockRoutes && scenario.mockRoutes.length > 0) {\r\n console.log(`🌐 [Mock Network] Queuing ${scenario.mockRoutes.length} route mock(s)`);\r\n await previewDriver.setupRouteMocks(scenario.mockRoutes);\r\n }\r\n\r\n const res = await previewDriver.start(currentViewport);\r\n page = res.page;\r\n context = res.context;\r\n\r\n if (scenario.mockRoutes && scenario.mockRoutes.length > 0) {\r\n await previewDriver.setupRouteMocks(scenario.mockRoutes);\r\n }\r\n }\r\n \r\n\r\n // Attach console error interception\r\n consoleTracker.attach(page);\r\n console.log(`šŸ” [Console Tracker] Attached — errors and warnings will be captured\\n`);\r\n\r\n // Internal navigation function supporting live URLs and hash routing\r\n const doNavigate = async (route: string) => {\r\n if (route.startsWith('http://') || route.startsWith('https://')) {\r\n await page.goto(route, { waitUntil: 'domcontentloaded' });\r\n await page.waitForTimeout(300);\r\n return;\r\n }\r\n if (route.startsWith('#')) {\r\n await page.evaluate((r) => { window.location.hash = r; }, route);\r\n await page.waitForTimeout(300);\r\n return;\r\n }\r\n if (previewDriver?.baseUrl && options.url) {\r\n try {\r\n const fullUrl = new URL(route, previewDriver.baseUrl).toString();\r\n await page.goto(fullUrl, { waitUntil: 'domcontentloaded' });\r\n await page.waitForTimeout(300);\r\n return;\r\n } catch {\r\n // fallback to hash\r\n }\r\n }\r\n const routePath = route.startsWith('/') ? route : `/${route}`;\r\n await page.evaluate((r) => {\r\n if (window.location.hash !== undefined) {\r\n window.location.hash = r;\r\n }\r\n }, routePath);\r\n await page.waitForTimeout(300);\r\n };\r\n\r\n if (scenario.route) {\r\n console.log(`[Runner] Navigating to route: ${scenario.route}`);\r\n await doNavigate(scenario.route);\r\n }\r\n\r\n const ctx: TestContext = {\r\n page,\r\n context,\r\n targetMode,\r\n currentViewport,\r\n\r\n\r\n capture: async (name: string, opts?: CaptureOptions) => {\r\n console.log(`šŸ“ø [Snapshot] ${name} (${currentViewport.width}x${currentViewport.height})`);\r\n return await captureEngine.takeSnapshot(page, name, currentViewport, opts);\r\n },\r\n\r\n captureBurst: async (name: string, opts: CaptureBurstOptions) => {\r\n console.log(`šŸŽ¬ [Burst] ${name} (duration: ${opts.durationMs}ms, interval: ${opts.intervalMs ?? 80}ms)`);\r\n return await captureEngine.takeBurst(page, name, currentViewport, opts);\r\n },\r\n\r\n\r\n navigate: async (route: string) => {\r\n console.log(`🧭 [Navigate] ${route}`);\r\n await doNavigate(route);\r\n },\r\n\r\n // ─── Viewport ───\r\n\r\n resize: async (width: number, height: number) => {\r\n console.log(`šŸ“ [Resize] ${width}x${height}`);\r\n currentViewport = { width, height };\r\n ctx.currentViewport = currentViewport;\r\n await page.setViewportSize(currentViewport);\r\n await page.waitForTimeout(200);\r\n },\r\n\r\n setPreset: async (preset: ViewportPreset) => {\r\n console.log(`šŸ“ [Preset] ${preset.name} (${preset.width}x${preset.height})`);\r\n await ctx.resize(preset.width, preset.height);\r\n },\r\n\r\n resizeToFit: async (selector?: string, padding = 0) => {\r\n let boundingBox;\r\n if (selector) {\r\n const el = await page.$(selector);\r\n if (el) {\r\n boundingBox = await el.boundingBox();\r\n }\r\n } else {\r\n boundingBox = await page.evaluate(() => {\r\n return {\r\n width: document.documentElement.scrollWidth,\r\n height: document.documentElement.scrollHeight\r\n };\r\n });\r\n }\r\n\r\n if (boundingBox) {\r\n const newWidth = Math.ceil(boundingBox.width) + padding * 2;\r\n const newHeight = Math.ceil(boundingBox.height) + padding * 2;\r\n console.log(`šŸ“ [ResizeToFit] ${selector || 'body'} -> ${newWidth}x${newHeight}`);\r\n await ctx.resize(newWidth, newHeight);\r\n } else {\r\n console.log(`āš ļø [ResizeToFit] Element ${selector} not found or has no bounding box.`);\r\n }\r\n },\r\n\r\n\r\n wait: async (ms: number) => {\r\n await page.waitForTimeout(ms);\r\n },\r\n\r\n waitForSelector: async (selector: string, timeoutMs = 5000) => {\r\n await page.waitForSelector(selector, { timeout: timeoutMs });\r\n },\r\n\r\n\r\n click: async (selector: string) => {\r\n console.log(`šŸ–±ļø [Click] ${selector}`);\r\n await page.click(selector);\r\n },\r\n \r\n rightClick: async (selector: string) => {\r\n console.log(`šŸ–±ļø [RightClick] ${selector}`);\r\n await page.click(selector, { button: 'right' });\r\n },\r\n\r\n type: async (selector: string, text: string) => {\r\n console.log(`āŒØļø [Type] ${selector} -> \"${text}\"`);\r\n await page.fill(selector, text);\r\n },\r\n \r\n selectOption: async (selector: string, value: string) => {\r\n console.log(`āœ… [Select] ${selector} -> \"${value}\"`);\r\n await page.selectOption(selector, value);\r\n },\r\n\r\n hover: async (selector: string) => {\r\n console.log(`šŸ‘† [Hover] ${selector}`);\r\n await page.hover(selector);\r\n },\r\n \r\n scroll: async (selector: string, deltaY: number) => {\r\n console.log(`šŸ“œ [Scroll] ${selector} by ${deltaY}px`);\r\n await page.evaluate(({ sel, dY }) => {\r\n const el = document.querySelector(sel);\r\n if (el) {\r\n el.scrollTop += dY;\r\n } else {\r\n window.scrollBy(0, dY);\r\n }\r\n }, { sel: selector, dY: deltaY });\r\n await page.waitForTimeout(100);\r\n },\r\n\r\n\r\n log: (msg: string) => {\r\n console.log(`ā„¹ļø [Scenario] ${msg}`);\r\n },\r\n\r\n // ─── Mock IPC ───\r\n\r\n setMockIpc: async (action: string, data: any, mockOptions?) => {\r\n if (targetMode === 'desktop') {\r\n console.log(`āš ļø [Mock IPC] setMockIpc ignored in desktop mode (real backend handles IPC)`);\r\n return;\r\n }\r\n if (!previewDriver) {\r\n console.log(`āš ļø [Mock IPC] PreviewDriver not available`);\r\n return;\r\n }\r\n console.log(`šŸ“¦ [Mock IPC] Set ${action} -> ${typeof data === 'string' ? data : JSON.stringify(data).slice(0, 80)}...`);\r\n await previewDriver.updateMockIpc(action, data, mockOptions);\r\n },\r\n\r\n setMockRoute: async (url: string, body: any, routeOptions?) => {\r\n if (targetMode === 'desktop') {\r\n console.log(`āš ļø [Mock Route] setMockRoute ignored in desktop mode`);\r\n return;\r\n }\r\n if (!previewDriver) {\r\n console.log(`āš ļø [Mock Route] PreviewDriver not available`);\r\n return;\r\n }\r\n console.log(`🌐 [Mock Route] Intercepting ${routeOptions?.method || 'ALL'} ${url} -> ${routeOptions?.status ?? 200}`);\r\n await previewDriver.addRouteMock({\r\n url,\r\n body,\r\n method: routeOptions?.method,\r\n status: routeOptions?.status,\r\n delayMs: routeOptions?.delayMs,\r\n headers: routeOptions?.headers\r\n });\r\n },\r\n\r\n\r\n getConsoleErrors: () => consoleTracker.getErrors(),\r\n \r\n getConsoleWarnings: () => consoleTracker.getWarnings(),\r\n hasConsoleErrors: () => consoleTracker.hasErrors,\r\n\r\n // ─── DOM Assertions ───\r\n\r\n readText: async (selector: string): Promise<string | null> => {\r\n const text = await page.textContent(selector);\r\n return text ? text.trim() : null;\r\n },\r\n \r\n getPageText: async (): Promise<string> => {\r\n return await page.evaluate(() => document.body.innerText || '');\r\n },\r\n\r\n isVisible: async (selector: string) => {\r\n try {\r\n const element = await page.$(selector);\r\n if (!element) return false;\r\n return await element.isVisible();\r\n } catch {\r\n return false;\r\n }\r\n },\r\n\r\n getElementCount: async (selector: string) => {\r\n const elements = await page.$$(selector);\r\n return elements.length;\r\n }\r\n };\r\n\r\n await scenario.run(ctx);\r\n\r\n const durationMs = Date.now() - startTime;\r\n const snapshots = captureEngine.getSnapshots();\r\n const consoleErrors = consoleTracker.getErrors();\r\n const consoleWarnings = consoleTracker.getWarnings();\r\n\r\n if (consoleErrors.length > 0) {\r\n console.log(`\\nšŸ”“ Console Errors: ${consoleErrors.length}`);\r\n consoleErrors.forEach((err, i) => console.log(` ${i + 1}. ${err.text.slice(0, 120)}`));\r\n }\r\n if (consoleWarnings.length > 0) {\r\n console.log(`\\n🟔 Console Warnings: ${consoleWarnings.length}`);\r\n }\r\n\r\n const reportPath = VisualReporter.generateReport({\r\n scenario,\r\n snapshots,\r\n consoleErrors,\r\n consoleWarnings,\r\n outputDir: scenarioArtifactsDir,\r\n targetMode,\r\n durationMs\r\n });\r\n\r\n const syncLatest = (repPath: string, snaps: any[]) => {\r\n try {\r\n const latestDir = path.join(artifactsRoot, 'latest');\r\n if (fs.existsSync(latestDir)) {\r\n fs.rmSync(latestDir, { recursive: true, force: true });\r\n }\r\n fs.mkdirSync(latestDir, { recursive: true });\r\n fs.copyFileSync(repPath, path.join(latestDir, 'report.md'));\r\n const manifestSrc = path.join(scenarioArtifactsDir, 'manifest.json');\r\n if (fs.existsSync(manifestSrc)) {\r\n fs.copyFileSync(manifestSrc, path.join(latestDir, 'manifest.json'));\r\n }\r\n for (const snap of snaps) {\r\n if (snap.filePath && fs.existsSync(snap.filePath)) {\r\n fs.copyFileSync(snap.filePath, path.join(latestDir, snap.fileName));\r\n }\r\n }\r\n return path.join(latestDir, 'report.md');\r\n } catch {\r\n return undefined;\r\n }\r\n };\r\n\r\n const latestReport = syncLatest(reportPath, snapshots);\r\n\r\n console.log(`\\nāœ… Visual Test Completed Successfully!`);\r\n console.log(`šŸ“Š Captured Snapshots: ${snapshots.length}`);\r\n console.log(`šŸ”“ Console Errors: ${consoleErrors.length}`);\r\n console.log(`🟔 Console Warnings: ${consoleWarnings.length}`);\r\n console.log(`šŸ“„ Markdown Report: ${reportPath}`);\r\n if (latestReport) {\r\n console.log(`šŸ“Œ Latest Report: ${latestReport}`);\r\n }\r\n\r\n return {\r\n scenarioId: scenario.id,\r\n targetMode,\r\n success: true,\r\n totalSnapshots: snapshots.length,\r\n consoleErrors: consoleErrors.length,\r\n consoleWarnings: consoleWarnings.length,\r\n reportPath,\r\n artifactsDir: scenarioArtifactsDir\r\n };\r\n } catch (err: any) {\r\n console.error(`\\nāŒ Visual Test Failed: ${err.message}`);\r\n const durationMs = Date.now() - startTime;\r\n const snapshots = captureEngine.getSnapshots();\r\n const consoleErrors = consoleTracker.getErrors();\r\n const consoleWarnings = consoleTracker.getWarnings();\r\n\r\n const reportPath = VisualReporter.generateReport({\r\n scenario,\r\n snapshots,\r\n consoleErrors,\r\n consoleWarnings,\r\n outputDir: scenarioArtifactsDir,\r\n targetMode,\r\n durationMs\r\n });\r\n\r\n try {\r\n const latestDir = path.join(artifactsRoot, 'latest');\r\n if (fs.existsSync(latestDir)) {\r\n fs.rmSync(latestDir, { recursive: true, force: true });\r\n }\r\n fs.mkdirSync(latestDir, { recursive: true });\r\n fs.copyFileSync(reportPath, path.join(latestDir, 'report.md'));\r\n } catch {\r\n // ignore\r\n }\r\n\r\n return {\r\n scenarioId: scenario.id,\r\n targetMode,\r\n success: false,\r\n totalSnapshots: snapshots.length,\r\n consoleErrors: consoleErrors.length,\r\n consoleWarnings: consoleWarnings.length,\r\n reportPath,\r\n artifactsDir: scenarioArtifactsDir,\r\n error: err.message\r\n };\r\n } finally {\r\n // 1. Run scenario teardown hook (guaranteed cleanup)\r\n if (typeof scenario.teardown === 'function') {\r\n try {\r\n console.log(`🧹 [Scenario Teardown] Executing teardown hook...`);\r\n await scenario.teardown();\r\n } catch (teardownErr: any) {\r\n console.error(`āš ļø [Scenario Teardown] Error during teardown:`, teardownErr.message);\r\n }\r\n }\r\n\r\n // 2. Perform requested file and folder cleanups\r\n if (options.cleanPaths && options.cleanPaths.length > 0) {\r\n for (const cleanTarget of options.cleanPaths) {\r\n try {\r\n const resolvedCleanPath = path.resolve(process.cwd(), cleanTarget);\r\n if (fs.existsSync(resolvedCleanPath)) {\r\n console.log(`🧹 [Auto-Cleanup] Removing: ${resolvedCleanPath}`);\r\n fs.rmSync(resolvedCleanPath, { recursive: true, force: true });\r\n }\r\n } catch (cleanErr: any) {\r\n console.error(`āš ļø [Auto-Cleanup] Failed to remove ${cleanTarget}:`, cleanErr.message);\r\n }\r\n }\r\n }\r\n\r\n // 3. Stop running drivers unless detached\r\n if (!options.detach) {\r\n if (desktopDriver) await desktopDriver.stop();\r\n if (previewDriver) await previewDriver.stop();\r\n if (processManager) await processManager.stop();\r\n } else {\r\n console.log('šŸ”— [Runner] Detach mode active, leaving browser/app open.');\r\n }\r\n }\r\n}\r\n","import path from 'path';\nimport fs from 'fs';\nimport { runVisualScenario } from '../runner/runner';\nimport { defineVisualTest, VIEWPORT_PRESETS, type ViewportPreset } from '../../shared/api/dsl';\nimport { resolveWwwrootDir } from '../../shared/lib/config';\n\nexport interface SnapCliOptions {\n url?: string;\n start?: string;\n startCwd?: string;\n selector?: string;\n viewports?: string[];\n waitMs?: number;\n name?: string;\n clean?: string[];\n cleanArtifacts?: boolean;\n headed?: boolean;\n detach?: boolean;\n outDir?: string;\n mode?: 'desktop' | 'preview';\n exe?: string;\n port?: number;\n}\n\nconst PRESET_MAP: Record<string, ViewportPreset> = {\n default: VIEWPORT_PRESETS.DEFAULT,\n desktop: VIEWPORT_PRESETS.DEFAULT,\n min: VIEWPORT_PRESETS.MIN_SUPPORTED,\n 'min-supported': VIEWPORT_PRESETS.MIN_SUPPORTED,\n wide: VIEWPORT_PRESETS.WIDE,\n mobile: { name: 'mobile', width: 375, height: 667 },\n tablet: { name: 'tablet', width: 768, height: 1024 },\n 'full-hd': VIEWPORT_PRESETS.FULL_HD\n};\n\nfunction parseViewportPresets(raw?: string[]): ViewportPreset[] {\n if (!raw || raw.length === 0) {\n return [VIEWPORT_PRESETS.DEFAULT, PRESET_MAP.mobile];\n }\n\n const presets: ViewportPreset[] = [];\n for (const item of raw) {\n const lower = item.toLowerCase().trim();\n if (PRESET_MAP[lower]) {\n presets.push(PRESET_MAP[lower]);\n } else if (lower.includes('x')) {\n const [w, h] = lower.split('x').map((n) => parseInt(n, 10));\n if (!isNaN(w) && !isNaN(h)) {\n presets.push({ name: `${w}x${h}`, width: w, height: h });\n }\n }\n }\n\n return presets.length > 0 ? presets : [VIEWPORT_PRESETS.DEFAULT, PRESET_MAP.mobile];\n}\n\nconst CANDIDATE_PORTS = [5173, 3000, 4321, 4200, 8080, 8000, 3001];\n\nasync function isPortResponding(url: string): Promise<boolean> {\n try {\n const res = await fetch(url, { signal: AbortSignal.timeout(800) });\n return Boolean(res.status);\n } catch {\n return false;\n }\n}\n\nasync function detectActiveDevServer(): Promise<string | null> {\n for (const port of CANDIDATE_PORTS) {\n const url = `http://localhost:${port}`;\n if (await isPortResponding(url)) {\n return url;\n }\n }\n return null;\n}\n\nexport async function runQuickSnap(options: SnapCliOptions): Promise<boolean> {\n let targetUrl = options.url;\n let useStaticPreview = false;\n let wwwrootDir: string | undefined;\n\n // Smart URL/Server Resolution when neither --url nor --start is explicitly provided\n if (!targetUrl && !options.start) {\n const activeUrl = await detectActiveDevServer();\n if (activeUrl) {\n targetUrl = activeUrl;\n console.log(`🌐 [Quick Snap] Detected active dev server on ${targetUrl}`);\n } else {\n // Check for compiled static files (dist, build, wwwroot)\n const candidateDir = resolveWwwrootDir();\n if (fs.existsSync(candidateDir) && fs.existsSync(path.join(candidateDir, 'index.html'))) {\n useStaticPreview = true;\n wwwrootDir = candidateDir;\n console.log(`šŸ“¦ [Quick Snap] No active server found. Detected built static directory at \"${candidateDir}\". Launching static preview...`);\n } else {\n console.error(`\\nāŒ [Quick Snap] No active server found on common ports (${CANDIDATE_PORTS.join(', ')}), and no static build found.`);\n console.log(`šŸ’” Suggested actions:`);\n console.log(` 1. Pass a start command: npx agent-lens snap --start=\"npm run dev\"`);\n console.log(` 2. Specify your URL: npx agent-lens snap --url=http://localhost:8080`);\n console.log(` 3. Build your static app: npm run build\\n`);\n return false;\n }\n }\n } else if (!targetUrl && options.start) {\n targetUrl = 'http://localhost:5173';\n }\n \n\n const waitMs = options.waitMs ?? 1000;\n const snapshotPrefix = options.name || 'quick_snap';\n const targetViewports = parseViewportPresets(options.viewports);\n\n console.log(`\\nšŸ“ø [Quick Snap] Preparing instant verification for: ${targetUrl || wwwrootDir}`);\n console.log(`šŸ“ [Quick Snap] Testing ${targetViewports.length} viewports: ${targetViewports.map((v) => `${v.name} (${v.width}x${v.height})`).join(', ')}`);\n if (options.selector) {\n console.log(`šŸŽÆ [Quick Snap] Focused element selector: \"${options.selector}\"`);\n }\n\n const snapScenario = defineVisualTest({\n id: 'quick-snap',\n title: `Quick Verification: ${targetUrl || 'Static Preview'}`,\n description: `One-shot automated snapshot and console health check`,\n route: targetUrl || '/',\n viewports: targetViewports,\n run: async (ctx) => {\n ctx.log(`Waiting ${waitMs}ms for page stabilization...`);\n await ctx.wait(waitMs);\n\n for (let i = 0; i < targetViewports.length; i++) {\n const vp = targetViewports[i];\n const stepNum = String(i + 1).padStart(2, '0');\n ctx.log(`Switching viewport to: ${vp.name} (${vp.width}x${vp.height})`);\n await ctx.setPreset(vp);\n await ctx.wait(200);\n await ctx.capture(`${stepNum}_${snapshotPrefix}_${vp.name}`);\n }\n\n if (options.selector) {\n ctx.log(`Focusing on selector: \"${options.selector}\"`);\n try {\n await ctx.setPreset(VIEWPORT_PRESETS.DEFAULT);\n await ctx.resizeToFit(options.selector, 15);\n await ctx.capture(`99_${snapshotPrefix}_element_focus`, { selector: options.selector });\n } catch (err: any) {\n ctx.log(`āš ļø Could not isolate selector \"${options.selector}\": ${err.message}`);\n }\n }\n\n const errors = ctx.getConsoleErrors();\n if (errors.length > 0) {\n ctx.log(`🚨 Caught ${errors.length} console errors during snap check!`);\n } else {\n ctx.log(`āœ… Clean run: No console errors detected.`);\n }\n }\n });\n\n const result = await runVisualScenario({\n scenario: snapScenario,\n targetMode: options.mode || 'preview',\n url: useStaticPreview ? undefined : targetUrl,\n wwwrootDir: useStaticPreview ? wwwrootDir : undefined,\n startCommand: options.start,\n startCwd: options.startCwd,\n executablePath: options.exe,\n cleanPaths: options.clean,\n cleanArtifacts: options.cleanArtifacts,\n port: options.port,\n headed: options.headed,\n detach: options.detach,\n artifactsRoot: options.outDir ? path.resolve(process.cwd(), options.outDir) : undefined\n });\n\n console.log(`\\n========================================`);\n console.log(`šŸ Quick Snap Finished!`);\n console.log(`šŸ“ø Snapshots: ${result.totalSnapshots}`);\n console.log(`šŸ”“ Console Errors: ${result.consoleErrors}`);\n console.log(`🟔 Console Warnings: ${result.consoleWarnings}`);\n console.log(`šŸ“„ Report: ${result.reportPath}`);\n console.log(`========================================\\n`);\n\n return result.success && result.consoleErrors === 0;\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { execSync } from 'child_process';\nimport { runVisualScenario } from '../features/runner/runner';\nimport type { VisualScenario } from '../shared/api/dsl';\nimport { createJiti } from 'jiti';\nimport { loadConfig, resolveWwwrootDir, detectStartCwd } from '../shared/lib/config';\nimport { runQuickSnap } from '../features/snap/snap';\n\n// Load config from agent-lens.json or package.json\nconst fileConfig = loadConfig();\n\n// Parse CLI Arguments\nconst args = process.argv.slice(2);\n\n// Check subcommands\nif (args[0] === 'init') {\n initScenarioTemplate();\n process.exit(0);\n}\n\nconst isSnapCommand = args[0] === 'snap';\nconst effectiveArgs = isSnapCommand ? args.slice(1) : args;\n\nconst options: {\n scenario?: string;\n mode: 'desktop' | 'preview';\n all?: boolean;\n port: number;\n help?: boolean;\n headed?: boolean;\n detach?: boolean;\n build?: boolean | string;\n start?: string;\n startCwd?: string;\n cleanArtifacts?: boolean;\n url?: string;\n selector?: string;\n viewports?: string[];\n waitMs?: number;\n name?: string;\n exe?: string;\n clean?: string[];\n dir?: string;\n wwwroot?: string;\n outDir?: string;\n} = {\n mode: fileConfig.mode || 'preview',\n port: fileConfig.port || 9222,\n headed: fileConfig.headed ?? false,\n detach: fileConfig.detach ?? false,\n build: fileConfig.buildCommand || false,\n start: fileConfig.startCommand,\n startCwd: fileConfig.startCwd,\n cleanArtifacts: fileConfig.cleanArtifacts ?? false,\n url: fileConfig.url,\n exe: fileConfig.executablePath,\n clean: Array.isArray(fileConfig.clean) ? fileConfig.clean : (fileConfig.clean ? [fileConfig.clean] : undefined),\n dir: fileConfig.scenarios,\n wwwroot: fileConfig.wwwroot,\n outDir: fileConfig.outDir\n};\n\nfor (const arg of effectiveArgs) {\n if (arg === '--help' || arg === '-h') {\n options.help = true;\n } else if (arg.startsWith('--scenario=')) {\n options.scenario = arg.split('=')[1];\n } else if (arg === '--all') {\n options.all = true;\n } else if (arg.startsWith('--mode=')) {\n const mode = arg.split('=')[1].toLowerCase();\n if (mode === 'desktop' || mode === 'preview') {\n options.mode = mode as 'desktop' | 'preview';\n }\n } else if (arg.startsWith('--port=')) {\n options.port = parseInt(arg.split('=')[1], 10) || 9222;\n } else if (arg === '--headed') {\n options.headed = true;\n } else if (arg === '--detach') {\n options.detach = true;\n } else if (arg === '--build') {\n options.build = true;\n } else if (arg.startsWith('--build=')) {\n options.build = arg.slice('--build='.length);\n } else if (arg.startsWith('--start=')) {\n options.start = arg.slice('--start='.length);\n } else if (arg.startsWith('--start-cwd=') || arg.startsWith('--cwd=')) {\n options.startCwd = arg.split('=')[1];\n } else if (arg === '--clean-artifacts') {\n options.cleanArtifacts = true;\n } else if (arg.startsWith('--url=')) {\n options.url = arg.split('=')[1];\n } else if (arg.startsWith('--selector=')) {\n options.selector = arg.split('=')[1];\n } else if (arg.startsWith('--viewports=')) {\n const raw = arg.slice('--viewports='.length);\n options.viewports = raw.split(',').map((v: string) => v.trim()).filter(Boolean);\n } else if (arg.startsWith('--wait=')) {\n options.waitMs = parseInt(arg.slice('--wait='.length), 10);\n } else if (arg.startsWith('--name=')) {\n options.name = arg.slice('--name='.length);\n } else if (arg.startsWith('--exe=')) {\n options.exe = arg.slice('--exe='.length);\n } else if (arg.startsWith('--executable=')) {\n options.exe = arg.slice('--executable='.length);\n } else if (arg.startsWith('--clean=') || arg.startsWith('--cleanup=')) {\n const prefix = arg.startsWith('--clean=') ? '--clean=' : '--cleanup=';\n const rawPaths = arg.slice(prefix.length);\n options.clean = rawPaths.split(',').map((p: string) => p.trim()).filter(Boolean);\n } else if (arg.startsWith('--dir=')) {\n options.dir = arg.split('=')[1];\n } else if (arg.startsWith('--wwwroot=')) {\n options.wwwroot = arg.split('=')[1];\n } else if (arg.startsWith('--outDir=') || arg.startsWith('--folder=')) {\n options.outDir = arg.split('=')[1];\n }\n}\n\n// Auto-detect startCwd if a start command was provided in a monorepo setup\nif (options.start && !options.startCwd) {\n options.startCwd = detectStartCwd(options.startCwd);\n}\n\nfunction printHelp() {\n console.log(`\nšŸ‘ļø AgentLens - Visual UI Self-Verification for AI Agents\n\nUsage:\n npx agent-lens snap [options] Instant one-shot visual & console check (no test files needed)\n npx agent-lens [options] Run scripted scenario tests from scenarios/\n npx agent-lens init Generate starter scenario template & mocks\n\nCommands:\n snap Take immediate multi-viewport screenshots of a URL & check console errors\n init Generate starter template in scenarios/template.scenario.ts and mocks.ts\n\nOptions:\n --url=<url> Target URL to test (e.g. http://localhost:5173 or http://localhost:3000)\n --start=\"<cmd>\" Launch dev server or backend process before testing (e.g. --start=\"npm run dev\")\n --start-cwd=<path> Directory to execute --start command in (e.g. --start-cwd=./Frontend)\n --clean-artifacts Purge previous test artifacts to prevent folder bloat\n --selector=<css> Target a specific element to focus on / resize-to-fit\n --viewports=<list> Comma-separated viewport presets (default: desktop,mobile; or 1200x800,375x667)\n --wait=<ms> Wait time in milliseconds after loading before snapshotting [default: 1000]\n --name=<prefix> Custom name prefix for captured snapshots [default: quick_snap]\n --scenario=<name> Run specific scenario by name (e.g. --scenario=smoke)\n --all Run all discovered scenarios\n --mode=<mode> Engine mode: 'preview' (Web/Vite/Live) or 'desktop' (WebView2/CDP) [default: preview]\n --exe=<path> Path to native executable for desktop mode (e.g. --exe=bin/MyApp.exe)\n --port=<port> CDP remote debugging port [default: 9222]\n --build[=<cmd>] Run build command before testing (e.g. --build=\"dotnet build\" or npm run build)\n --clean=<paths> Comma-separated paths to safely delete upon test exit (e.g. --clean=\"./temp,./cache\")\n --headed Show Chromium browser window\n --detach Keep browser/app open after finishing\n --dir=<path> Custom scenarios directory [default: scenarios]\n --wwwroot=<path> Custom directory for static fallback mode [default: dist]\n --folder=<path> Directory to save visual artifacts/reports (also --outDir)\n --help, -h Show this help message\n `);\n}\n\nfunction initScenarioTemplate() {\n const targetDir = path.resolve(process.cwd(), 'scenarios');\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n\n // 1. Generate template.scenario.ts\n const templatePath = path.join(targetDir, 'template.scenario.ts');\n if (!fs.existsSync(templatePath)) {\n const templateContent = `import { defineVisualTest, VIEWPORT_PRESETS } from 'agent-lens';\n\nexport default defineVisualTest({\n id: 'template-check',\n title: 'Basic UI Smoke & Responsiveness Check',\n route: '/',\n // Optional setup hook before test runs\n setup: async () => {\n // prepare test files or folders\n },\n run: async (ctx) => {\n ctx.log('Initial page render');\n await ctx.capture('01_initial_state');\n\n // Test adaptive layout\n await ctx.setPreset(VIEWPORT_PRESETS.MIN_SUPPORTED);\n await ctx.capture('02_compact_view');\n\n // Check for JavaScript / React runtime errors\n const errors = ctx.getConsoleErrors();\n if (errors.length > 0) {\n ctx.log(\\`āš ļø Warning: Caught \\${errors.length} console errors!\\`);\n }\n },\n // Optional teardown hook guaranteed to run on exit\n teardown: async () => {\n // clean up temporary test files or state\n }\n});\n`;\n fs.writeFileSync(templatePath, templateContent, 'utf8');\n console.log(`āœ… Starter scenario generated at: ${templatePath}`);\n } else {\n console.log(`ā„¹ļø Template already exists at: ${templatePath}`);\n }\n\n // Generate starter mocks.ts to prevent root app crash\n const mocksPath = path.join(targetDir, 'mocks.ts');\n if (!fs.existsSync(mocksPath)) {\n const mocksContent = `/**\n * Global IPC & API Mocks\n * \n * Export an array of base mocks to satisfy root application state on boot.\n */\nexport default [\n { action: 'GET_PREFS', data: { theme: 'dark', language: 'en' } },\n { action: 'GET_USER_PROFILE', data: { id: 1, name: 'Agent', role: 'admin' } }\n];\n`;\n fs.writeFileSync(mocksPath, mocksContent, 'utf8');\n console.log(`āœ… Base global mocks generated at: ${mocksPath}`);\n }\n\n console.log(`šŸ‘‰ Run tests with: npx agent-lens --scenario=template --mode=preview`);\n}\n\nif (options.help) {\n printHelp();\n process.exit(0);\n}\n\nasync function findScenarios(dir: string, specificName?: string): Promise<string[]> {\n const results: string[] = [];\n if (!fs.existsSync(dir)) return results;\n\n const items = fs.readdirSync(dir, { withFileTypes: true });\n for (const item of items) {\n const fullPath = path.join(dir, item.name);\n if (item.isDirectory()) {\n results.push(...await findScenarios(fullPath, specificName));\n } else if (item.name.endsWith('.scenario.ts') || item.name.endsWith('.scenario.js')) {\n if (!specificName || item.name.startsWith(specificName)) {\n results.push(fullPath);\n }\n }\n }\n return results;\n}\n\nfunction resolveScenariosDirectory(customDir?: string): string {\n if (customDir) {\n return path.resolve(process.cwd(), customDir);\n }\n\n const candidates = [\n 'scenarios',\n 'tests/visual',\n 'tests/scenarios',\n 'test/scenarios',\n 'src/scenarios'\n ];\n\n for (const c of candidates) {\n const p = path.resolve(process.cwd(), c);\n if (fs.existsSync(p)) {\n return p;\n }\n }\n\n return path.resolve(process.cwd(), 'scenarios');\n}\n\nasync function main() {\n // One-shot \"snap\" command execution\n if (isSnapCommand || (options.url && !options.scenario && !options.all)) {\n const snapSuccess = await runQuickSnap({\n url: options.url,\n start: options.start,\n startCwd: options.startCwd,\n selector: options.selector,\n viewports: options.viewports,\n waitMs: options.waitMs,\n name: options.name,\n clean: options.clean,\n cleanArtifacts: options.cleanArtifacts,\n headed: options.headed,\n detach: options.detach,\n outDir: options.outDir,\n mode: options.mode,\n exe: options.exe,\n port: options.port\n });\n\n process.exit(snapSuccess ? 0 : 1);\n }\n\n // 2. Scenario-based test execution\n if (!options.scenario && !options.all) {\n console.error('āŒ Please specify a scenario (--scenario=name), run --all, or use: npx agent-lens snap --url=http://localhost:5173');\n printHelp();\n process.exit(1);\n }\n\n const scenariosDir = resolveScenariosDirectory(options.dir);\n const scenarioPaths = await findScenarios(scenariosDir, options.scenario);\n\n if (scenarioPaths.length === 0) {\n console.error(`āŒ No scenarios found in ${scenariosDir}`);\n console.log(`šŸ’” Generate a template with: npx agent-lens init`);\n process.exit(1);\n }\n\n const shouldBuild = options.build || fileConfig.autoBuild;\n if (shouldBuild) {\n const buildCmd = typeof options.build === 'string'\n ? options.build\n : (fileConfig.buildCommand || 'npm run build');\n\n console.log(`\\nšŸ”Ø [Build] Running build process: \"${buildCmd}\"...`);\n try {\n execSync(buildCmd, { stdio: 'inherit', cwd: options.startCwd || process.cwd() });\n } catch (e) {\n console.error(`āŒ Build failed: ${buildCmd}`);\n process.exit(1);\n }\n } else if (options.mode === 'preview' && !options.url && !options.start) {\n console.log(`āš ļø Warning: Running without --build or --url flag. Make sure your frontend is built!`);\n }\n\n console.log(`šŸ“‹ Found ${scenarioPaths.length} scenario(s) in: ${scenariosDir}`);\n\n // Initialize JITI for seamless TypeScript loading\n const jiti = createJiti(process.cwd());\n\n // Check for global mocks\n let globalMocks: any[] = [];\n const mockCandidates = [\n path.join(scenariosDir, 'mocks.ts'),\n path.join(scenariosDir, 'mocks.js'),\n path.join(process.cwd(), 'mocks.ts'),\n path.join(process.cwd(), 'mocks.js')\n ];\n\n for (const mocksPath of mockCandidates) {\n if (fs.existsSync(mocksPath)) {\n try {\n const m = await jiti.import(mocksPath) as any;\n globalMocks = m.default || m.mocks || [];\n console.log(`šŸŒ Loaded ${globalMocks.length} global mock(s) from ${path.basename(mocksPath)}`);\n break;\n } catch (err) {\n console.warn(`āš ļø Failed to load global mocks from ${mocksPath}:`, err);\n }\n }\n }\n\n let allSuccess = true;\n for (const scenarioPath of scenarioPaths) {\n try {\n const scenarioModule = await jiti.import(scenarioPath) as any;\n const scenario: VisualScenario = scenarioModule.default || scenarioModule.scenario;\n\n if (!scenario || typeof scenario.run !== 'function') {\n console.error(`āš ļø Skipped: file ${path.basename(scenarioPath)} does not export a VisualScenario object by default.`);\n continue;\n }\n\n const result = await runVisualScenario({\n scenario,\n targetMode: options.mode,\n url: options.url,\n startCommand: options.start,\n startCwd: options.startCwd,\n cleanArtifacts: options.cleanArtifacts,\n port: options.port,\n headed: options.headed,\n detach: options.detach,\n executablePath: options.exe,\n cleanPaths: options.clean,\n desktopEnv: fileConfig.env,\n wwwrootDir: options.wwwroot ? resolveWwwrootDir(options.wwwroot) : undefined,\n artifactsRoot: options.outDir ? path.resolve(process.cwd(), options.outDir) : undefined,\n globalMocks\n });\n\n if (!result.success) {\n allSuccess = false;\n }\n } catch (err: any) {\n console.error(`āŒ Failed to load scenario ${path.basename(scenarioPath)}:`, err);\n allSuccess = false;\n }\n }\n\n if (!allSuccess) {\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path","path","fs","path","fs","http","fs","path","action","spawn","treeKill","path","fs","path","fs","path","fs"]}
1
+ {"version":3,"sources":["../src/shared/lib/config.ts","../src/shared/api/plugin.ts","../src/shared/types/console.ts","../src/shared/types/ipc.ts","../src/shared/api/dsl.ts","../src/features/capture/capture.ts","../src/features/reporter/reporter.ts","../src/features/console-tracker/consoleTracker.ts","../src/shared/lib/playwrightLoader.ts","../src/shared/drivers/previewDriver.ts","../src/shared/lib/processManager.ts","../src/shared/lib/pluginLoader.ts","../src/features/runner/lib/navigation.ts","../src/features/runner/lib/artifactsSync.ts","../src/features/runner/lib/contextBuilder.ts","../src/features/runner/runner.ts","../src/features/runner/index.ts","../src/features/snap/snap.ts","../src/app/lib/argsParser.ts","../src/app/lib/help.ts","../src/app/lib/templateInit.ts","../src/app/lib/scenarioFinder.ts","../src/plugins/live-controller/session.ts","../src/plugins/live-controller/actions.ts","../src/app/cli.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs';\n\nexport interface AgentLensConfigFile {\n mode?: 'desktop' | 'preview';\n port?: number;\n headed?: boolean;\n detach?: boolean;\n buildCommand?: string;\n autoBuild?: boolean;\n startCommand?: string;\n startCwd?: string;\n cleanArtifacts?: boolean;\n url?: string;\n executablePath?: string;\n clean?: string | string[];\n scenarios?: string;\n wwwroot?: string;\n outDir?: string;\n env?: Record<string, string>;\n plugins?: string[];\n}\n\nexport function loadConfig(cwd: string = process.cwd()): AgentLensConfigFile {\n const jsonConfigPath = path.join(cwd, 'agent-lens.json');\n if (fs.existsSync(jsonConfigPath)) {\n try {\n const raw = fs.readFileSync(jsonConfigPath, 'utf-8');\n return JSON.parse(raw);\n } catch (e: any) {\n console.warn(`āš ļø [Config] Failed to parse agent-lens.json: ${e.message}`);\n }\n }\n\n const packageJsonPath = path.join(cwd, 'package.json');\n if (fs.existsSync(packageJsonPath)) {\n try {\n const raw = fs.readFileSync(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(raw);\n if (pkg.agentLens && typeof pkg.agentLens === 'object') {\n return pkg.agentLens;\n }\n } catch {\n // ignore\n }\n }\n\n return {};\n}\n\nexport function detectStartCwd(providedCwd?: string): string | undefined {\n if (providedCwd) {\n const resolved = path.resolve(process.cwd(), providedCwd);\n if (fs.existsSync(resolved)) {\n return providedCwd;\n }\n }\n\n const rootPkgPath = path.join(process.cwd(), 'package.json');\n let rootHasDevScript = false;\n if (fs.existsSync(rootPkgPath)) {\n try {\n const rootPkg = JSON.parse(fs.readFileSync(rootPkgPath, 'utf-8'));\n rootHasDevScript = Boolean(rootPkg.scripts?.dev || rootPkg.scripts?.start);\n } catch {\n // ignore\n }\n }\n\n if (rootHasDevScript) {\n return undefined;\n }\n\n const candidates = ['Frontend', 'frontend', 'client', 'web', 'ui', 'apps/web', 'src/frontend'];\n for (const candidate of candidates) {\n const candidatePkg = path.join(process.cwd(), candidate, 'package.json');\n if (fs.existsSync(candidatePkg)) {\n return `./${candidate}`;\n }\n }\n\n return undefined;\n}\n\nexport function resolveWwwrootDir(customDir?: string): string {\n if (customDir) {\n return path.resolve(process.cwd(), customDir);\n }\n\n const candidates = [\n 'dist',\n 'build',\n 'out',\n 'wwwroot',\n 'Frontend/dist',\n 'frontend/dist',\n 'client/dist'\n ];\n\n for (const c of candidates) {\n const candidatePath = path.resolve(process.cwd(), c);\n if (fs.existsSync(candidatePath) && fs.existsSync(path.join(candidatePath, 'index.html'))) {\n return candidatePath;\n }\n }\n\n for (const c of candidates) {\n const candidatePath = path.resolve(process.cwd(), c);\n if (fs.existsSync(candidatePath)) {\n return candidatePath;\n }\n }\n\n return path.resolve(process.cwd(), 'dist');\n}","import type { Page, BrowserContext, Browser } from 'playwright';\nimport type { TestContext, VisualScenario } from './dsl';\nimport type { ReportData } from '../types/report';\n\nexport interface DriverLaunchResult {\n page: Page;\n context: BrowserContext;\n browser?: Browser;\n stop?: () => Promise<void>;\n}\n\nexport interface PluginHookContext {\n scenario?: VisualScenario;\n targetMode: 'desktop' | 'preview' | string;\n artifactsDir: string;\n cliOptions?: Record<string, unknown>;\n state: Map<string, unknown>;\n}\n\nexport interface AgentLensPlugin {\n /** Unique plugin identifier (e.g. 'desktop-webview2', 'live-controller', 'mock-ipc') */\n name: string;\n version?: string;\n\n /** Lifecycle hook: initial setup before drivers and scenarios start */\n setup?: (context: PluginHookContext) => Promise<void> | void;\n\n /**\n * Microkernel driver hook: allows a plugin to provide a custom browser/page session\n * (e.g., desktop WebView2 CDP connection, custom remote browser).\n */\n launchSession?: (\n options: { currentViewport: { width: number; height: number }; headed?: boolean },\n hookContext: PluginHookContext\n ) => Promise<DriverLaunchResult | undefined>;\n\n /** Lifecycle hook: called when browser context is ready */\n onContextCreated?: (context: BrowserContext, hookContext: PluginHookContext) => Promise<void> | void;\n\n /** Lifecycle hook: called when the test page is created/navigated */\n onPageCreated?: (page: Page, context: BrowserContext, hookContext: PluginHookContext) => Promise<void> | void;\n\n /**\n * Context extension: inject custom methods or properties directly into TestContext (ctx)\n */\n extendContext?: (\n ctx: TestContext,\n page: Page,\n hookContext: PluginHookContext\n ) => Record<string, any> | Promise<Record<string, any>>;\n\n /** Lifecycle hook: called after scenario runs and report data is calculated */\n onAfterRun?: (reportData: ReportData, hookContext: PluginHookContext) => Promise<void> | void;\n\n /** Lifecycle hook: teardown and cleanup guaranteed to run */\n teardown?: (hookContext: PluginHookContext) => Promise<void> | void;\n}\n\nexport function definePlugin(plugin: AgentLensPlugin): AgentLensPlugin {\n return plugin;\n}","export interface ConsoleEntry {\n level: 'error' | 'warning' | 'info' | 'log' | 'debug';\n text: string;\n url: string;\n timestamp: string;\n stack?: string;\n}\n","export type MockIpcResponseType = 'SUCCESS' | 'ERROR';\n\nexport interface MockIpcEntry {\n action: string;\n data: any;\n type?: MockIpcResponseType;\n delayMs?: number;\n}\n","import type { Page, BrowserContext } from 'playwright';\nimport type { ConsoleEntry } from '../types/console';\nimport type { MockIpcResponseType } from '../types/ipc';\nimport type { AgentLensPlugin } from './plugin';\n\nexport * from './plugin';\nexport * from '../types/console';\nexport * from '../types/ipc';\n\nexport interface ViewportPreset {\n name: string;\n width: number;\n height: number;\n}\n\nexport const VIEWPORT_PRESETS = {\n /** Minimum supported window size */\n MIN_SUPPORTED: { name: 'min-supported', width: 1024, height: 768 } as ViewportPreset,\n /** Standard default window size */\n DEFAULT: { name: 'default', width: 1200, height: 800 } as ViewportPreset,\n /** Wide screen for checking grids and tables */\n WIDE: { name: 'wide', width: 1600, height: 900 } as ViewportPreset,\n /** Full HD */\n FULL_HD: { name: 'full-hd', width: 1920, height: 1080 } as ViewportPreset,\n};\n\nexport interface MockRouteEntry {\n url: string;\n method?: string;\n status?: number;\n body: any;\n delayMs?: number;\n headers?: Record<string, string>;\n}\n\nexport interface CaptureOptions {\n selector?: string;\n fullPage?: boolean;\n mask?: string[];\n}\n\nexport interface CaptureBurstOptions {\n /** Total duration of burst animation capture in milliseconds */\n durationMs: number;\n /** Interval between frames in milliseconds (default: 80ms) */\n intervalMs?: number;\n /** Restrict capture to a specific element */\n selector?: string;\n}\n\nexport interface SnapshotMetadata {\n index: number;\n name: string;\n fileName: string;\n filePath: string;\n relativeUri: string;\n viewport: { width: number; height: number };\n timestamp: string;\n isBurstFrame?: boolean;\n burstGroup?: string;\n frameIndex?: number;\n selector?: string;\n}\n\nexport interface TestContext {\n [key: string]: any;\n page: Page;\n context: BrowserContext;\n targetMode: 'desktop' | 'preview';\n currentViewport: { width: number; height: number };\n\n // --- Snapshots ---\n capture: (name: string, options?: CaptureOptions) => Promise<SnapshotMetadata>;\n captureBurst: (name: string, options: CaptureBurstOptions) => Promise<SnapshotMetadata[]>;\n\n // --- Navigation ---\n navigate: (route: string) => Promise<void>;\n\n // --- Viewport ---\n resize: (width: number, height: number) => Promise<void>;\n setPreset: (preset: ViewportPreset) => Promise<void>;\n resizeToFit: (selector?: string, padding?: number) => Promise<void>;\n\n // --- Waiting ---\n wait: (ms: number) => Promise<void>;\n waitForSelector: (selector: string, timeoutMs?: number) => Promise<void>;\n\n // --- Interaction ---\n click: (selector: string) => Promise<void>;\n rightClick: (selector: string) => Promise<void>;\n type: (selector: string, text: string) => Promise<void>;\n selectOption: (selector: string, value: string) => Promise<void>;\n hover: (selector: string) => Promise<void>;\n scroll: (selector: string, deltaY: number) => Promise<void>;\n\n // --- Logging ---\n log: (message: string) => void;\n\n // --- Mock IPC & Network Routes ---\n setMockIpc: (action: string, data: any, options?: { type?: MockIpcResponseType; delayMs?: number }) => Promise<void>;\n setMockRoute: (\n url: string,\n body: any,\n options?: { method?: string; status?: number; delayMs?: number; headers?: Record<string, string> }\n ) => Promise<void>;\n\n // --- Console Errors ---\n getConsoleErrors: () => ConsoleEntry[];\n getConsoleWarnings: () => ConsoleEntry[];\n hasConsoleErrors: () => boolean;\n\n // --- DOM Assertions ---\n readText: (selector: string) => Promise<string | null>;\n getPageText: () => Promise<string>;\n isVisible: (selector: string) => Promise<boolean>;\n getElementCount: (selector: string) => Promise<number>;\n}\n\nexport interface VisualScenario {\n /** Unique scenario identifier (kebab-case) */\n id: string;\n /** Human-readable title for the report */\n title: string;\n /** Description of what is being tested */\n description?: string;\n /** Initial route to navigate to (e.g., '/instances', '/settings') */\n route?: string;\n /** List of viewport sizes to test */\n viewports?: ViewportPreset[];\n /** Initial IPC mock data for preview mode */\n mockIpc?: Array<{ action: string; data: any; type?: MockIpcResponseType; delayMs?: number }>;\n /** Initial HTTP REST/GraphQL route mocks for preview mode */\n mockRoutes?: MockRouteEntry[];\n /** Optional plugins required for this scenario */\n plugins?: (string | AgentLensPlugin)[];\n /** Setup hook executed before scenario runs */\n setup?: () => Promise<void> | void;\n /** The main body of the scenario */\n run: (ctx: TestContext) => Promise<void>;\n /** Teardown hook guaranteed to run on completion */\n teardown?: () => Promise<void> | void;\n}\n\nexport function defineVisualTest(scenario: VisualScenario): VisualScenario {\n return scenario;\n}\n","import fs from 'fs';\r\nimport path from 'path';\r\nimport type { Page } from 'playwright';\r\nimport type { CaptureOptions, CaptureBurstOptions, SnapshotMetadata } from '../../shared/api/dsl';\r\n\r\nexport class CaptureEngine {\r\n private outputDir: string;\r\n private currentStepIndex: number = 0;\r\n private recordedSnapshots: SnapshotMetadata[] = [];\r\n\r\n constructor(outputDir: string) {\r\n this.outputDir = outputDir;\r\n if (!fs.existsSync(this.outputDir)) {\r\n fs.mkdirSync(this.outputDir, { recursive: true });\r\n }\r\n }\r\n\r\n public getSnapshots(): SnapshotMetadata[] {\r\n return this.recordedSnapshots;\r\n }\r\n\r\n public getOutputDir(): string {\r\n return this.outputDir;\r\n }\r\n\r\n /**\r\n */\r\n public async takeSnapshot(\r\n page: Page,\r\n name: string,\r\n viewport: { width: number; height: number },\r\n options?: CaptureOptions\r\n ): Promise<SnapshotMetadata> {\r\n this.currentStepIndex += 1;\r\n const paddedIndex = String(this.currentStepIndex).padStart(2, '0');\r\n const sanitizedName = name.replace(/[^a-zA-Z0-9_\\-]/g, '_');\r\n const fileName = `${paddedIndex}_${sanitizedName}_${viewport.width}x${viewport.height}.png`;\r\n const filePath = path.join(this.outputDir, fileName);\r\n\r\n if (options?.selector) {\r\n const element = await page.waitForSelector(options.selector, { timeout: 5000 });\r\n await element.screenshot({ path: filePath });\r\n } else {\r\n await page.screenshot({ path: filePath, fullPage: options?.fullPage ?? false });\r\n }\r\n\r\n const metadata: SnapshotMetadata = {\r\n index: this.currentStepIndex,\r\n name,\r\n fileName,\r\n filePath,\r\n relativeUri: `./${fileName}`,\r\n viewport,\r\n timestamp: new Date().toISOString(),\r\n selector: options?.selector\r\n };\r\n\r\n this.recordedSnapshots.push(metadata);\r\n return metadata;\r\n }\r\n\r\n /**\r\n */\r\n public async takeBurst(\r\n page: Page,\r\n name: string,\r\n viewport: { width: number; height: number },\r\n options: CaptureBurstOptions\r\n ): Promise<SnapshotMetadata[]> {\r\n this.currentStepIndex += 1;\r\n const stepIndex = this.currentStepIndex;\r\n const paddedIndex = String(stepIndex).padStart(2, '0');\r\n const sanitizedName = name.replace(/[^a-zA-Z0-9_\\-]/g, '_');\r\n\r\n const duration = Math.max(options.durationMs, 50);\r\n const interval = Math.max(options.intervalMs ?? 80, 20);\r\n const totalFrames = Math.ceil(duration / interval);\r\n\r\n const burstSnapshots: SnapshotMetadata[] = [];\r\n const burstGroup = sanitizedName;\r\n\r\n for (let frame = 0; frame <= totalFrames; frame++) {\r\n const elapsedMs = frame * interval;\r\n const paddedFrame = String(frame + 1).padStart(2, '0');\r\n const fileName = `${paddedIndex}_burst_${sanitizedName}_f${paddedFrame}_${elapsedMs}ms.png`;\r\n const filePath = path.join(this.outputDir, fileName);\r\n\r\n if (options.selector) {\r\n const element = await page.$(options.selector);\r\n if (element) {\r\n await element.screenshot({ path: filePath });\r\n } else {\r\n await page.screenshot({ path: filePath });\r\n }\r\n } else {\r\n await page.screenshot({ path: filePath });\r\n }\r\n\r\n const meta: SnapshotMetadata = {\r\n index: stepIndex,\r\n name: `${name} (frame ${frame + 1}, +${elapsedMs}ms)`,\r\n fileName,\r\n filePath,\r\n relativeUri: `./${fileName}`,\r\n viewport,\r\n timestamp: new Date().toISOString(),\r\n isBurstFrame: true,\r\n burstGroup,\r\n frameIndex: frame + 1,\r\n selector: options.selector\r\n };\r\n\r\n burstSnapshots.push(meta);\r\n this.recordedSnapshots.push(meta);\r\n\r\n if (frame < totalFrames) {\r\n await new Promise((r) => setTimeout(r, interval));\r\n }\r\n }\r\n\r\n return burstSnapshots;\r\n }\r\n}\r\n","import fs from 'fs';\nimport path from 'path';\nimport type { SnapshotMetadata, VisualScenario } from '../../shared/api/dsl';\nimport type { ConsoleEntry } from '../../shared/types/console';\nimport type { ReportData } from '../../shared/types/report';\n\nexport type { ReportData };\n\n\nexport class VisualReporter {\n public static generateReport(data: ReportData): string {\n const {\n scenario,\n snapshots,\n consoleErrors,\n consoleWarnings,\n outputDir,\n targetMode,\n durationMs\n } = data;\n\n const manifestPath = path.join(outputDir, 'manifest.json');\n const reportPath = path.join(outputDir, 'report.md');\n\n const manifest = {\n scenarioId: scenario.id,\n title: scenario.title,\n description: scenario.description,\n targetMode,\n durationMs,\n totalSnapshots: snapshots.length,\n consoleErrors: consoleErrors.length,\n consoleWarnings: consoleWarnings.length,\n createdAt: new Date().toISOString(),\n snapshots,\n errors: consoleErrors,\n warnings: consoleWarnings\n };\n fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n\n const rows: string[] = [];\n \n const regularSnapshots = snapshots.filter((s) => !s.isBurstFrame);\n const burstGroups = new Map<string, SnapshotMetadata[]>();\n\n snapshots.filter((s) => s.isBurstFrame && s.burstGroup).forEach((s) => {\n const list = burstGroups.get(s.burstGroup!) || [];\n list.push(s);\n burstGroups.set(s.burstGroup!, list);\n });\n\n for (const snap of regularSnapshots) {\n const relativeLink = snap.relativeUri || `./${snap.fileName}`;\n rows.push(\n `| **${String(snap.index).padStart(2, '0')}** | \\`${snap.viewport.width}x${snap.viewport.height}\\` | ${snap.name} | [${snap.fileName}](${relativeLink}) |`\n );\n }\n\n let burstSections = '';\n if (burstGroups.size > 0) {\n burstSections += `\\n### šŸŽ¬ Animation Bursts\\n\\n`;\n for (const [group, frames] of burstGroups.entries()) {\n burstSections += `#### Animation: \\`${group}\\` (${frames.length} frames)\\n\\n`;\n burstSections += `| Frame | Viewport | File | Preview |\\n| :--- | :--- | :--- | :--- |\\n`;\n for (const frame of frames) {\n const relativeLink = frame.relativeUri || `./${frame.fileName}`;\n burstSections += `| Frame ${frame.frameIndex} | \\`${frame.viewport.width}x${frame.viewport.height}\\` | [${frame.fileName}](${relativeLink}) | ![](${relativeLink}) |\\n`;\n }\n burstSections += `\\n`;\n }\n }\n \n\n const healthStatus = this.getHealthStatus(consoleErrors, consoleWarnings);\n let consoleSections = '';\n\n if (consoleErrors.length > 0) {\n consoleSections += `\\n## šŸ”“ Console Errors (${consoleErrors.length})\\n\\n`;\n consoleSections += `> [!CAUTION]\\n> Found **${consoleErrors.length}** JavaScript errors during the test. This might indicate broken components, missing data, or unhandled exceptions.\\n\\n`;\n consoleSections += `| # | Time | Error | URL |\\n| :-: | :--- | :--- | :--- |\\n`;\n consoleErrors.forEach((err, i) => {\n const time = err.timestamp.split('T')[1]?.slice(0, 8) || '';\n const text = err.text.replace(/\\|/g, '\\\\|').slice(0, 200);\n const url = err.url.replace(/\\|/g, '\\\\|');\n consoleSections += `| ${i + 1} | \\`${time}\\` | ${text} | \\`${url}\\` |\\n`;\n });\n\n const withStack = consoleErrors.filter(e => e.stack);\n if (withStack.length > 0) {\n consoleSections += `\\n<details>\\n<summary>šŸ“‹ Stack Traces (${withStack.length})</summary>\\n\\n`;\n withStack.forEach((err, i) => {\n consoleSections += `**Error ${i + 1}:** \\`${err.text.slice(0, 100)}\\`\\n\\`\\`\\`\\n${err.stack}\\n\\`\\`\\`\\n\\n`;\n });\n consoleSections += `</details>\\n`;\n }\n }\n\n if (consoleWarnings.length > 0) {\n consoleSections += `\\n## 🟔 Console Warnings (${consoleWarnings.length})\\n\\n`;\n consoleSections += `| # | Warning |\\n| :-: | :--- |\\n`;\n consoleWarnings.slice(0, 20).forEach((warn, i) => {\n const text = warn.text.replace(/\\|/g, '\\\\|').slice(0, 200);\n consoleSections += `| ${i + 1} | ${text} |\\n`;\n });\n if (consoleWarnings.length > 20) {\n consoleSections += `\\n*...and ${consoleWarnings.length - 20} more warnings (full list in manifest.json)*\\n`;\n }\n }\n\n let pluginSections = '';\n if (data.customSections && data.customSections.length > 0) {\n for (const sec of data.customSections) {\n pluginSections += `\\n## ${sec.title}\\n\\n${sec.content}\\n\\n`;\n }\n }\n\n const reportContent = `# šŸ“ø Visual Test Report: ${scenario.title}\n\n> **Scenario ID:** \\`${scenario.id}\\` \n> **Target Mode:** \\`${targetMode.toUpperCase()}\\` (${targetMode === 'desktop' ? 'Native Desktop App / WebView2' : 'Fast Web Preview'}) \n> **Execution Duration:** ${(durationMs / 1000).toFixed(2)} s \n> **Total Snapshots Captured:** ${snapshots.length} \n> **Health Status:** ${healthStatus} \n> **Artifacts Folder:** \\`${outputDir}\\`\n\n---\n\n## šŸ–¼ļø Primary Snapshot Overview\n\n| # | Viewport | Step Description | File Reference |\n| :-: | :--- | :--- | :--- |\n${rows.join('\\n')}\n\n${burstSections}\n${consoleSections}\n${pluginSections}\n---\n\n## šŸ“‹ AI Agent Verification Checklist:\n- [ ] **Console Errors**: ${consoleErrors.length === 0 ? 'āœ… No errors found' : `āŒ ${consoleErrors.length} errors — MUST REVIEW`}\n- [ ] **Visual Layout Check**: Inspect snapshots (e.g. view_image on \\`./01_${regularSnapshots[0]?.fileName || 'quick_snap'}\\`) for layout shifts or clipped elements.\n- [ ] **Responsiveness at \\`1024x768\\`**: Elements do not overflow the screen, no unwanted horizontal scroll.\n \n- [ ] **Typography & Spacing**: Spacing matches the design system and layout grids.\n- [ ] **Color Palette & Theme**: Background tints and button accent colors match the concept.\n- [ ] **Component States**: Modals open centered, dropdowns do not overlap with other layers (z-index).\n- [ ] **Localization**: Verify that there are no raw i18n keys (text with dots like \\`sidebar.home\\` instead of \"Home\").\n\n`;\n\n fs.writeFileSync(reportPath, reportContent, 'utf-8');\n return reportPath;\n }\n\n private static getHealthStatus(errors: ConsoleEntry[], warnings: ConsoleEntry[]): string {\n if (errors.length === 0 && warnings.length === 0) {\n return 'āœ… Healthy — no errors or warnings';\n }\n if (errors.length === 0 && warnings.length > 0) {\n return `āš ļø Warnings (${warnings.length}) — no critical errors`;\n }\n return `āŒ ERRORS (${errors.length} errors, ${warnings.length} warnings) — requires attention`;\n }\n}\n","import type { Page, ConsoleMessage } from 'playwright';\r\nimport type { ConsoleEntry } from '../../shared/types/console';\r\n\r\nexport type { ConsoleEntry };\r\n\r\n\r\nexport class ConsoleTracker {\r\n private entries: ConsoleEntry[] = [];\r\n private attached = false;\r\n\r\n public attach(page: Page): void {\r\n if (this.attached) return;\r\n this.attached = true;\r\n\r\n page.on('console', (msg: ConsoleMessage) => {\r\n const type = msg.type(); // 'log' | 'error' | 'warning' | 'info' | 'debug' | 'trace' | ...\r\n const level = this.mapConsoleType(type);\r\n\r\n const entry: ConsoleEntry = {\r\n level,\r\n text: msg.text(),\r\n url: page.url(),\r\n timestamp: new Date().toISOString()\r\n };\r\n\r\n this.entries.push(entry);\r\n\r\n if (level === 'error') {\r\n console.log(`šŸ”“ [Console ERROR] ${msg.text()}`);\r\n } else if (level === 'warning') {\r\n if (!this.isIgnoredWarning(msg.text())) {\r\n console.log(`🟔 [Console WARN] ${msg.text()}`);\r\n }\r\n }\r\n });\r\n\r\n page.on('pageerror', (error: Error) => {\r\n const entry: ConsoleEntry = {\r\n level: 'error',\r\n text: error.message,\r\n url: page.url(),\r\n timestamp: new Date().toISOString(),\r\n stack: error.stack\r\n };\r\n\r\n this.entries.push(entry);\r\n console.log(`šŸ’„ [Page ERROR] ${error.message}`);\r\n });\r\n }\r\n\r\n public getErrors(): ConsoleEntry[] {\r\n return this.entries.filter(e => e.level === 'error');\r\n }\r\n\r\n public getWarnings(): ConsoleEntry[] {\r\n return this.entries\r\n .filter(e => e.level === 'warning')\r\n .filter(e => !this.isIgnoredWarning(e.text));\r\n }\r\n\r\n public getAll(): ConsoleEntry[] {\r\n return [...this.entries];\r\n }\r\n\r\n public get errorCount(): number {\r\n return this.getErrors().length;\r\n }\r\n\r\n public get warningCount(): number {\r\n return this.getWarnings().length;\r\n }\r\n\r\n public get hasErrors(): boolean {\r\n return this.errorCount > 0;\r\n }\r\n\r\n public clear(): void {\r\n this.entries = [];\r\n }\r\n\r\n\r\n private mapConsoleType(type: string): ConsoleEntry['level'] {\r\n switch (type) {\r\n case 'error': return 'error';\r\n case 'warning': return 'warning';\r\n case 'info': return 'info';\r\n case 'debug': return 'debug';\r\n default: return 'log';\r\n }\r\n }\r\n\r\n\r\n private isIgnoredWarning(text: string): boolean {\r\n const ignoredPatterns = [\r\n 'findDOMNode is deprecated',\r\n // Chromium DevTools\r\n 'DevTools',\r\n // Playwright injection\r\n '__playwright',\r\n '[vite]',\r\n // React 18 hydration warnings\r\n 'Extra attributes from the server',\r\n 'Download the React DevTools',\r\n ];\r\n return ignoredPatterns.some(pattern => text.includes(pattern));\r\n }\r\n}\r\n","import { chromium as baseChromium, type ChromiumBrowser, type BrowserType } from 'playwright';\r\n\r\n/**\r\n * Safe Playwright Chromium loader that wraps browser initialization with helpful diagnostic messages.\r\n */\r\nexport const chromium: BrowserType<ChromiumBrowser> = new Proxy(baseChromium, {\r\n get(target, prop, receiver) {\r\n if (prop === 'launch') {\r\n return async (...args: Parameters<typeof baseChromium.launch>) => {\r\n try {\r\n return await target.launch(...args);\r\n } catch (err: any) {\r\n if (\r\n err.message?.includes(\"Executable doesn't exist\") ||\r\n err.message?.includes('playwright install') ||\r\n err.message?.includes('browser has not been downloaded')\r\n ) {\r\n console.error(\"\\nāŒ [AgentLens] Playwright Chromium browser binary is missing!\");\r\n console.error(\"šŸ‘‰ Please install it by running: npx playwright install chromium\\n\");\r\n }\r\n throw err;\r\n }\r\n };\r\n }\r\n const val = Reflect.get(target, prop, receiver);\r\n return typeof val === 'function' ? val.bind(target) : val;\r\n }\r\n});","import http from 'http';\nimport fs from 'fs';\nimport path from 'path';\nimport type { Browser, BrowserContext, Page } from 'playwright';\nimport { chromium } from '../lib/playwrightLoader';\nimport type { MockRouteEntry } from '../api/dsl';\nimport { resolveWwwrootDir } from '../lib/config';\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf'\n};\n\nexport interface PreviewDriverOptions {\n wwwrootDir?: string;\n headed?: boolean;\n url?: string;\n}\n\nexport class PreviewDriver {\n private server: http.Server | null = null;\n private browser: Browser | null = null;\n private context: BrowserContext | null = null;\n private page: Page | null = null;\n private serverPort: number = 0;\n private options: PreviewDriverOptions;\n private _baseUrl: string = '';\n private initialRouteMocks: MockRouteEntry[] = [];\n\n constructor(options?: PreviewDriverOptions) {\n this.options = options || {};\n if (!this.options.url) {\n this.options.wwwrootDir = resolveWwwrootDir(this.options.wwwrootDir);\n }\n }\n\n public get baseUrl(): string {\n return this._baseUrl;\n }\n\n public async start(initialViewport = { width: 1200, height: 800 }): Promise<{ page: Page; context: BrowserContext; browser: Browser }> {\n let targetUrl = this.options.url;\n\n if (!targetUrl) {\n if (!fs.existsSync(this.options.wwwrootDir!)) {\n throw new Error(`Directory not found at: ${this.options.wwwrootDir}. Please build your frontend project first or pass --url=<url>.`);\n }\n\n await new Promise<void>((resolve, reject) => {\n this.server = http.createServer((req, res) => {\n let reqUrl = req.url?.split('?')[0] || '/';\n if (reqUrl === '/') reqUrl = '/index.html';\n\n let safePath = path.normalize(path.join(this.options.wwwrootDir!, reqUrl));\n if (!safePath.startsWith(this.options.wwwrootDir!)) {\n res.writeHead(403);\n return res.end('Forbidden');\n }\n\n if (!fs.existsSync(safePath) || fs.statSync(safePath).isDirectory()) {\n // SPA fallback to index.html\n safePath = path.join(this.options.wwwrootDir!, 'index.html');\n }\n\n const ext = path.extname(safePath).toLowerCase();\n const contentType = MIME_TYPES[ext] || 'application/octet-stream';\n\n try {\n const content = fs.readFileSync(safePath);\n res.writeHead(200, { 'Content-Type': contentType });\n res.end(content);\n } catch (e: any) {\n res.writeHead(500);\n res.end(`Server error: ${e.message}`);\n }\n });\n\n this.server.listen(0, '127.0.0.1', () => {\n const addr = this.server?.address();\n if (typeof addr === 'object' && addr?.port) {\n this.serverPort = addr.port;\n this._baseUrl = `http://127.0.0.1:${this.serverPort}`;\n resolve();\n } else {\n reject(new Error('Failed to acquire port for static preview server'));\n }\n });\n });\n\n targetUrl = `${this._baseUrl}/index.html`;\n } else {\n this._baseUrl = targetUrl;\n console.log(`🌐 [PreviewDriver] Connecting directly to live URL: ${targetUrl}`);\n }\n\n this.browser = await chromium.launch({\n headless: !this.options.headed,\n args: ['--no-sandbox', '--disable-setuid-sandbox']\n });\n\n this.context = await this.browser.newContext({\n viewport: initialViewport,\n deviceScaleFactor: 1\n });\n\n this.page = await this.context.newPage();\n\n if (this.initialRouteMocks.length > 0) {\n for (const entry of this.initialRouteMocks) {\n await this.addRouteMock(entry);\n }\n }\n\n await this.page.goto(targetUrl, { waitUntil: 'domcontentloaded' });\n\n return { page: this.page, context: this.context, browser: this.browser };\n }\n\n public async addRouteMock(entry: MockRouteEntry): Promise<void> {\n if (!this.page) {\n this.initialRouteMocks.push(entry);\n return;\n }\n\n await this.page.route(entry.url, async (route) => {\n const req = route.request();\n if (entry.method && req.method().toUpperCase() !== entry.method.toUpperCase()) {\n return route.continue();\n }\n\n if (entry.delayMs) {\n await new Promise((r) => setTimeout(r, entry.delayMs));\n }\n\n const isJson = typeof entry.body === 'object' && entry.body !== null;\n await route.fulfill({\n status: entry.status ?? 200,\n contentType: isJson ? 'application/json' : 'text/plain; charset=utf-8',\n body: isJson ? JSON.stringify(entry.body) : String(entry.body ?? ''),\n headers: entry.headers\n });\n });\n }\n\n public async setupRouteMocks(routes: MockRouteEntry[]): Promise<void> {\n for (const r of routes) {\n await this.addRouteMock(r);\n }\n }\n\n public async stop(): Promise<void> {\n if (this.context) {\n await this.context.close().catch(() => {});\n this.context = null;\n }\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n if (this.server) {\n await new Promise<void>((resolve) => {\n this.server?.close(() => resolve());\n });\n this.server = null;\n }\n }\n}\n","import { spawn, type ChildProcess } from 'child_process';\nimport treeKill from 'tree-kill';\n\nexport interface ProcessStartOptions {\n \n cwd?: string;\n env?: NodeJS.ProcessEnv;\n}\n\nexport class ProcessManager {\n private childProcess: ChildProcess | null = null;\n private isStopped = false;\n\n public async start(command: string, options?: ProcessStartOptions): Promise<void> {\n const cwd = options?.cwd || process.cwd();\n console.log(`šŸš€ [ProcessManager] Starting command: \"${command}\" in ${cwd}`);\n\n this.childProcess = spawn(command, {\n cwd,\n env: { ...process.env, ...options?.env },\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n this.childProcess.stdout?.on('data', (chunk) => {\n const line = chunk.toString().trim();\n if (line) {\n // Subprocess stdout output handled silently unless needed\n }\n });\n\n this.childProcess.stderr?.on('data', (chunk) => {\n const line = chunk.toString().trim();\n if (line && !line.includes('ExperimentalWarning')) {\n // Forward warning if necessary\n }\n });\n\n this.childProcess.on('exit', (code, signal) => {\n if (!this.isStopped && code !== 0 && code !== null) {\n console.warn(`āš ļø [ProcessManager] Subprocess exited prematurely with code ${code}, signal ${signal}`);\n }\n });\n }\n\n public async waitForUrl(url: string, timeoutMs = 30000): Promise<boolean> {\n console.log(`ā³ [ProcessManager] Waiting for ${url} to respond...`);\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n if (this.childProcess && this.childProcess.exitCode !== null) {\n throw new Error(\n `[ProcessManager] Server process exited with code ${this.childProcess.exitCode} while waiting for ${url}`\n );\n }\n\n try {\n const response = await fetch(url, { signal: AbortSignal.timeout(1000) });\n if (response.status) {\n console.log(`āœ… [ProcessManager] Target ${url} is ready (status: ${response.status})!`);\n return true;\n }\n } catch {\n // Retry on connection refused or timeout\n }\n\n await new Promise((r) => setTimeout(r, 500));\n }\n\n throw new Error(`[ProcessManager] Timeout after ${timeoutMs}ms waiting for ${url} to respond.`);\n }\n\n public async stop(): Promise<void> {\n if (this.isStopped || !this.childProcess || !this.childProcess.pid) {\n return;\n }\n\n this.isStopped = true;\n const pid = this.childProcess.pid;\n console.log(`šŸ›‘ [ProcessManager] Terminating process tree for PID ${pid}...`);\n\n await new Promise<void>((resolve) => {\n treeKill(pid, 'SIGTERM', (err) => {\n if (err) {\n try {\n treeKill(pid, 'SIGKILL');\n } catch {\n // ignore\n }\n }\n resolve();\n });\n });\n\n this.childProcess = null;\n }\n}","import path from 'path';\nimport fs from 'fs';\nimport { createJiti } from 'jiti';\nimport type { AgentLensPlugin, PluginHookContext, DriverLaunchResult } from '../api/plugin';\nimport type { TestContext } from '../api/dsl';\nimport type { ReportData } from '../types/report';\nimport type { Page, BrowserContext } from 'playwright';\n\nfunction findPackageRoot(): string {\n let cur = __dirname;\n while (cur !== path.dirname(cur)) {\n const pkgPath = path.join(cur, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n if (pkg.name === '@_deep4wee/agent-lens' || pkg.name === 'agent-lens') {\n return cur;\n }\n } catch {\n // ignore\n }\n }\n cur = path.dirname(cur);\n }\n return path.resolve(__dirname, '..');\n}\n\nexport class PluginManager {\n private plugins: AgentLensPlugin[] = [];\n private jiti = createJiti(process.cwd());\n\n public register(plugin: AgentLensPlugin): void {\n if (this.plugins.some((p) => p.name === plugin.name)) {\n return;\n }\n this.plugins.push(plugin);\n console.log(`šŸ”Œ [Plugin] Registered: ${plugin.name}${plugin.version ? ` (v${plugin.version})` : ''}`);\n }\n\n public async load(pluginSpec: string | AgentLensPlugin): Promise<void> {\n if (typeof pluginSpec === 'object' && pluginSpec !== null) {\n this.register(pluginSpec);\n return;\n }\n\n const pluginNameOrPath = pluginSpec.trim();\n if (!pluginNameOrPath) return;\n\n // 1. Direct path (relative or absolute)\n if (\n pluginNameOrPath.startsWith('.') ||\n pluginNameOrPath.startsWith('/') ||\n pluginNameOrPath.includes('/') ||\n pluginNameOrPath.includes('\\\\')\n ) {\n const resolvedPath = path.resolve(process.cwd(), pluginNameOrPath);\n await this.loadFromFile(resolvedPath);\n return;\n }\n\n // 2. Local convention directories: .agent-lens/plugins/ or plugins/\n const localCandidates = [\n path.resolve(process.cwd(), '.agent-lens', 'plugins', `${pluginNameOrPath}.ts`),\n path.resolve(process.cwd(), '.agent-lens', 'plugins', `${pluginNameOrPath}.js`),\n path.resolve(process.cwd(), 'plugins', `${pluginNameOrPath}.ts`),\n path.resolve(process.cwd(), 'plugins', `${pluginNameOrPath}.js`),\n path.resolve(process.cwd(), '.agent-lens', 'plugins', pluginNameOrPath, 'index.ts'),\n path.resolve(process.cwd(), '.agent-lens', 'plugins', pluginNameOrPath, 'index.js'),\n path.resolve(process.cwd(), 'plugins', pluginNameOrPath, 'index.ts'),\n path.resolve(process.cwd(), 'plugins', pluginNameOrPath, 'index.js')\n ];\n\n for (const candidate of localCandidates) {\n if (fs.existsSync(candidate)) {\n await this.loadFromFile(candidate);\n return;\n }\n }\n\n // 3. Built-in plugins in agent-lens\n const pkgRoot = findPackageRoot();\n const builtInCandidates = [\n path.join(pkgRoot, 'src', 'plugins', pluginNameOrPath, 'index.ts'),\n path.join(pkgRoot, 'src', 'plugins', pluginNameOrPath, 'index.js'),\n path.join(pkgRoot, 'dist', 'plugins', pluginNameOrPath, 'index.js'),\n path.join(pkgRoot, 'plugins', pluginNameOrPath, 'index.ts'),\n path.join(pkgRoot, 'plugins', pluginNameOrPath, 'index.js'),\n path.resolve(__dirname, '../../plugins', pluginNameOrPath, 'index.ts'),\n path.resolve(__dirname, '../../plugins', pluginNameOrPath, 'index.js'),\n path.resolve(__dirname, '../plugins', pluginNameOrPath, 'index.ts'),\n path.resolve(__dirname, '../plugins', pluginNameOrPath, 'index.js')\n ];\n\n for (const builtIn of builtInCandidates) {\n if (fs.existsSync(builtIn)) {\n await this.loadFromFile(builtIn);\n return;\n }\n }\n\n // 4. Fallback to npm package resolution (e.g. @agent-lens/plugin-xxx)\n try {\n const mod = await this.jiti.import(pluginNameOrPath) as any;\n const plugin: AgentLensPlugin = mod.default || mod.plugin || mod;\n if (plugin && plugin.name) {\n this.register(plugin);\n } else {\n console.warn(`āš ļø [Plugin] Package \"${pluginNameOrPath}\" did not export a valid AgentLensPlugin.`);\n }\n } catch (err: any) {\n console.warn(`āš ļø [Plugin] Could not load plugin '${pluginNameOrPath}': ${err.message}`);\n }\n }\n\n private async loadFromFile(filePath: string): Promise<void> {\n if (!fs.existsSync(filePath)) {\n console.warn(`āš ļø [Plugin] Plugin file not found: ${filePath}`);\n return;\n }\n\n try {\n const mod = await this.jiti.import(filePath) as any;\n const plugin: AgentLensPlugin = mod.default || mod.plugin || mod;\n if (plugin && plugin.name) {\n this.register(plugin);\n } else {\n console.warn(`āš ļø [Plugin] File \"${filePath}\" does not export a valid AgentLensPlugin by default.`);\n }\n } catch (err: any) {\n console.error(`āŒ [Plugin] Failed to import plugin from ${filePath}:`, err.message);\n }\n }\n\n public async loadAll(specs: (string | AgentLensPlugin)[]): Promise<void> {\n for (const spec of specs) {\n await this.load(spec);\n }\n }\n\n public async runSetup(hookContext: PluginHookContext): Promise<void> {\n for (const p of this.plugins) {\n if (p.setup) await p.setup(hookContext);\n }\n }\n\n public async launchSession(\n options: { currentViewport: { width: number; height: number }; headed?: boolean },\n hookContext: PluginHookContext\n ): Promise<DriverLaunchResult | undefined> {\n for (const p of this.plugins) {\n if (p.launchSession) {\n const session = await p.launchSession(options, hookContext);\n if (session) {\n return session;\n }\n }\n }\n return undefined;\n }\n\n public async runOnContextCreated(context: BrowserContext, hookContext: PluginHookContext): Promise<void> {\n for (const p of this.plugins) {\n if (p.onContextCreated) await p.onContextCreated(context, hookContext);\n }\n }\n\n public async runOnPageCreated(page: Page, context: BrowserContext, hookContext: PluginHookContext): Promise<void> {\n for (const p of this.plugins) {\n if (p.onPageCreated) await p.onPageCreated(page, context, hookContext);\n }\n }\n\n public async extendContext(ctx: TestContext, page: Page, hookContext: PluginHookContext): Promise<void> {\n for (const p of this.plugins) {\n if (p.extendContext) {\n const extensions = await p.extendContext(ctx, page, hookContext);\n if (extensions && typeof extensions === 'object') {\n Object.assign(ctx, extensions);\n }\n }\n }\n }\n\n public async runOnAfterRun(reportData: ReportData, hookContext: PluginHookContext): Promise<void> {\n for (const p of this.plugins) {\n if (p.onAfterRun) await p.onAfterRun(reportData, hookContext);\n }\n }\n\n public async runTeardown(hookContext: PluginHookContext): Promise<void> {\n for (const p of this.plugins) {\n if (p.teardown) {\n try {\n await p.teardown(hookContext);\n } catch (e: any) {\n console.error(`āš ļø [Plugin] Error in ${p.name}.teardown:`, e.message);\n }\n }\n }\n }\n\n public get loadedPlugins(): AgentLensPlugin[] {\n return [...this.plugins];\n }\n}","import type { Page } from 'playwright';\n\nexport type NavigateFunction = (route: string) => Promise<void>;\n\n/**\n * Creates an intelligent route navigator supporting full URLs, hash routes,\n * base-relative paths, and SPA hash fallbacks.\n */\nexport function createNavigator(page: Page, baseUrl?: string, targetUrl?: string): NavigateFunction {\n return async (route: string): Promise<void> => {\n // 1. Direct absolute URLs\n if (route.startsWith('http://') || route.startsWith('https://')) {\n await page.goto(route, { waitUntil: 'domcontentloaded' });\n await page.waitForTimeout(300);\n return;\n }\n\n // 2. Hash-based routing (e.g. #/settings)\n if (route.startsWith('#')) {\n await page.evaluate((r) => { window.location.hash = r; }, route);\n await page.waitForTimeout(300);\n return;\n }\n\n // 3. Base URL resolution\n if (baseUrl && targetUrl) {\n try {\n const fullUrl = new URL(route, baseUrl).toString();\n await page.goto(fullUrl, { waitUntil: 'domcontentloaded' });\n await page.waitForTimeout(300);\n return;\n } catch {\n // Fall back to hash navigation on invalid URL format\n }\n }\n\n // 4. Default client-side SPA fallback\n const routePath = route.startsWith('/') ? route : `/${route}`;\n await page.evaluate((r) => {\n if (window.location.hash !== undefined) {\n window.location.hash = r;\n }\n }, routePath);\n await page.waitForTimeout(300);\n };\n}\n","import fs from 'fs';\nimport path from 'path';\nimport type { SnapshotMetadata } from '../../../shared/api/dsl';\n\n/**\n * Synchronizes the generated test report and snapshots into artifacts/latest/\n * so agents always have immediate access to the freshest results without parsing timestamps.\n */\nexport function syncLatestArtifacts(\n artifactsRoot: string,\n scenarioArtifactsDir: string,\n reportPath: string,\n snapshots: SnapshotMetadata[]\n): string | undefined {\n try {\n const latestDir = path.join(artifactsRoot, 'latest');\n if (fs.existsSync(latestDir)) {\n fs.rmSync(latestDir, { recursive: true, force: true });\n }\n fs.mkdirSync(latestDir, { recursive: true });\n\n // 1. Copy markdown report\n if (fs.existsSync(reportPath)) {\n fs.copyFileSync(reportPath, path.join(latestDir, 'report.md'));\n }\n\n // 2. Copy manifest JSON if present\n const manifestSrc = path.join(scenarioArtifactsDir, 'manifest.json');\n if (fs.existsSync(manifestSrc)) {\n fs.copyFileSync(manifestSrc, path.join(latestDir, 'manifest.json'));\n }\n\n // 3. Copy individual image snapshots\n for (const snap of snapshots) {\n if (snap.filePath && fs.existsSync(snap.filePath)) {\n fs.copyFileSync(snap.filePath, path.join(latestDir, snap.fileName));\n }\n }\n\n return path.join(latestDir, 'report.md');\n } catch {\n return undefined;\n }\n}\n","import type { Page, BrowserContext } from 'playwright';\nimport type {\n TestContext,\n ViewportPreset,\n CaptureOptions,\n CaptureBurstOptions,\n MockRouteEntry\n} from '../../../shared/api/dsl';\nimport type { CaptureEngine } from '../../capture/capture';\nimport type { ConsoleTracker } from '../../console-tracker/consoleTracker';\nimport type { PreviewDriver } from '../../../shared/drivers/previewDriver';\nimport type { NavigateFunction } from './navigation';\n\nexport interface ContextBuilderOptions {\n page: Page;\n context: BrowserContext;\n targetMode: 'desktop' | 'preview' | string;\n initialViewport: { width: number; height: number };\n captureEngine: CaptureEngine;\n consoleTracker: ConsoleTracker;\n previewDriver: PreviewDriver | null;\n doNavigate: NavigateFunction;\n}\n\nexport function buildTestContext(options: ContextBuilderOptions): {\n ctx: TestContext;\n getCurrentViewport: () => { width: number; height: number };\n} {\n const {\n page,\n context,\n targetMode,\n initialViewport,\n captureEngine,\n consoleTracker,\n previewDriver,\n doNavigate\n } = options;\n\n let currentViewport = { ...initialViewport };\n\n const ctx: TestContext = {\n page,\n context,\n targetMode: targetMode as 'desktop' | 'preview',\n currentViewport,\n\n // --- Snapshots ---\n capture: async (name: string, opts?: CaptureOptions) => {\n console.log(`šŸ“ø [Snapshot] ${name} (${currentViewport.width}x${currentViewport.height})`);\n return await captureEngine.takeSnapshot(page, name, currentViewport, opts);\n },\n\n captureBurst: async (name: string, opts: CaptureBurstOptions) => {\n console.log(`šŸŽ¬ [Burst] ${name} (duration: ${opts.durationMs}ms, interval: ${opts.intervalMs ?? 80}ms)`);\n return await captureEngine.takeBurst(page, name, currentViewport, opts);\n },\n\n // --- Navigation ---\n navigate: async (route: string) => {\n console.log(`🧭 [Navigate] ${route}`);\n await doNavigate(route);\n },\n\n // --- Viewport Management ---\n resize: async (width: number, height: number) => {\n console.log(`šŸ“ [Resize] ${width}x${height}`);\n currentViewport = { width, height };\n ctx.currentViewport = currentViewport;\n await page.setViewportSize(currentViewport);\n await page.waitForTimeout(200);\n },\n\n setPreset: async (preset: ViewportPreset) => {\n console.log(`šŸ“ [Preset] ${preset.name} (${preset.width}x${preset.height})`);\n await ctx.resize(preset.width, preset.height);\n },\n\n resizeToFit: async (selector?: string, padding = 0) => {\n let boundingBox;\n if (selector) {\n const el = await page.$(selector);\n if (el) {\n boundingBox = await el.boundingBox();\n }\n } else {\n boundingBox = await page.evaluate(() => ({\n width: document.documentElement.scrollWidth,\n height: document.documentElement.scrollHeight\n }));\n }\n\n if (boundingBox) {\n const newWidth = Math.ceil(boundingBox.width) + padding * 2;\n const newHeight = Math.ceil(boundingBox.height) + padding * 2;\n console.log(`šŸ“ [ResizeToFit] ${selector || 'body'} -> ${newWidth}x${newHeight}`);\n await ctx.resize(newWidth, newHeight);\n } else {\n console.log(`āš ļø [ResizeToFit] Element ${selector} not found or has no bounding box.`);\n }\n },\n\n // --- Waiting & DOM Observation ---\n wait: async (ms: number) => {\n await page.waitForTimeout(ms);\n },\n\n waitForSelector: async (selector: string, timeoutMs = 5000) => {\n await page.waitForSelector(selector, { timeout: timeoutMs });\n },\n\n // --- Interaction ---\n click: async (selector: string) => {\n console.log(`šŸ–±ļø [Click] ${selector}`);\n await page.click(selector);\n },\n\n rightClick: async (selector: string) => {\n console.log(`šŸ–±ļø [RightClick] ${selector}`);\n await page.click(selector, { button: 'right' });\n },\n\n type: async (selector: string, text: string) => {\n console.log(`āŒØļø [Type] ${selector} -> \"${text}\"`);\n await page.fill(selector, text);\n },\n\n selectOption: async (selector: string, value: string) => {\n console.log(`āœ… [Select] ${selector} -> \"${value}\"`);\n await page.selectOption(selector, value);\n },\n\n hover: async (selector: string) => {\n console.log(`šŸ‘† [Hover] ${selector}`);\n await page.hover(selector);\n },\n\n scroll: async (selector: string, deltaY: number) => {\n console.log(`šŸ“œ [Scroll] ${selector} by ${deltaY}px`);\n await page.evaluate(\n ({ sel, dY }) => {\n const el = document.querySelector(sel);\n if (el) {\n el.scrollTop += dY;\n } else {\n window.scrollBy(0, dY);\n }\n },\n { sel: selector, dY: deltaY }\n );\n await page.waitForTimeout(100);\n },\n\n // --- Logging ---\n log: (msg: string) => {\n console.log(`ā„¹ļø [Scenario] ${msg}`);\n },\n\n // --- Mock IPC (delegated or stubbed if plugin not loaded) ---\n setMockIpc: async (action: string, data: any, mockOptions?: any) => {\n console.log(`āš ļø [Mock IPC] setMockIpc called for \"${action}\". Ensure --plugin=mock-ipc is enabled.`);\n },\n\n // --- HTTP Route Mocking ---\n setMockRoute: async (\n url: string,\n body: any,\n routeOptions?: { method?: string; status?: number; delayMs?: number; headers?: Record<string, string> }\n ) => {\n if (!previewDriver) {\n console.log(`āš ļø [Mock Route] setMockRoute ignored (no preview driver running)`);\n return;\n }\n console.log(`🌐 [Mock Route] Intercepting ${routeOptions?.method || 'ALL'} ${url} -> ${routeOptions?.status ?? 200}`);\n await previewDriver.addRouteMock({\n url,\n body,\n method: routeOptions?.method,\n status: routeOptions?.status,\n delayMs: routeOptions?.delayMs,\n headers: routeOptions?.headers\n });\n },\n\n // --- Console Errors ---\n getConsoleErrors: () => consoleTracker.getErrors(),\n getConsoleWarnings: () => consoleTracker.getWarnings(),\n hasConsoleErrors: () => consoleTracker.hasErrors,\n\n // --- DOM Assertions ---\n readText: async (selector: string): Promise<string | null> => {\n const text = await page.textContent(selector);\n return text ? text.trim() : null;\n },\n\n getPageText: async (): Promise<string> => {\n return await page.evaluate(() => document.body.innerText || '');\n },\n\n isVisible: async (selector: string) => {\n try {\n const element = await page.$(selector);\n if (!element) return false;\n return await element.isVisible();\n } catch {\n return false;\n }\n },\n\n getElementCount: async (selector: string) => {\n const elements = await page.$$(selector);\n return elements.length;\n }\n };\n\n return {\n ctx,\n getCurrentViewport: () => currentViewport\n };\n}\n","import path from 'path';\nimport fs from 'fs';\nimport type { Page, BrowserContext } from 'playwright';\nimport {\n type VisualScenario,\n VIEWPORT_PRESETS,\n type AgentLensPlugin\n} from '../../shared/api/dsl';\nimport { CaptureEngine } from '../capture/capture';\nimport { VisualReporter } from '../reporter/reporter';\nimport { ConsoleTracker } from '../console-tracker/consoleTracker';\nimport { PreviewDriver } from '../../shared/drivers/previewDriver';\nimport { ProcessManager } from '../../shared/lib/processManager';\nimport { PluginManager } from '../../shared/lib/pluginLoader';\nimport { createNavigator } from './lib/navigation';\nimport { syncLatestArtifacts } from './lib/artifactsSync';\nimport { buildTestContext } from './lib/contextBuilder';\n\nexport interface RunOptions {\n scenario: VisualScenario;\n targetMode?: 'desktop' | 'preview' | string;\n artifactsRoot?: string;\n autoLaunchDesktop?: boolean;\n port?: number;\n wwwrootDir?: string;\n executablePath?: string;\n desktopArgs?: string[];\n desktopEnv?: Record<string, string>;\n cleanPaths?: string[];\n url?: string;\n startCommand?: string;\n startCwd?: string;\n cleanArtifacts?: boolean;\n headed?: boolean;\n detach?: boolean;\n globalMocks?: any[];\n plugins?: (string | AgentLensPlugin)[];\n}\n\nexport interface RunResult {\n scenarioId: string;\n targetMode: 'desktop' | 'preview' | string;\n success: boolean;\n totalSnapshots: number;\n consoleErrors: number;\n consoleWarnings: number;\n reportPath: string;\n artifactsDir: string;\n error?: string;\n}\n\nexport async function runVisualScenario(options: RunOptions): Promise<RunResult> {\n const { scenario } = options;\n const targetMode = options.targetMode || 'preview';\n const startTime = Date.now();\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\n const artifactsRoot = options.artifactsRoot || path.resolve(process.cwd(), 'artifacts');\n\n if (options.cleanArtifacts && fs.existsSync(artifactsRoot)) {\n console.log(`🧹 [Clean Artifacts] Purging previous artifact runs in ${artifactsRoot}...`);\n const entries = fs.readdirSync(artifactsRoot, { withFileTypes: true });\n for (const entry of entries) {\n fs.rmSync(path.join(artifactsRoot, entry.name), { recursive: true, force: true });\n }\n }\n\n const scenarioArtifactsDir = path.join(artifactsRoot, `${scenario.id}_${timestamp}`);\n if (!fs.existsSync(scenarioArtifactsDir)) {\n fs.mkdirSync(scenarioArtifactsDir, { recursive: true });\n }\n\n const captureEngine = new CaptureEngine(scenarioArtifactsDir);\n const consoleTracker = new ConsoleTracker();\n const defaultViewport = scenario.viewports?.[0] || VIEWPORT_PRESETS.DEFAULT;\n const currentViewport = { width: defaultViewport.width, height: defaultViewport.height };\n\n let previewDriver: PreviewDriver | null = null;\n let processManager: ProcessManager | null = null;\n let customDriverStop: (() => Promise<void>) | null = null;\n\n // Initialize and load plugins\n const pluginManager = new PluginManager();\n const pluginSpecs = [...(options.plugins || []), ...(scenario.plugins || [])];\n if (pluginSpecs.length > 0) {\n await pluginManager.loadAll(pluginSpecs);\n }\n\n const hookContext = {\n scenario,\n targetMode,\n artifactsDir: scenarioArtifactsDir,\n cliOptions: options as unknown as Record<string, unknown>,\n state: new Map<string, unknown>()\n };\n\n try {\n let page: Page;\n let context: BrowserContext;\n\n console.log(`\\n========================================`);\n console.log(`šŸš€ Starting Visual Test: ${scenario.title}`);\n console.log(`šŸŽÆ Mode: ${targetMode.toUpperCase()}`);\n console.log(`šŸ“ Artifacts: ${scenarioArtifactsDir}`);\n console.log(`========================================\\n`);\n\n // 1. Optional dev-server/process management\n if (options.startCommand) {\n processManager = new ProcessManager();\n await processManager.start(options.startCommand, { cwd: options.startCwd });\n const waitTarget = options.url || 'http://localhost:5173';\n await processManager.waitForUrl(waitTarget);\n }\n\n // 2. Run plugin setup hooks\n await pluginManager.runSetup(hookContext);\n\n if (typeof scenario.setup === 'function') {\n console.log(`šŸ”§ [Scenario Setup] Executing setup hook...`);\n await scenario.setup();\n }\n\n // 3. Driver Session Launch (Microkernel Pattern)\n const customSession = await pluginManager.launchSession(\n { currentViewport, headed: options.headed },\n hookContext\n );\n\n if (customSession) {\n page = customSession.page;\n context = customSession.context;\n if (customSession.stop) {\n customDriverStop = customSession.stop;\n }\n } else if (targetMode === 'desktop') {\n throw new Error(\n `[AgentLens] Target mode is 'desktop', but no desktop plugin is registered. ` +\n `Please add --plugin=desktop-webview2 to your command or configuration.`\n );\n } else {\n // Standard Core Preview Driver (Chromium)\n previewDriver = new PreviewDriver({\n wwwrootDir: options.wwwrootDir,\n url: options.url,\n headed: options.headed\n });\n\n if (scenario.mockRoutes && scenario.mockRoutes.length > 0) {\n console.log(`🌐 [Mock Network] Queuing ${scenario.mockRoutes.length} route mock(s)`);\n await previewDriver.setupRouteMocks(scenario.mockRoutes);\n }\n\n const res = await previewDriver.start(currentViewport);\n page = res.page;\n context = res.context;\n\n if (scenario.mockRoutes && scenario.mockRoutes.length > 0) {\n await previewDriver.setupRouteMocks(scenario.mockRoutes);\n }\n }\n\n // 4. Run plugin browser/context lifecycle hooks\n await pluginManager.runOnContextCreated(context, hookContext);\n await pluginManager.runOnPageCreated(page, context, hookContext);\n\n // 5. Attach console error interception\n consoleTracker.attach(page);\n console.log(`šŸ” [Console Tracker] Attached — errors and warnings will be captured\\n`);\n\n // 6. Navigation and Context Setup\n const doNavigate = createNavigator(page, previewDriver?.baseUrl, options.url);\n\n if (scenario.route) {\n console.log(`🧭 [Runner] Navigating to initial route: ${scenario.route}`);\n await doNavigate(scenario.route);\n }\n\n const { ctx } = buildTestContext({\n page,\n context,\n targetMode,\n initialViewport: currentViewport,\n captureEngine,\n consoleTracker,\n previewDriver,\n doNavigate\n });\n\n // 7. Allow plugins to extend TestContext (e.g. mock-ipc, live-controller)\n await pluginManager.extendContext(ctx, page, hookContext);\n\n // 8. Execute the scenario body\n await scenario.run(ctx);\n\n const durationMs = Date.now() - startTime;\n const snapshots = captureEngine.getSnapshots();\n const consoleErrors = consoleTracker.getErrors();\n const consoleWarnings = consoleTracker.getWarnings();\n\n if (consoleErrors.length > 0) {\n console.log(`\\nšŸ”“ Console Errors: ${consoleErrors.length}`);\n consoleErrors.forEach((err, i) => console.log(` ${i + 1}. ${err.text.slice(0, 120)}`));\n }\n if (consoleWarnings.length > 0) {\n console.log(`\\n🟔 Console Warnings: ${consoleWarnings.length}`);\n }\n\n // 9. Generate Report & Run AfterRun Hooks\n const reportData = {\n scenario,\n snapshots,\n consoleErrors,\n consoleWarnings,\n outputDir: scenarioArtifactsDir,\n targetMode,\n durationMs,\n customSections: []\n };\n\n await pluginManager.runOnAfterRun(reportData, hookContext);\n const reportPath = VisualReporter.generateReport(reportData);\n const latestReport = syncLatestArtifacts(artifactsRoot, scenarioArtifactsDir, reportPath, snapshots);\n\n console.log(`\\nāœ… Visual Test Completed Successfully!`);\n console.log(`šŸ“Š Captured Snapshots: ${snapshots.length}`);\n console.log(`šŸ”“ Console Errors: ${consoleErrors.length}`);\n console.log(`🟔 Console Warnings: ${consoleWarnings.length}`);\n console.log(`šŸ“„ Markdown Report: ${reportPath}`);\n if (latestReport) {\n console.log(`šŸ“Œ Latest Report: ${latestReport}`);\n }\n\n return {\n scenarioId: scenario.id,\n targetMode,\n success: true,\n totalSnapshots: snapshots.length,\n consoleErrors: consoleErrors.length,\n consoleWarnings: consoleWarnings.length,\n reportPath,\n artifactsDir: scenarioArtifactsDir\n };\n } catch (err: any) {\n console.error(`\\nāŒ Visual Test Failed: ${err.message}`);\n const durationMs = Date.now() - startTime;\n const snapshots = captureEngine.getSnapshots();\n const consoleErrors = consoleTracker.getErrors();\n const consoleWarnings = consoleTracker.getWarnings();\n\n const reportData = {\n scenario,\n snapshots,\n consoleErrors,\n consoleWarnings,\n outputDir: scenarioArtifactsDir,\n targetMode,\n durationMs\n };\n\n const reportPath = VisualReporter.generateReport(reportData);\n syncLatestArtifacts(artifactsRoot, scenarioArtifactsDir, reportPath, snapshots);\n\n return {\n scenarioId: scenario.id,\n targetMode,\n success: false,\n totalSnapshots: snapshots.length,\n consoleErrors: consoleErrors.length,\n consoleWarnings: consoleWarnings.length,\n reportPath,\n artifactsDir: scenarioArtifactsDir,\n error: err.message\n };\n } finally {\n // 10. Guaranteed teardown sequence\n await pluginManager.runTeardown(hookContext);\n\n if (typeof scenario.teardown === 'function') {\n try {\n console.log(`🧹 [Scenario Teardown] Executing teardown hook...`);\n await scenario.teardown();\n } catch (teardownErr: any) {\n console.error(`āš ļø [Scenario Teardown] Error during teardown:`, teardownErr.message);\n }\n }\n\n if (options.cleanPaths && options.cleanPaths.length > 0) {\n for (const cleanTarget of options.cleanPaths) {\n try {\n const resolvedCleanPath = path.resolve(process.cwd(), cleanTarget);\n if (fs.existsSync(resolvedCleanPath)) {\n console.log(`🧹 [Auto-Cleanup] Removing: ${resolvedCleanPath}`);\n fs.rmSync(resolvedCleanPath, { recursive: true, force: true });\n }\n } catch (cleanErr: any) {\n console.error(`āš ļø [Auto-Cleanup] Failed to remove ${cleanTarget}:`, cleanErr.message);\n }\n }\n }\n\n if (!options.detach) {\n if (customDriverStop) await customDriverStop();\n if (previewDriver) await previewDriver.stop();\n if (processManager) await processManager.stop();\n } else {\n console.log('šŸ”— [Runner] Detach mode active, leaving browser/app open.');\n }\n }\n}","export { runVisualScenario, type RunOptions, type RunResult } from './runner';\nexport { createNavigator, type NavigateFunction } from './lib/navigation';\nexport { syncLatestArtifacts } from './lib/artifactsSync';\nexport { buildTestContext, type ContextBuilderOptions } from './lib/contextBuilder';\n","import path from 'path';\nimport fs from 'fs';\nimport { runVisualScenario } from '../runner/runner';\nimport { defineVisualTest, VIEWPORT_PRESETS, type ViewportPreset } from '../../shared/api/dsl';\nimport { resolveWwwrootDir } from '../../shared/lib/config';\n\nexport interface SnapCliOptions {\n url?: string;\n start?: string;\n startCwd?: string;\n selector?: string;\n viewports?: string[];\n waitMs?: number;\n name?: string;\n clean?: string[];\n cleanArtifacts?: boolean;\n headed?: boolean;\n detach?: boolean;\n outDir?: string;\n mode?: 'desktop' | 'preview';\n exe?: string;\n port?: number;\n plugins?: (string | any)[];\n fullPage?: boolean;\n}\n\nconst PRESET_MAP: Record<string, ViewportPreset> = {\n \n default: VIEWPORT_PRESETS.DEFAULT,\n desktop: VIEWPORT_PRESETS.DEFAULT,\n min: VIEWPORT_PRESETS.MIN_SUPPORTED,\n 'min-supported': VIEWPORT_PRESETS.MIN_SUPPORTED,\n wide: VIEWPORT_PRESETS.WIDE,\n mobile: { name: 'mobile', width: 375, height: 667 },\n tablet: { name: 'tablet', width: 768, height: 1024 },\n 'full-hd': VIEWPORT_PRESETS.FULL_HD\n};\n\nfunction parseViewportPresets(raw?: string[]): ViewportPreset[] {\n if (!raw || raw.length === 0) {\n return [VIEWPORT_PRESETS.DEFAULT, PRESET_MAP.mobile];\n }\n\n const presets: ViewportPreset[] = [];\n for (const item of raw) {\n const lower = item.toLowerCase().trim();\n if (PRESET_MAP[lower]) {\n presets.push(PRESET_MAP[lower]);\n } else if (lower.includes('x')) {\n const [w, h] = lower.split('x').map((n) => parseInt(n, 10));\n if (!isNaN(w) && !isNaN(h)) {\n presets.push({ name: `${w}x${h}`, width: w, height: h });\n }\n }\n }\n\n return presets.length > 0 ? presets : [VIEWPORT_PRESETS.DEFAULT, PRESET_MAP.mobile];\n}\n\nconst CANDIDATE_PORTS = [5173, 3000, 4321, 4200, 8080, 8000, 3001];\n\nasync function isPortResponding(url: string): Promise<boolean> {\n try {\n const res = await fetch(url, { signal: AbortSignal.timeout(800) });\n return Boolean(res.status);\n } catch {\n return false;\n }\n}\n\nasync function detectActiveDevServer(): Promise<string | null> {\n for (const port of CANDIDATE_PORTS) {\n const url = `http://localhost:${port}`;\n if (await isPortResponding(url)) {\n return url;\n }\n }\n return null;\n}\n\nexport async function runQuickSnap(options: SnapCliOptions): Promise<boolean> {\n let targetUrl = options.url;\n let useStaticPreview = false;\n let wwwrootDir: string | undefined;\n\n // Smart URL/Server Resolution when neither --url nor --start is explicitly provided\n if (!targetUrl && !options.start) {\n const activeUrl = await detectActiveDevServer();\n if (activeUrl) {\n targetUrl = activeUrl;\n console.log(`🌐 [Quick Snap] Detected active dev server on ${targetUrl}`);\n } else {\n // Check for compiled static files (dist, build, wwwroot)\n const candidateDir = resolveWwwrootDir();\n if (fs.existsSync(candidateDir) && fs.existsSync(path.join(candidateDir, 'index.html'))) {\n useStaticPreview = true;\n wwwrootDir = candidateDir;\n console.log(`šŸ“¦ [Quick Snap] No active server found. Detected built static directory at \"${candidateDir}\". Launching static preview...`);\n } else {\n console.error(`\\nāŒ [Quick Snap] No active server found on common ports (${CANDIDATE_PORTS.join(', ')}), and no static build found.`);\n console.log(`šŸ’” Suggested actions:`);\n console.log(` 1. Pass a start command: npx agent-lens snap --start=\"npm run dev\"`);\n console.log(` 2. Specify your URL: npx agent-lens snap --url=http://localhost:8080`);\n console.log(` 3. Build your static app: npm run build\\n`);\n return false;\n }\n }\n } else if (!targetUrl && options.start) {\n targetUrl = 'http://localhost:5173';\n }\n \n\n const waitMs = options.waitMs ?? 1000;\n const snapshotPrefix = options.name || 'quick_snap';\n const targetViewports = parseViewportPresets(options.viewports);\n\n console.log(`\\nšŸ“ø [Quick Snap] Preparing instant verification for: ${targetUrl || wwwrootDir}`);\n console.log(`šŸ“ [Quick Snap] Testing ${targetViewports.length} viewports: ${targetViewports.map((v) => `${v.name} (${v.width}x${v.height})`).join(', ')}`);\n if (options.selector) {\n console.log(`šŸŽÆ [Quick Snap] Focused element selector: \"${options.selector}\"`);\n }\n\n const snapScenario = defineVisualTest({\n id: 'quick-snap',\n title: `Quick Verification: ${targetUrl || 'Static Preview'}`,\n description: `One-shot automated snapshot and console health check`,\n route: targetUrl || '/',\n viewports: targetViewports,\n run: async (ctx) => {\n ctx.log(`Waiting ${waitMs}ms for page stabilization...`);\n await ctx.wait(waitMs);\n\n for (let i = 0; i < targetViewports.length; i++) {\n const vp = targetViewports[i];\n const stepNum = String(i + 1).padStart(2, '0');\n ctx.log(`Switching viewport to: ${vp.name} (${vp.width}x${vp.height})`);\n await ctx.setPreset(vp);\n await ctx.wait(200);\n await ctx.capture(`${stepNum}_${snapshotPrefix}_${vp.name}`, { fullPage: options.fullPage });\n }\n\n if (options.selector) {\n ctx.log(`Focusing on selector: \"${options.selector}\"`);\n try {\n await ctx.setPreset(VIEWPORT_PRESETS.DEFAULT);\n await ctx.resizeToFit(options.selector, 15);\n await ctx.capture(`99_${snapshotPrefix}_element_focus`, { selector: options.selector });\n } catch (err: any) {\n ctx.log(`āš ļø Could not isolate selector \"${options.selector}\": ${err.message}`);\n }\n }\n\n const errors = ctx.getConsoleErrors();\n if (errors.length > 0) {\n ctx.log(`🚨 Caught ${errors.length} console errors during snap check!`);\n } else {\n ctx.log(`āœ… Clean run: No console errors detected.`);\n }\n }\n });\n\n const result = await runVisualScenario({\n scenario: snapScenario,\n targetMode: options.mode || 'preview',\n url: useStaticPreview ? undefined : targetUrl,\n wwwrootDir: useStaticPreview ? wwwrootDir : undefined,\n startCommand: options.start,\n startCwd: options.startCwd,\n executablePath: options.exe,\n cleanPaths: options.clean,\n cleanArtifacts: options.cleanArtifacts,\n port: options.port,\n headed: options.headed,\n detach: options.detach,\n artifactsRoot: options.outDir ? path.resolve(process.cwd(), options.outDir) : undefined,\n plugins: options.plugins\n });\n \n\n console.log(`\\n========================================`);\n console.log(`šŸ Quick Snap Finished!`);\n console.log(`šŸ“ø Snapshots: ${result.totalSnapshots}`);\n console.log(`šŸ”“ Console Errors: ${result.consoleErrors}`);\n console.log(`🟔 Console Warnings: ${result.consoleWarnings}`);\n console.log(`šŸ“„ Report: ${result.reportPath}`);\n console.log(`========================================\\n`);\n\n return result.success && result.consoleErrors === 0;\n}\n","import type { AgentLensConfigFile } from '../../shared/lib/config';\nimport { detectStartCwd } from '../../shared/lib/config';\n\nexport interface CliOptions {\n scenario?: string;\n mode: 'desktop' | 'preview' | string;\n all?: boolean;\n port: number;\n help?: boolean;\n headed?: boolean;\n detach?: boolean;\n build?: boolean | string;\n start?: string;\n startCwd?: string;\n cleanArtifacts?: boolean;\n url?: string;\n selector?: string;\n viewports?: string[];\n waitMs?: number;\n name?: string;\n exe?: string;\n clean?: string[];\n dir?: string;\n wwwroot?: string;\n outDir?: string;\n plugins?: string[];\n fullPage?: boolean;\n}\n\nexport interface ParsedCliResult {\n isSnapCommand: boolean;\n isInitCommand: boolean;\n options: CliOptions;\n}\n\nexport function parseCliArgs(argv: string[], fileConfig: AgentLensConfigFile): ParsedCliResult {\n const isInitCommand = argv[0] === 'init';\n const isSnapCommand = argv[0] === 'snap';\n const effectiveArgs = isSnapCommand ? argv.slice(1) : argv;\n\n const options: CliOptions = {\n mode: fileConfig.mode || 'preview',\n port: fileConfig.port || 9222,\n headed: fileConfig.headed ?? false,\n detach: fileConfig.detach ?? false,\n build: fileConfig.buildCommand || false,\n start: fileConfig.startCommand,\n startCwd: fileConfig.startCwd,\n cleanArtifacts: fileConfig.cleanArtifacts ?? false,\n url: fileConfig.url,\n exe: fileConfig.executablePath,\n clean: Array.isArray(fileConfig.clean) ? fileConfig.clean : (fileConfig.clean ? [fileConfig.clean] : undefined),\n dir: fileConfig.scenarios,\n wwwroot: fileConfig.wwwroot,\n outDir: fileConfig.outDir,\n plugins: fileConfig.plugins ? [...fileConfig.plugins] : []\n };\n\n for (const arg of effectiveArgs) {\n if (arg === '--help' || arg === '-h') {\n options.help = true;\n } else if (arg.startsWith('--scenario=')) {\n options.scenario = arg.split('=')[1];\n } else if (arg === '--all') {\n options.all = true;\n } else if (arg.startsWith('--mode=')) {\n options.mode = arg.split('=')[1].toLowerCase();\n } else if (arg.startsWith('--port=')) {\n options.port = parseInt(arg.split('=')[1], 10) || 9222;\n } else if (arg === '--headed') {\n options.headed = true;\n } else if (arg === '--detach') {\n options.detach = true;\n } else if (arg === '--build') {\n options.build = true;\n } else if (arg.startsWith('--build=')) {\n options.build = arg.slice('--build='.length);\n } else if (arg.startsWith('--start=')) {\n options.start = arg.slice('--start='.length);\n } else if (arg.startsWith('--start-cwd=') || arg.startsWith('--cwd=')) {\n options.startCwd = arg.split('=')[1];\n } else if (arg === '--clean-artifacts') {\n options.cleanArtifacts = true;\n } else if (arg.startsWith('--url=')) {\n options.url = arg.split('=')[1];\n } else if (arg.startsWith('--selector=')) {\n options.selector = arg.split('=')[1];\n } else if (arg.startsWith('--viewports=')) {\n const raw = arg.slice('--viewports='.length);\n options.viewports = raw.split(',').map((v: string) => v.trim()).filter(Boolean);\n } else if (arg.startsWith('--wait=')) {\n options.waitMs = parseInt(arg.slice('--wait='.length), 10);\n } else if (arg.startsWith('--name=')) {\n options.name = arg.slice('--name='.length);\n } else if (arg.startsWith('--exe=') || arg.startsWith('--executable=')) {\n const prefix = arg.startsWith('--exe=') ? '--exe=' : '--executable=';\n options.exe = arg.slice(prefix.length);\n } else if (arg.startsWith('--clean=') || arg.startsWith('--cleanup=')) {\n const prefix = arg.startsWith('--clean=') ? '--clean=' : '--cleanup=';\n const rawPaths = arg.slice(prefix.length);\n options.clean = rawPaths.split(',').map((p: string) => p.trim()).filter(Boolean);\n } else if (arg.startsWith('--dir=')) {\n options.dir = arg.split('=')[1];\n } else if (arg.startsWith('--wwwroot=')) {\n options.wwwroot = arg.split('=')[1];\n } else if (arg.startsWith('--outDir=') || arg.startsWith('--folder=')) {\n options.outDir = arg.split('=')[1];\n } else if (arg.startsWith('--plugin=') || arg.startsWith('--plugins=')) {\n const raw = arg.split('=')[1] || '';\n const items = raw.split(',').map((p: string) => p.trim()).filter(Boolean);\n options.plugins = [...(options.plugins || []), ...items];\n } else if (arg === '--full' || arg === '--full-page') {\n options.fullPage = true;\n }\n }\n\n // Auto-detect startCwd if a start command was provided in a monorepo setup\n if (options.start && !options.startCwd) {\n options.startCwd = detectStartCwd(options.startCwd);\n }\n\n // Auto-load desktop-webview2 plugin when running in desktop mode or with an .exe\n if ((options.mode === 'desktop' || options.exe) && !options.plugins?.includes('desktop-webview2')) {\n options.plugins = ['desktop-webview2', ...(options.plugins || [])];\n }\n\n return {\n isSnapCommand,\n isInitCommand,\n options\n };\n}\n","export function printHelp(): void {\n console.log(`\nšŸ‘ļø AgentLens - Visual UI Self-Verification for AI Agents\n\nUsage:\n npx agent-lens snap [options] Instant one-shot visual & console check (no test files needed)\n npx agent-lens live [action] Interactive live session (start, click, type, snap, stop)\n npx agent-lens [options] Run scripted scenario tests from scenarios/\n npx agent-lens init Generate starter scenario template & mocks\n\nCommands:\n snap Take immediate multi-viewport screenshots of a URL & check console errors\n live Interactive control: click coordinates/selectors, type text, snap --full\n init Generate starter template in scenarios/template.scenario.ts and mocks.ts\n\nOptions:\n --url=<url> Target URL to test (e.g. http://localhost:5173 or http://localhost:3000)\n --start=\"<cmd>\" Launch dev server or backend process before testing (e.g. --start=\"npm run dev\")\n --start-cwd=<path> Directory to execute --start command in (e.g. --start-cwd=./Frontend)\n --clean-artifacts Purge previous test artifacts to prevent folder bloat\n --full Capture full scrollable page instead of only the viewport\n --selector=<css> Target a specific element to focus on / resize-to-fit\n --viewports=<list> Comma-separated viewport presets (default: desktop,mobile; or 1200x800,375x667)\n --wait=<ms> Wait time in milliseconds after loading before snapshotting [default: 1000]\n --name=<prefix> Custom name prefix for captured snapshots [default: quick_snap]\n --scenario=<name> Run specific scenario by name (e.g. --scenario=smoke)\n --all Run all discovered scenarios\n --mode=<mode> Engine mode: 'preview' (Web/Vite/Live) or 'desktop' (WebView2/CDP) [default: preview]\n --exe=<path> Path to native executable for desktop mode (e.g. --exe=bin/MyApp.exe)\n --port=<port> CDP remote debugging port [default: 9222]\n --build[=<cmd>] Run build command before testing (e.g. --build=\"dotnet build\" or npm run build)\n --clean=<paths> Comma-separated paths to safely delete upon test exit (e.g. --clean=\"./temp,./cache\")\n --plugin=<names> Comma-separated plugins (e.g. --plugin=desktop-webview2,mock-ipc)\n --headed Show Chromium browser window\n --detach Keep browser/app open after finishing\n --dir=<path> Custom scenarios directory [default: scenarios]\n --wwwroot=<path> Custom directory for static fallback mode [default: dist]\n --folder=<path> Directory to save visual artifacts/reports (also --outDir)\n --help, -h Show this help message\n `);\n}\n","import path from 'path';\nimport fs from 'fs';\n\nexport function initScenarioTemplate(): void {\n const targetDir = path.resolve(process.cwd(), 'scenarios');\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n\n // 1. Generate template.scenario.ts\n const templatePath = path.join(targetDir, 'template.scenario.ts');\n if (!fs.existsSync(templatePath)) {\n const templateContent = `import { defineVisualTest, VIEWPORT_PRESETS } from 'agent-lens';\n\nexport default defineVisualTest({\n id: 'template-check',\n title: 'Basic UI Smoke & Responsiveness Check',\n route: '/',\n // Optional setup hook before test runs\n setup: async () => {\n // prepare test files or folders\n },\n run: async (ctx) => {\n ctx.log('Initial page render');\n await ctx.capture('01_initial_state');\n\n // Test adaptive layout\n await ctx.setPreset(VIEWPORT_PRESETS.MIN_SUPPORTED);\n await ctx.capture('02_compact_view');\n\n // Check for JavaScript / React runtime errors\n const errors = ctx.getConsoleErrors();\n if (errors.length > 0) {\n ctx.log(\\`āš ļø Warning: Caught \\${errors.length} console errors!\\`);\n }\n },\n // Optional teardown hook guaranteed to run on exit\n teardown: async () => {\n // clean up temporary test files or state\n }\n});\n`;\n fs.writeFileSync(templatePath, templateContent, 'utf8');\n console.log(`āœ… Starter scenario generated at: ${templatePath}`);\n } else {\n console.log(`ā„¹ļø Template already exists at: ${templatePath}`);\n }\n\n // 2. Generate starter mocks.ts to satisfy root app state on boot\n const mocksPath = path.join(targetDir, 'mocks.ts');\n if (!fs.existsSync(mocksPath)) {\n const mocksContent = `/**\n * Global IPC & API Mocks\n * \n * Export an array of base mocks to satisfy root application state on boot.\n */\nexport default [\n { action: 'GET_PREFS', data: { theme: 'dark', language: 'en' } },\n { action: 'GET_USER_PROFILE', data: { id: 1, name: 'Agent', role: 'admin' } }\n];\n`;\n fs.writeFileSync(mocksPath, mocksContent, 'utf8');\n console.log(`āœ… Base global mocks generated at: ${mocksPath}`);\n }\n\n console.log(`šŸ‘‰ Run tests with: npx agent-lens --scenario=template --mode=preview`);\n}\n","import path from 'path';\nimport fs from 'fs';\n\nexport async function findScenarios(dir: string, specificName?: string): Promise<string[]> {\n const results: string[] = [];\n if (!fs.existsSync(dir)) return results;\n\n const items = fs.readdirSync(dir, { withFileTypes: true });\n for (const item of items) {\n const fullPath = path.join(dir, item.name);\n if (item.isDirectory()) {\n results.push(...await findScenarios(fullPath, specificName));\n } else if (item.name.endsWith('.scenario.ts') || item.name.endsWith('.scenario.js')) {\n if (!specificName || item.name.startsWith(specificName)) {\n results.push(fullPath);\n }\n }\n }\n return results;\n}\n\nexport function resolveScenariosDirectory(customDir?: string): string {\n if (customDir) {\n return path.resolve(process.cwd(), customDir);\n }\n\n const candidates = [\n 'scenarios',\n 'tests/visual',\n 'tests/scenarios',\n 'test/scenarios',\n 'src/scenarios'\n ];\n\n for (const c of candidates) {\n const p = path.resolve(process.cwd(), c);\n if (fs.existsSync(p)) {\n return p;\n }\n }\n\n return path.resolve(process.cwd(), 'scenarios');\n}\n","import fs from 'fs';\nimport path from 'path';\nimport type { Page, Browser, BrowserContext } from 'playwright';\nimport { chromium } from '../../shared/lib/playwrightLoader';\nimport treeKill from 'tree-kill';\n\nexport interface LiveSessionInfo {\n port: number;\n url: string;\n pid?: number;\n startedAt: string;\n}\n\nconst SESSION_DIR = path.resolve(process.cwd(), '.agent-lens');\nconst SESSION_FILE = path.join(SESSION_DIR, 'live-session.json');\nconst LIVE_ARTIFACTS_DIR = path.resolve(process.cwd(), 'artifacts', 'live');\n\nexport function getSessionFile(): string {\n return SESSION_FILE;\n}\n\nexport function getLiveArtifactsDir(): string {\n if (!fs.existsSync(LIVE_ARTIFACTS_DIR)) {\n fs.mkdirSync(LIVE_ARTIFACTS_DIR, { recursive: true });\n }\n return LIVE_ARTIFACTS_DIR;\n}\n\nexport function readLiveSession(): LiveSessionInfo | null {\n if (!fs.existsSync(SESSION_FILE)) return null;\n try {\n return JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nexport function saveLiveSession(info: LiveSessionInfo): void {\n if (!fs.existsSync(SESSION_DIR)) {\n fs.mkdirSync(SESSION_DIR, { recursive: true });\n }\n fs.writeFileSync(SESSION_FILE, JSON.stringify(info, null, 2), 'utf-8');\n}\n\nexport function clearLiveSession(): void {\n if (fs.existsSync(SESSION_FILE)) {\n try {\n fs.unlinkSync(SESSION_FILE);\n } catch {\n // ignore\n }\n }\n}\n\n/**\n * Connect to an already running Live Browser session over CDP.\n */\nexport async function connectToLiveSession(): Promise<{ browser: Browser; context: BrowserContext; page: Page }> {\n const session = readLiveSession();\n if (!session) {\n throw new Error(\n `No active live session found. Start one with: npx agent-lens live start --url=http://localhost:5173`\n );\n }\n\n const browser = await chromium.connectOverCDP(`http://127.0.0.1:${session.port}`);\n const contexts = browser.contexts();\n const context = contexts[0] || (await browser.newContext());\n const pages = context.pages();\n const page = pages[0] || (await context.waitForEvent('page', { timeout: 5000 }));\n\n return { browser, context, page };\n}\n\n/**\n * Stop running live session and clean up process and session file.\n */\nexport async function stopLiveSession(): Promise<boolean> {\n const session = readLiveSession();\n if (!session) {\n console.log(`ā„¹ļø [Live] No active session to stop.`);\n return false;\n }\n\n try {\n const { browser } = await connectToLiveSession();\n await browser.close().catch(() => {});\n } catch {\n // browser might already be closed\n }\n\n if (session.pid) {\n await new Promise<void>((resolve) => {\n treeKill(session.pid!, 'SIGTERM', () => resolve());\n });\n }\n\n clearLiveSession();\n console.log(`šŸ›‘ [Live] Session stopped and cleaned up.`);\n return true;\n}\n","import path from 'path';\nimport type { Page } from 'playwright';\nimport {\n connectToLiveSession,\n saveLiveSession,\n stopLiveSession,\n getLiveArtifactsDir\n} from './session';\nimport { chromium } from '../../shared/lib/playwrightLoader';\n\nexport interface SnapLiveOptions {\n name?: string;\n fullPage?: boolean;\n selector?: string;\n}\n\n/**\n * Click at physical pixel coordinates on the page (for Vision AI models).\n */\nexport async function clickCoords(\n page: Page,\n x: number,\n y: number,\n options?: { button?: 'left' | 'right' | 'middle'; clickCount?: number }\n): Promise<void> {\n console.log(`šŸ–±ļø [LiveController] Clicking coordinates: (${x}, ${y})`);\n await page.mouse.click(x, y, options);\n await page.waitForTimeout(200);\n}\n\n/**\n * Drag and drop from (fromX, fromY) to (toX, toY).\n */\nexport async function dragAndDrop(\n page: Page,\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n steps = 10\n): Promise<void> {\n console.log(`šŸ–ļø [LiveController] Dragging from (${fromX}, ${fromY}) to (${toX}, ${toY}) in ${steps} steps`);\n await page.mouse.move(fromX, fromY);\n await page.mouse.down();\n await page.mouse.move(toX, toY, { steps });\n await page.mouse.up();\n await page.waitForTimeout(200);\n}\n\n/**\n * Scroll page by percentage (0 to 100).\n */\nexport async function scrollPercent(page: Page, percent: number): Promise<void> {\n const clamped = Math.max(0, Math.min(100, percent));\n console.log(`šŸ“œ [LiveController] Scrolling to ${clamped}% of page height`);\n await page.evaluate((pct) => {\n const totalHeight = document.documentElement.scrollHeight - window.innerHeight;\n const targetY = (totalHeight * pct) / 100;\n window.scrollTo({ top: targetY, behavior: 'smooth' });\n }, clamped);\n await page.waitForTimeout(300);\n}\n\n/**\n * Capture a live snapshot with optional fullPage (--full) support.\n */\nexport async function snapLive(page: Page, options?: SnapLiveOptions): Promise<string> {\n const artifactsDir = getLiveArtifactsDir();\n const fileName = options?.name ? `${options.name}.png` : 'current.png';\n const filePath = path.join(artifactsDir, fileName);\n\n if (options?.selector) {\n const el = await page.waitForSelector(options.selector, { timeout: 5000 });\n await el.screenshot({ path: filePath });\n } else {\n await page.screenshot({ path: filePath, fullPage: options?.fullPage ?? false });\n }\n\n console.log(`šŸ“ø [LiveController] Snapshot saved: ${filePath}${options?.fullPage ? ' (Full Page)' : ''}`);\n return filePath;\n}\n\n/**\n * Handle CLI commands: live start, click, type, snap, stop\n */\nexport async function handleLiveCli(argv: string[]): Promise<boolean> {\n const action = argv[0]?.toLowerCase();\n\n switch (action) {\n case 'start': {\n const urlArg = argv.find((a) => a.startsWith('--url='))?.split('=')[1] || 'http://localhost:5173';\n const portArg = parseInt(argv.find((a) => a.startsWith('--port='))?.split('=')[1] || '9223', 10);\n const isHeaded = argv.includes('--headed');\n\n console.log(`šŸš€ [Live] Starting background browser for ${urlArg} on CDP port ${portArg}...`);\n\n const browser = await chromium.launch({\n headless: !isHeaded,\n args: [`--remote-debugging-port=${portArg}`, '--no-sandbox']\n });\n\n const context = await browser.newContext({ viewport: { width: 1200, height: 800 } });\n const page = await context.newPage();\n await page.goto(urlArg, { waitUntil: 'domcontentloaded' });\n await page.waitForTimeout(500);\n\n saveLiveSession({\n port: portArg,\n url: urlArg,\n startedAt: new Date().toISOString()\n });\n\n await snapLive(page, { name: 'current' });\n console.log(`āœ… [Live] Session active! You can now send live commands:\\n`);\n console.log(` npx agent-lens live click 450 120`);\n console.log(` npx agent-lens live type \"input\" \"hello\"`);\n console.log(` npx agent-lens live snap --full`);\n console.log(` npx agent-lens live stop\\n`);\n return true;\n }\n\n case 'click': {\n const { page, browser } = await connectToLiveSession();\n const firstArg = argv[1];\n const secondArg = argv[2];\n\n const x = parseInt(firstArg, 10);\n const y = parseInt(secondArg, 10);\n\n if (!isNaN(x) && !isNaN(y)) {\n await clickCoords(page, x, y);\n } else if (firstArg) {\n console.log(`šŸ–±ļø [Live] Clicking selector: \"${firstArg}\"`);\n await page.click(firstArg);\n } else {\n console.error(`āŒ Usage: npx agent-lens live click <x> <y> OR npx agent-lens live click <selector>`);\n await browser.close();\n return false;\n }\n\n await snapLive(page, { name: 'current' });\n return true;\n }\n\n case 'type': {\n const { page, browser } = await connectToLiveSession();\n const selector = argv[1];\n const text = argv[2];\n\n if (!selector || text === undefined) {\n console.error(`āŒ Usage: npx agent-lens live type <selector> <text>`);\n await browser.close();\n return false;\n }\n\n console.log(`āŒØļø [Live] Typing into \"${selector}\": \"${text}\"`);\n await page.fill(selector, text);\n await snapLive(page, { name: 'current' });\n return true;\n }\n\n case 'snap': {\n const { page } = await connectToLiveSession();\n const isFull = argv.includes('--full');\n const nameArg = argv.find((a) => !a.startsWith('--') && a !== 'snap');\n\n await snapLive(page, { name: nameArg || 'current', fullPage: isFull });\n return true;\n }\n\n case 'stop': {\n return await stopLiveSession();\n }\n\n default: {\n console.log(`\nā„¹ļø AgentLens Live Controller:\n npx agent-lens live start --url=<url> Start background live session\n npx agent-lens live click <x> <y> Click at pixel coordinates\n npx agent-lens live click <selector> Click CSS selector\n npx agent-lens live type <sel> <text> Fill input field\n npx agent-lens live snap [name] [--full] Capture current or full-page screenshot\n npx agent-lens live stop Close live browser and finish\n `);\n return true;\n }\n }\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { execSync } from 'child_process';\nimport { createJiti } from 'jiti';\nimport { loadConfig, resolveWwwrootDir } from '../shared/lib/config';\nimport { runVisualScenario } from '../features/runner';\nimport { runQuickSnap } from '../features/snap/snap';\nimport type { VisualScenario } from '../shared/api/dsl';\nimport { parseCliArgs } from './lib/argsParser';\nimport { printHelp } from './lib/help';\nimport { initScenarioTemplate } from './lib/templateInit';\nimport { findScenarios, resolveScenariosDirectory } from './lib/scenarioFinder';\n\nimport { handleLiveCli } from '../plugins/live-controller/actions';\n\nconst rawArgs = process.argv.slice(2);\n\nif (rawArgs[0] === 'live') {\n handleLiveCli(rawArgs.slice(1))\n .then((success) => process.exit(success ? 0 : 1))\n .catch((err) => {\n console.error('āŒ Live command failed:', err instanceof Error ? err.message : err);\n process.exit(1);\n });\n} else {\n const fileConfig = loadConfig();\n const { isSnapCommand, isInitCommand, options } = parseCliArgs(rawArgs, fileConfig);\n\n if (isInitCommand) {\n initScenarioTemplate();\n process.exit(0);\n }\n\nif (options.help) {\n printHelp();\n process.exit(0);\n}\n\nasync function main() {\n // 1. One-shot \"snap\" command execution\n if (isSnapCommand || (options.url && !options.scenario && !options.all)) {\n const snapSuccess = await runQuickSnap({\n url: options.url,\n start: options.start,\n startCwd: options.startCwd,\n selector: options.selector,\n viewports: options.viewports,\n waitMs: options.waitMs,\n name: options.name,\n clean: options.clean,\n cleanArtifacts: options.cleanArtifacts,\n headed: options.headed,\n detach: options.detach,\n outDir: options.outDir,\n mode: options.mode as any,\n exe: options.exe,\n port: options.port,\n plugins: options.plugins,\n fullPage: options.fullPage\n });\n\n process.exit(snapSuccess ? 0 : 1);\n }\n\n // 2. Scenario-based test execution\n if (!options.scenario && !options.all) {\n console.error('āŒ Please specify a scenario (--scenario=name), run --all, or use: npx agent-lens snap --url=http://localhost:5173');\n printHelp();\n process.exit(1);\n }\n\n const scenariosDir = resolveScenariosDirectory(options.dir);\n const scenarioPaths = await findScenarios(scenariosDir, options.scenario);\n\n if (scenarioPaths.length === 0) {\n console.error(`āŒ No scenarios found in ${scenariosDir}`);\n console.log(`šŸ’” Generate a template with: npx agent-lens init`);\n process.exit(1);\n }\n\n const shouldBuild = options.build || fileConfig.autoBuild;\n if (shouldBuild) {\n const buildCmd = typeof options.build === 'string'\n ? options.build\n : (fileConfig.buildCommand || 'npm run build');\n\n console.log(`\\nšŸ”Ø [Build] Running build process: \"${buildCmd}\"...`);\n try {\n execSync(buildCmd, { stdio: 'inherit', cwd: options.startCwd || process.cwd() });\n } catch (e) {\n console.error(`āŒ Build failed: ${buildCmd}`);\n process.exit(1);\n }\n } else if (options.mode === 'preview' && !options.url && !options.start) {\n console.log(`āš ļø Warning: Running without --build or --url flag. Make sure your frontend is built!`);\n }\n\n console.log(`šŸ“‹ Found ${scenarioPaths.length} scenario(s) in: ${scenariosDir}`);\n\n // Initialize JITI for seamless TypeScript loading\n const jiti = createJiti(process.cwd());\n\n // Check for global mocks\n let globalMocks: any[] = [];\n const mockCandidates = [\n path.join(scenariosDir, 'mocks.ts'),\n path.join(scenariosDir, 'mocks.js'),\n path.join(process.cwd(), 'mocks.ts'),\n path.join(process.cwd(), 'mocks.js')\n ];\n\n for (const mocksPath of mockCandidates) {\n if (fs.existsSync(mocksPath)) {\n try {\n const m = await jiti.import(mocksPath) as any;\n globalMocks = m.default || m.mocks || [];\n console.log(`šŸŒ Loaded ${globalMocks.length} global mock(s) from ${path.basename(mocksPath)}`);\n break;\n } catch (err) {\n console.warn(`āš ļø Failed to load global mocks from ${mocksPath}:`, err);\n }\n }\n }\n\n // Auto-load mock-ipc plugin if global mocks or scenario mockIpc are present\n if (globalMocks.length > 0 && !options.plugins?.includes('mock-ipc')) {\n options.plugins = ['mock-ipc', ...(options.plugins || [])];\n }\n\n let allSuccess = true;\n for (const scenarioPath of scenarioPaths) {\n try {\n const scenarioModule = await jiti.import(scenarioPath) as any;\n const scenario: VisualScenario = scenarioModule.default || scenarioModule.scenario;\n\n if (!scenario || typeof scenario.run !== 'function') {\n console.error(`āš ļø Skipped: file ${path.basename(scenarioPath)} does not export a VisualScenario object by default.`);\n continue;\n }\n\n // If scenario requires mockIpc, ensure plugin is active\n const scenarioPlugins = [...(options.plugins || [])];\n if (scenario.mockIpc && scenario.mockIpc.length > 0 && !scenarioPlugins.includes('mock-ipc')) {\n scenarioPlugins.push('mock-ipc');\n }\n\n const result = await runVisualScenario({\n scenario,\n targetMode: options.mode as any,\n url: options.url,\n startCommand: options.start,\n startCwd: options.startCwd,\n cleanArtifacts: options.cleanArtifacts,\n port: options.port,\n headed: options.headed,\n detach: options.detach,\n executablePath: options.exe,\n cleanPaths: options.clean,\n desktopEnv: fileConfig.env,\n wwwrootDir: options.wwwroot ? resolveWwwrootDir(options.wwwroot) : undefined,\n artifactsRoot: options.outDir ? path.resolve(process.cwd(), options.outDir) : undefined,\n globalMocks,\n plugins: scenarioPlugins\n });\n\n if (!result.success) {\n allSuccess = false;\n }\n } catch (err: any) {\n console.error(`āŒ Failed to load scenario ${path.basename(scenarioPath)}:`, err);\n allSuccess = false;\n }\n }\n\n if (!allSuccess) {\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n});\n}\n"],"mappings":"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","names":["fs","path","fs","path","fs","path","path","fs","fs","path","path","fs","init_runner","path","fs","path","fs","path","fs","fs","path","treeKill","path","path","fs","createJiti","init_runner"]}