#!/usr/bin/env node import assert from 'assert'; import fs from 'fs'; import os from 'os'; import path from 'path'; import { createAutoTestPipelineTool, buildPreviewCacheKey, buildWorkspaceFingerprint, buildPromptCacheKey, buildParseCacheKey, buildGeneratedCasesCacheKey, buildPageVisibilityCacheKey } from './src/tools/autotest-pipeline.js'; import { WorkflowBuilder } from './src/tools/autotest/workflow-builder.js'; import { TestRunner } from './src/tools/autotest/test-runner.js'; import { WorkflowExecutor } from './src/vl/workflow-executor.js'; console.log('\n── AutoTest Generate Cache ──'); const workDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vlcode-autotest-cache-')); const vlDir = path.join(workDir, '.vl-code'); fs.mkdirSync(vlDir, { recursive: true }); const baseUrl = 'https://example.test/app'; const projectContext = { getAllFiles() { return []; }, }; fs.writeFileSync(path.join(vlDir, 'project.json'), JSON.stringify({ previewUrls: { App: baseUrl }, }, null, 2)); fs.writeFileSync(path.join(vlDir, 'last-compile.json'), JSON.stringify({ gid: 4242, timestamp: '2026-03-15T16:00:00.000Z', previewUrls: { App: baseUrl }, }, null, 2)); const metadata = { apps: [], sections: [], components: [], services: [], databases: [] }; const navElements = []; const plan = { appName: 'App', appId: 'App', homePage: '/', pages: [{ path: '/', name: 'Home', navPath: [] }], criticalPaths: [], }; const target = WorkflowBuilder.planCaseGenerationTargets(plan, 4)[0]; const cachedCases = [{ id: 'WF_001', name: 'Cached Smoke', priority: 'P0', page: '/', _generationTargetId: target.id, steps: [ { action: 'navigate', selector: baseUrl }, { action: 'assert_visible', selector: 'text=Home' }, ], }]; const workspaceFingerprint = buildWorkspaceFingerprint(projectContext); const previewCacheKey = buildPreviewCacheKey(workDir, baseUrl); const promptCacheKey = buildPromptCacheKey({ appId: 'App', workspaceFingerprint, appMeta: metadata, navElements }); const parseCacheKey = buildParseCacheKey({ appId: 'App', workspaceFingerprint, appMeta: metadata, navElements }); const casesCacheKey = buildGeneratedCasesCacheKey({ appId: 'App', workspaceFingerprint, appMeta: metadata, baseUrl, navElements, target, workDir, }); const visibilityCacheKey = buildPageVisibilityCacheKey({ previewCacheKey, appId: 'App', testPlan: plan, }); fs.writeFileSync(path.join(vlDir, 'autotest-cache.json'), JSON.stringify({ version: 1, navDiscovery: { [previewCacheKey]: { updatedAt: '2026-03-15T16:00:00.000Z', lastUsedAt: Date.now(), value: navElements }, }, pageVisibility: { [visibilityCacheKey]: { updatedAt: '2026-03-15T16:00:00.000Z', lastUsedAt: Date.now(), value: { '/': { visibleIds: [] } } }, }, promptFragments: { [promptCacheKey]: { updatedAt: '2026-03-15T16:00:00.000Z', lastUsedAt: Date.now(), value: 'cached metadata context' }, }, parsedPlans: { [parseCacheKey]: { updatedAt: '2026-03-15T16:00:00.000Z', lastUsedAt: Date.now(), value: plan }, }, generatedCases: { [casesCacheKey]: { updatedAt: '2026-03-15T16:00:00.000Z', lastUsedAt: Date.now(), value: cachedCases }, }, }, null, 2)); const originalDiscoverNav = TestRunner.discoverNavElementsOnce; const originalLaunch = TestRunner.prototype.launch; const originalExecute = WorkflowExecutor.prototype.execute; TestRunner.discoverNavElementsOnce = async () => { throw new Error('nav discovery should not run on cache hit'); }; TestRunner.prototype.launch = async function launchShouldNotRun() { throw new Error('browser launch should not run on cache hit'); }; WorkflowExecutor.prototype.execute = async function executeShouldNotRun() { throw new Error('workflow execution should not run on cache hit'); }; try { const tool = createAutoTestPipelineTool( { workDir, autotest: { useWorkflowEngine: true, maxCases: 4 }, llmProvider: 'cli', cliAvailable: true, model: 'claude-opus-4-6', }, projectContext ); const result = await tool.execute({ action: 'generate', baseUrl, maxCases: 4 }); assert.match(result.result, /Generated 1 test cases/); assert.equal(result.testCases.length, 1, 'cached generate should return cached cases'); assert.equal(result.testCases[0].name, 'Cached Smoke'); } finally { TestRunner.discoverNavElementsOnce = originalDiscoverNav; TestRunner.prototype.launch = originalLaunch; WorkflowExecutor.prototype.execute = originalExecute; fs.rmSync(workDir, { recursive: true, force: true }); } console.log('PASS test-autotest-generate-cache.js');