fix(oracle-r2): same-origin baseUrl + refresh actually re-fetches
Oracle round-2 review caught two real bugs: 1. Production baseUrl bypassed the nginx /api proxy - api.ts defaulted to https://demo.flow-master.ai in prod - Browser would hit cross-origin and CORS-fail - Now: baseUrl='' everywhere; nginx.conf already reverse-proxies /api/* - vite.config.ts proxy still handles dev 2. Refresh button didn't refresh - setMode('live') early-returned when already in live mode - Now: setMode() and refreshLive() share runLiveFetch(); refreshLive ignores the same-mode guard and always re-runs - 4 new vitest regressions in state/store.test.ts cover the contract - Smoke now asserts /api/ea2/work-items is called twice after Refresh Also: - buildScenarios.ts parallelized: cap N=6 candidates, Promise.all per- candidate fetches → live mode now ~3s instead of 30s - CommandBar + LeftRail preview toasts now name the exact endpoint (/api/runtime/transactions/{id}/actions) in the visible text - Landing 'Go live' button rebound to refreshLive() when already live; copy changed to 'Live · refresh' - README: scenario table now renders (added separator row); deploy section points at the real ops PR + the actual overlay path (overlays/demo, not overlays/mc.flow-master.ai); CORS doc clarifies same-origin requirement Constraint: browsers reject cross-origin → same-origin /api/* required Rejected: dev/prod baseUrl divergence | created production bug Confidence: high Scope-risk: narrow Not-tested: production image actually built + served by ops PR (gated by trusted updater + DNS)
This commit is contained in:
+35
-1
@@ -114,7 +114,11 @@ await page.waitForTimeout(450);
|
||||
logOk("tour advances", (await page.locator(".tour-title").first().innerText()).length > 0);
|
||||
await page.keyboard.press("Escape");
|
||||
|
||||
// Live-mode toggle (real network call to demo.flow-master.ai)
|
||||
// Live-mode toggle (real network call to demo.flow-master.ai via vite proxy)
|
||||
const networkCalls = [];
|
||||
page.on("request", (req) => {
|
||||
if (req.url().includes("/api/ea2/work-items")) networkCalls.push(req.url());
|
||||
});
|
||||
const toggleBtn = page.locator(".mode-toggle").first();
|
||||
await toggleBtn.click();
|
||||
const liveOk = await page.waitForFunction(
|
||||
@@ -126,6 +130,36 @@ if (liveOk) {
|
||||
await page.waitForTimeout(400);
|
||||
await page.screenshot({ path: `${OUT}/09-live-mode.png` });
|
||||
logOk("Refresh button appears in live mode", await page.locator(".link-btn", { hasText: "Refresh" }).isVisible());
|
||||
|
||||
// Refresh must trigger ANOTHER /api/ea2/work-items request (Oracle round 2 fix).
|
||||
// Wait for the Refresh button to become enabled (initial fetch may still be settling).
|
||||
await page.locator(".link-btn", { hasText: "Refresh" }).waitFor({ state: "visible" });
|
||||
await page.waitForFunction(
|
||||
() => {
|
||||
const btns = Array.from(document.querySelectorAll(".link-btn"));
|
||||
const btn = btns.find((b) => (b.textContent || "").includes("Refresh"));
|
||||
return btn && !btn.disabled;
|
||||
},
|
||||
{ timeout: 10000 },
|
||||
);
|
||||
const before = networkCalls.length;
|
||||
await page.locator(".link-btn", { hasText: "Refresh" }).click();
|
||||
await page.waitForTimeout(2500);
|
||||
logOk("Refresh re-fetches /api/ea2/work-items", networkCalls.length > before,
|
||||
`before=${before} after=${networkCalls.length}`);
|
||||
}
|
||||
|
||||
// LeftRail Confirm button: toast must name /api/runtime/transactions/{id}/actions
|
||||
await page.locator(".mc-tab", { hasText: "Accounts Receivable" }).click();
|
||||
await page.waitForTimeout(400);
|
||||
const confirmBtn = page.locator(".agent-acts .btn-primary").first();
|
||||
if (await confirmBtn.count() > 0) {
|
||||
await confirmBtn.click();
|
||||
await page.waitForTimeout(300);
|
||||
const lastToast = (await page.locator(".toast-msg").last().innerText()).trim();
|
||||
logOk("LeftRail Confirm toast names /api/runtime/transactions endpoint",
|
||||
/\/api\/runtime\/transactions\/\{id\}\/actions/.test(lastToast),
|
||||
`toast="${lastToast.slice(0, 80)}"`);
|
||||
}
|
||||
|
||||
// Telemetry honesty (check before leaving MC because RH has no telemetry strip)
|
||||
|
||||
Reference in New Issue
Block a user