From 2150636fd00d9f77c67935a5ebad3997a48f2930 Mon Sep 17 00:00:00 2001 From: shad Date: Sun, 14 Jun 2026 16:36:06 +0400 Subject: [PATCH] test(qa): 4 new gates for approvals + documents + llm-proxy chain - approvals_scene_renders_queue (rows > 0) - approvals_detail_shows_active_step_with_actions (title + actions > 0) - documents_scene_renders_data_definitions (rows > 0) - llm_proxy_chain_returns_503_without_provider_key (real network round- trip through canvas nginx -> in-cluster proxy -> 503 because no OPENAI_API_KEY / ANTHROPIC_API_KEY is set) Full dogfood: 36/36 green. --- qa/full_dogfood.mjs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/qa/full_dogfood.mjs b/qa/full_dogfood.mjs index 9c6c747..a98b61d 100644 --- a/qa/full_dogfood.mjs +++ b/qa/full_dogfood.mjs @@ -295,6 +295,46 @@ record( `threads=${threadRowCount}, previews=${previewRows}, times=${timeBadges}` ); +// 18. APPROVALS scene loads with tenant-scoped queue + clickable rows. +await p.goto("https://canvas.flow-master.ai/", { waitUntil: "networkidle" }).catch(() => {}); +await p.waitForTimeout(600); +await p.locator(".hub-chip", { hasText: /Approvals queue/ }).click().catch(() => {}); +await p.waitForSelector(".approvals-row", { timeout: 15000 }).catch(() => {}); +await p.waitForTimeout(1000); +const approvalsRows = await p.locator(".approvals-row").count(); +record("approvals_scene_renders_queue", approvalsRows > 0, `rows=${approvalsRows}`); +if (approvalsRows > 0) { + await p.locator(".approvals-row").first().click(); + await p.waitForSelector(".approvals-card", { timeout: 8000 }).catch(() => {}); + await p.waitForTimeout(600); + const cardTitle = (await p.locator(".approvals-card-title").first().textContent()) || ""; + const actionBtns = await p.locator(".approvals-actions .btn").count(); + record( + "approvals_detail_shows_active_step_with_actions", + cardTitle.trim().length > 0 && actionBtns > 0, + `step="${cardTitle.trim().slice(0, 40)}" actions=${actionBtns}` + ); +} + +// 19. DOCUMENTS scene loads with EA2-sourced data definitions. +await p.goto("https://canvas.flow-master.ai/", { waitUntil: "networkidle" }).catch(() => {}); +await p.waitForTimeout(600); +await p.locator(".hub-chip", { hasText: /^Documents$/ }).click().catch(() => {}); +await p.waitForSelector(".docs-row", { timeout: 20000 }).catch(() => {}); +await p.waitForTimeout(1500); +const docsRows = await p.locator(".docs-row").count(); +record("documents_scene_renders_data_definitions", docsRows > 0, `rows=${docsRows}`); + +// 20. LLM proxy is reachable through canvas nginx; returns 503 without provider. +const llmRes = await p.request.post("https://canvas.flow-master.ai/internal/canvas-llm/chat", { + data: { messages: [{ role: "user", content: "ping" }] }, +}); +record( + "llm_proxy_chain_returns_503_without_provider_key", + llmRes.status() === 503, + `HTTP ${llmRes.status()}` +); + // Summarise const fails = results.filter((r) => !r.ok); console.log(`\n=== ${results.length - fails.length}/${results.length} passed ===`);