High priority (new PR #108 features): - Command palette: open/close, search flows, page navigation, FlowPilot handoff - Fallback branches: add in editor, execute in session runner - Session-to-flow: verify button appears on completed session detail Medium priority (existing features without coverage): - Procedural session: intake form, step-through, completion - Tree editor: troubleshooting and procedural editor load/edit/save - FlowPilot chat: page load, new chat creation - Admin panel: dashboard, user management, settings access Also adds API helpers: createProceduralTree(), createProceduralTreeWithFallbacks() Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
95 lines
3.3 KiB
TypeScript
95 lines
3.3 KiB
TypeScript
import { expect, test } from '@playwright/test'
|
|
import {
|
|
createAuthenticatedApiContext,
|
|
createProceduralTree,
|
|
createProceduralTreeWithFallbacks,
|
|
disposeApiContext,
|
|
uniqueName,
|
|
} from './helpers/api'
|
|
|
|
test.describe('fallback branches smoke tests', () => {
|
|
test('can add and remove fallback steps in the procedural editor', async ({ page }) => {
|
|
const api = await createAuthenticatedApiContext()
|
|
const tree = await createProceduralTree(api, {
|
|
name: uniqueName('PW Editor Fallback Flow'),
|
|
})
|
|
|
|
try {
|
|
// Navigate to the procedural editor
|
|
await page.goto(`/flows/${tree.id}/edit`)
|
|
|
|
// Wait for editor to load
|
|
await expect(page.getByText('Verify the server is reachable')).toBeVisible({ timeout: 10000 })
|
|
|
|
// Click on the first step to expand it
|
|
await page.getByText('Verify the server is reachable').click()
|
|
|
|
// Look for fallback branches section
|
|
const fallbackToggle = page.getByText(/Fallback branches/)
|
|
await expect(fallbackToggle).toBeVisible()
|
|
|
|
// Expand fallback section
|
|
await fallbackToggle.click()
|
|
|
|
// Add a fallback step
|
|
await page.getByText('Add fallback step').click()
|
|
|
|
// Should show a new fallback step input
|
|
const fallbackInput = page.getByPlaceholder('Fallback step title')
|
|
await expect(fallbackInput).toBeVisible()
|
|
await fallbackInput.fill('Try alternative ping method')
|
|
|
|
// Fill description
|
|
const descInput = page.getByPlaceholder('What to try instead...')
|
|
await expect(descInput).toBeVisible()
|
|
await descInput.fill('Use traceroute if ping fails')
|
|
|
|
// Fallback count should update
|
|
await expect(page.getByText(/Fallback branches \(1\)/)).toBeVisible()
|
|
} finally {
|
|
await disposeApiContext(api)
|
|
}
|
|
})
|
|
|
|
test('shows fallback steps during procedural session execution', async ({ page }) => {
|
|
const api = await createAuthenticatedApiContext()
|
|
const tree = await createProceduralTreeWithFallbacks(api, {
|
|
name: uniqueName('PW Runner Fallback Flow'),
|
|
})
|
|
|
|
try {
|
|
// Navigate to the procedural flow
|
|
await page.goto(`/flows/${tree.id}/navigate`)
|
|
await expect(page.getByRole('heading', { name: tree.name })).toBeVisible({ timeout: 10000 })
|
|
|
|
// Start the session (no intake form on this flow)
|
|
const startButton = page.getByRole('button', { name: /Start/ })
|
|
await startButton.click()
|
|
|
|
// Should see the first step
|
|
await expect(page.getByText('Clear the DNS cache')).toBeVisible({ timeout: 5000 })
|
|
|
|
// Should see "Didn't work?" toggle since step has fallback_steps
|
|
const didntWorkToggle = page.getByText("Didn't work?")
|
|
await expect(didntWorkToggle).toBeVisible()
|
|
|
|
// Expand fallback section
|
|
await didntWorkToggle.click()
|
|
|
|
// Should see fallback step options
|
|
await expect(page.getByText('Restart DNS Client service')).toBeVisible()
|
|
await expect(page.getByText('Check DNS server configuration')).toBeVisible()
|
|
|
|
// Mark a fallback as resolved
|
|
const thisWorked = page.getByRole('button', { name: 'This worked' }).first()
|
|
await expect(thisWorked).toBeVisible()
|
|
await thisWorked.click()
|
|
|
|
// Fallback step should show completed styling
|
|
await expect(page.locator('[class*="border-emerald"]').first()).toBeVisible()
|
|
} finally {
|
|
await disposeApiContext(api)
|
|
}
|
|
})
|
|
})
|