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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 28 additions & 18 deletions frontend/scripts/smoke-clips-first-lifecycle.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const readSource = (relativePath) => readFileSync(resolve(__dirname, relativePat
const appSource = readSource('../src/App.tsx');
const panelSource = readSource('../src/components/AIPanel.tsx');
const aiStoreSource = readSource('../src/store/aiStore.ts');
const aiJobControllerSource = readSource('../src/features/ai/useAIJobController.ts');

assert.match(appSource, /const currentWorkflowIntent: WorkflowIntent = editorWorkflow === 'short' \? 'short' : 'full-video'/);
assert.match(appSource, /onClick=\{\(\) => void handleOpenFile\(currentWorkflowIntent\)\}/);
Expand Down Expand Up @@ -46,28 +47,37 @@ assert.match(aiStoreSource, /clipReviewDecisions: \{\}/);
assert.match(aiStoreSource, /providers: \{/);
assert.match(panelSource, /if \(!isCurrentClipWorkspace\(\)\) return;\s+setEditPlanResult\(data\);/);
assert.match(panelSource, /if \(!isCurrentClipWorkspace\(\)\) return;\s+setFillerResult\(data\);/);
assert.match(panelSource, /type AIJobRunContext = \{[\s\S]*workspaceEpoch: number/);
assert.match(panelSource, /const activeAIJobRunRef = useRef<AIJobRunContext \| null>\(null\)/);
assert.match(panelSource, /Another AI action is still running/);
assert.match(panelSource, /const isCurrentAIJobRun = useCallback/);
assert.match(panelSource, /let jobRes: Response;[\s\S]*jobRes = await fetch\(`\$\{backendUrl\}\/jobs\/\$\{jobId\}`\)[\s\S]*Connection interrupted; checking AI job status[\s\S]*continue;/);
assert.match(panelSource, /if \(!jobRes\.ok\) \{[\s\S]*jobRes\.status === 404[\s\S]*AI job status unavailable; retrying[\s\S]*continue;/);
assert.match(panelSource, /let job: AIJob<T>;[\s\S]*job = \(await jobRes\.json\(\)\) as AIJob<T>[\s\S]*AI job status was unreadable; retrying[\s\S]*continue;/);
assert.match(panelSource, /setActiveAIJob\(\{ \.\.\.job, \.\.\.context, workspaceEpoch: run\.workspaceEpoch, runId: run\.id \}\)/);
assert.match(panelSource, /workspaceEpoch: run\.workspaceEpoch/);
assert.match(panelSource, /runId: run\.id/);
assert.match(panelSource, /current && current\.workspaceEpoch !== clipWorkspaceEpoch \? null : current/);
const cancelAIJobBody = panelSource.match(/const cancelAIJob = useCallback\(async \(\) => \{([\s\S]*?)\n\s*\}, \[/)?.[1] || '';
assert.match(panelSource, /useAIJobController\(\{ backendUrl \}\)/);
assert.doesNotMatch(panelSource, /activeAIJobRunRef|const pollAIJob|const beginAIJobRun|const finishAIJobRun|const isCurrentAIJobRun/);
assert.match(aiJobControllerSource, /type AIJobRunContext = \{[\s\S]*workspaceEpoch: number/);
assert.match(aiJobControllerSource, /const activeAIJobRunRef = useRef<AIJobRunContext \| null>\(null\)/);
assert.match(aiJobControllerSource, /Another AI action is still running/);
assert.match(aiJobControllerSource, /const isCurrentAIJobRun = useCallback/);
assert.match(aiJobControllerSource, /let jobRes: Response;[\s\S]*jobRes = await fetch\(`\$\{backendUrl\}\/jobs\/\$\{jobId\}`\)[\s\S]*Connection interrupted; checking AI job status[\s\S]*continue;/);
assert.match(aiJobControllerSource, /if \(!jobRes\.ok\) \{[\s\S]*jobRes\.status === 404[\s\S]*AI job status unavailable; retrying[\s\S]*continue;/);
assert.match(aiJobControllerSource, /let job: AIJob<T>;[\s\S]*job = \(await jobRes\.json\(\)\) as AIJob<T>[\s\S]*AI job status was unreadable; retrying[\s\S]*continue;/);
assert.match(aiJobControllerSource, /setActiveAIJob\(\{ \.\.\.job, \.\.\.context, workspaceEpoch: run\.workspaceEpoch, runId: run\.id \}\)/);
assert.match(aiJobControllerSource, /workspaceEpoch: run\.workspaceEpoch/);
assert.match(aiJobControllerSource, /runId: run\.id/);
assert.match(aiJobControllerSource, /current && current\.workspaceEpoch !== clipWorkspaceEpoch \? null : current/);
assert.doesNotMatch(aiJobControllerSource, /defaultProvider|providers|setFillerResult|setEditPlanResult|applyClipDiscoveryResult|mergeGeneratedPublishingCopy|setCreatorNotice|getCreatorErrorPresentation/);
const cancelAIJobBody = aiJobControllerSource.match(/const cancelAIJob = useCallback\(async \(\) => \{([\s\S]*?)\n\s*\}, \[/)?.[1] || '';
assert.match(cancelAIJobBody, /const run = activeAIJobRunRef\.current/);
assert.match(cancelAIJobBody, /if \(job\.workspaceEpoch !== run\.workspaceEpoch \|\| job\.runId !== run\.id \|\| !isCurrentAIJobRun\(run\)\) return/);
assert.match(cancelAIJobBody, /await fetch\([\s\S]*if \(!isCurrentAIJobRun\(run\)\) return/);
assert.doesNotMatch(cancelAIJobBody, /setProcessing\(false/);
const retryAIJobBody = panelSource.match(/const retryAIJob = useCallback\(async \(\) => \{([\s\S]*?)\n\s*\}, \[/)?.[1] || '';
assert.match(retryAIJobBody, /const sourceJob = activeAIJob/);
assert.match(retryAIJobBody, /sourceJob\.workspaceEpoch !== useAIStore\.getState\(\)\.clipWorkspaceEpoch/);
assert.match(retryAIJobBody, /run = beginAIJobRun\(\)/);
assert.match(retryAIJobBody, /pollAIJob<unknown>\(jobId, sourceJob\.label, context, run\)/);
assert.match(retryAIJobBody, /if \(!isCurrentAIJobRun\(run\)\) return/);
const retryTransportBody = aiJobControllerSource.match(/const retryAIJob = useCallback\(async \(\) => \{([\s\S]*?)\n\s*\}, \[/)?.[1] || '';
assert.match(retryTransportBody, /const sourceJob = activeAIJob/);
assert.match(retryTransportBody, /sourceJob\.workspaceEpoch !== useAIStore\.getState\(\)\.clipWorkspaceEpoch/);
assert.match(retryTransportBody, /const run = beginAIJobRun\(\)/);
assert.match(retryTransportBody, /pollAIJob<unknown>\(jobId, sourceJob\.label, context, run\)/);
assert.match(retryTransportBody, /if \(!isCurrentAIJobRun\(run\)\) return null/);
const retryDomainBody = panelSource.match(/const retryAIJob = useCallback\(async \(\) => \{([\s\S]*?)\n\s*\}, \[/)?.[1] || '';
assert.match(retryDomainBody, /const retryResult = await retryAIJobTransport\(\)/);
assert.match(retryDomainBody, /retriedJob\.workspaceEpoch !== useAIStore\.getState\(\)\.clipWorkspaceEpoch/);
assert.match(retryDomainBody, /retriedJob\.kind === 'ai:filler-removal'/);
assert.match(retryDomainBody, /applyClipDiscoveryResult\(result as ClipDiscoveryResult, 'suggested_clip_retry'\)/);
assert.match(retryDomainBody, /mergeGeneratedPublishingCopy\(currentDraft, metadata\)/);

const openFileBody = appSource.match(/const handleOpenFile = async \(intent: WorkflowIntent = 'full-video'\) => \{([\s\S]*?)\n\s*\};\s*const handleBrowserFileChange/)?.[1] || '';
const browserChangeBody = appSource.match(/const handleBrowserFileChange = async \(e: React\.ChangeEvent<HTMLInputElement>\) => \{([\s\S]*?)\n\s*\};\s*const handleBrowserDrop/)?.[1] || '';
Expand Down
9 changes: 5 additions & 4 deletions frontend/scripts/smoke-errors-accessibility.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const transcript = readSource('../src/components/TranscriptEditor.tsx');
const status = readSource('../src/components/TranscriptionStatus.tsx');
const waveform = readSource('../src/components/WaveformTimeline.tsx');
const ai = readSource('../src/components/AIPanel.tsx');
const aiJobController = readSource('../src/features/ai/useAIJobController.ts');
const dialog = readSource('../src/components/CreatorDialog.tsx');
const notice = readSource('../src/components/CreatorNotice.tsx');
const shortcuts = readSource('../src/hooks/useKeyboardShortcuts.ts');
Expand Down Expand Up @@ -82,13 +83,13 @@ assert.match(waveform, /aria-label=\{followPlayhead \? 'Stop following playhead'
assert.match(waveform, /aria-label="Zoom out"/);
assert.match(waveform, /aria-label="Zoom in"/);

assert.match(ai, /\/jobs\/\$\{sourceJob\.id\}\/retry/);
assert.match(aiJobController, /\/jobs\/\$\{sourceJob\.id\}\/retry/);
assert.match(ai, /ai:clip-metadata/);
assert.match(ai, /appendDiscoveredClipDrafts/);
assert.match(ai, /setCreatorNotice/);
assert.match(ai, /setCreatorNotice\(null\);\s*setProcessing\(true, processingMessage\);\s*try \{\s*const startRes/);
assert.match(ai, /setCreatorNotice\(null\);\s*setProcessing\(true, `Retrying \$\{sourceJob\.label\}/);
assert.match(ai, /Another AI action is still running/);
assert.match(ai, /setCreatorNotice\(null\);\s*return startAIJobTransport<T>\(path, body, fallbackMessage, context, processingMessage\)/);
assert.match(ai, /setCreatorNotice\(null\);\s*try \{\s*const retryResult = await retryAIJobTransport\(\)/);
assert.match(aiJobController, /Another AI action is still running/);
assert.match(ai, /const canRetry = !busy && \(job\.status === 'failed' \|\| job\.status === 'canceled'\)/);
const generatePublishingCopyBody = ai.match(/const generatePublishingCopy = useCallback\(([\s\S]*?)\n \);\n\n const retryAIJob/)?.[1] || '';
assert.match(generatePublishingCopyBody, /getCreatorErrorPresentation\('ai-action', err\)/);
Expand Down
Loading