|
|
@@ -1,4 +1,4 @@
|
|
|
-import { Page } from '@playwright/test'
|
|
|
+import { Page, WebSocketRoute } from '@playwright/test'
|
|
|
|
|
|
// Mock data
|
|
|
export const mockPatterns = [
|
|
|
@@ -89,12 +89,14 @@ export async function setupApiMocks(page: Page) {
|
|
|
})
|
|
|
|
|
|
await page.route('**/run_playlist', async route => {
|
|
|
- const body = route.request().postDataJSON() as { name: string }
|
|
|
- const playlist = mockPlaylists[body?.name as keyof typeof mockPlaylists]
|
|
|
+ const body = route.request().postDataJSON() as { playlist_name?: string; name?: string }
|
|
|
+ // Support both playlist_name (actual API) and name (legacy)
|
|
|
+ const playlistName = body?.playlist_name || body?.name
|
|
|
+ const playlist = mockPlaylists[playlistName as keyof typeof mockPlaylists]
|
|
|
if (playlist && playlist.length > 0) {
|
|
|
currentStatus.is_running = true
|
|
|
currentStatus.playlist_mode = true
|
|
|
- currentStatus.playlist_name = body.name
|
|
|
+ currentStatus.playlist_name = playlistName || null
|
|
|
currentStatus.current_file = playlist[0]
|
|
|
currentStatus.queue = playlist.slice(1)
|
|
|
}
|
|
|
@@ -148,8 +150,76 @@ export async function setupApiMocks(page: Page) {
|
|
|
await route.fulfill({ json: {} })
|
|
|
})
|
|
|
|
|
|
- // WebSocket - return empty to prevent connection attempts
|
|
|
- // Playwright doesn't intercept WebSocket by default, but we can handle the fallback
|
|
|
+ // Logs endpoint
|
|
|
+ await page.route('**/api/logs**', async route => {
|
|
|
+ await route.fulfill({ json: { logs: [], total: 0, has_more: false } })
|
|
|
+ })
|
|
|
+
|
|
|
+ // Pattern history (individual)
|
|
|
+ await page.route('**/api/pattern_history/**', async route => {
|
|
|
+ await route.fulfill({ json: { actual_time_formatted: null, speed: null } })
|
|
|
+ })
|
|
|
+
|
|
|
+ // Serial ports
|
|
|
+ await page.route('**/list_serial_ports', async route => {
|
|
|
+ await route.fulfill({ json: [] })
|
|
|
+ })
|
|
|
+
|
|
|
+ // Static files - return 200 with placeholder
|
|
|
+ await page.route('**/static/**', async route => {
|
|
|
+ // Return a 1x1 transparent PNG for images
|
|
|
+ const base64Png = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='
|
|
|
+ await route.fulfill({
|
|
|
+ status: 200,
|
|
|
+ contentType: 'image/png',
|
|
|
+ body: Buffer.from(base64Png, 'base64'),
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // WebSocket mocking - critical for bypassing the "Connecting to Backend" overlay
|
|
|
+ // The Layout component shows a blocking overlay until WebSocket connects
|
|
|
+ await page.routeWebSocket('**/ws/status', (ws: WebSocketRoute) => {
|
|
|
+ // Don't connect to server - we're mocking everything
|
|
|
+ // Send status updates to simulate backend status messages
|
|
|
+ const statusMessage = JSON.stringify({
|
|
|
+ type: 'status_update',
|
|
|
+ data: {
|
|
|
+ ...currentStatus,
|
|
|
+ connection_status: true,
|
|
|
+ is_homing: false,
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // Send initial status immediately after connection
|
|
|
+ // The client's onopen handler will fire, setting isBackendConnected = true
|
|
|
+ setTimeout(() => {
|
|
|
+ ws.send(statusMessage)
|
|
|
+ }, 100)
|
|
|
+
|
|
|
+ // Send periodic updates
|
|
|
+ const interval = setInterval(() => {
|
|
|
+ ws.send(statusMessage)
|
|
|
+ }, 1000)
|
|
|
+
|
|
|
+ ws.onClose(() => {
|
|
|
+ clearInterval(interval)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // Mock other WebSocket endpoints
|
|
|
+ await page.routeWebSocket('**/ws/logs', (_ws: WebSocketRoute) => {
|
|
|
+ // Just accept the connection - don't need to send anything
|
|
|
+ })
|
|
|
+
|
|
|
+ await page.routeWebSocket('**/ws/cache-progress', (ws: WebSocketRoute) => {
|
|
|
+ // Send "not running" status
|
|
|
+ setTimeout(() => {
|
|
|
+ ws.send(JSON.stringify({
|
|
|
+ type: 'cache_progress',
|
|
|
+ data: { is_running: false, stage: 'idle' }
|
|
|
+ }))
|
|
|
+ }, 100)
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
export function getMockStatus() {
|