import { expect } from "vitest"; import { denFetch, evalIn, waitFor } from "@openwork/behaviors"; import type { DenSession } from "@openwork/behaviors"; import { app, needs, server, test, unmetNeeds } from "@openwork/testkit"; import type { TestNeeds } from "@openwork/testkit"; const requirements: TestNeeds = { optIn: ["OPENWORK_EVAL_E2E_TESTS"], }; const missingRequirements = unmetNeeds(requirements, process.env); const title = missingRequirements.length > 0 ? `organization-managed Desktop dashboard skipped — needs: ${missingRequirements.join(", ")}` : "Desktop enables managed dashboard caching and automatic refresh after member opt-in"; function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } async function organizationId(session: DenSession): Promise { const result = await denFetch(session, "/v1/me/orgs", { headers: { authorization: `Bearer ${session.token}` }, }); const organizations = isRecord(result.body) && Array.isArray(result.body.orgs) ? result.body.orgs.filter(isRecord) : []; const id = organizations[0] && typeof organizations[0].id === "string" ? organizations[0].id : ""; if (!result.response.ok || !id) { throw new Error(`Finding the active organization failed: HTTP ${result.response.status} ${result.text.slice(0, 500)}`); } return id; } type DashboardElementInput = { serverName: string; connectionId: string; toolName: string; projectedToolName: string; resourceUri: string; title: string; requiresApproval?: boolean; organizationAutoLaunch?: boolean; }; const weeklyReportElement: DashboardElementInput = { serverName: "openwork-app-host-connect-0123456789ab", connectionId: "emc_01dashboardfixture0000000000", toolName: "render_report", projectedToolName: "openwork-app-host-connect-0123456789ab_render_report", resourceUri: "ui://fixture/report/view.html", title: "Weekly report", }; async function createDashboard( session: DenSession, name: string, elements: DashboardElementInput[] = [weeklyReportElement], ): Promise { const result = await denFetch(session, "/v1/dashboards", { method: "POST", headers: { authorization: `Bearer ${session.token}` }, body: JSON.stringify({ name, elements, }), }); const item = isRecord(result.body) && isRecord(result.body.item) ? result.body.item : null; const id = item && typeof item.id === "string" ? item.id : ""; const returnedElements = item && Array.isArray(item.elements) ? item.elements : []; if (result.response.status !== 201 || !id || returnedElements.length !== elements.length) { throw new Error(`Creating ${name} failed: HTTP ${result.response.status} ${result.text.slice(0, 500)}`); } return id; } test(title, async ({ evidence, place }) => { needs(requirements); await using den = await server({ place, env: { DEN_DASHBOARDS_ENABLED: "true" }, org: { name: `Managed Desktop dashboard ${Date.now()}`, admin: { name: "Managed Dashboard Admin" }, }, }); const orgId = await organizationId(den.admin); const grantedName = `Operations board ${Date.now()}`; const privateName = `Private board ${Date.now()}`; const grantedDashboardId = await createDashboard(den.admin, grantedName, [ weeklyReportElement, { ...weeklyReportElement, toolName: "create_ticket", projectedToolName: "openwork-app-host-connect-0123456789ab_create_ticket", resourceUri: "ui://fixture/ticket/view.html", title: "Automatic ticket summary", requiresApproval: true, organizationAutoLaunch: true, }, ]); await createDashboard(den.admin, privateName); const grant = await denFetch(den.admin, `/v1/dashboards/${grantedDashboardId}/access`, { method: "POST", headers: { authorization: `Bearer ${den.admin.token}` }, body: JSON.stringify({ orgWide: true, role: "viewer" }), }); if (grant.response.status !== 201) { throw new Error(`Granting the dashboard failed: HTTP ${grant.response.status} ${grant.text.slice(0, 500)}`); } await using desktop = await app({ den, as: "admin", place, }); const dashboardHash = "#/dashboard"; const dashboardOpened = await evalIn(desktop, `(() => { const button = [...document.querySelectorAll("button")] .find((entry) => entry.textContent?.trim() === "Dashboard"); if (!(button instanceof HTMLButtonElement) || button.disabled) return false; button.click(); return true; })()`); expect(dashboardOpened).toBe(true); await waitFor(desktop, `(() => { const section = document.querySelector(${JSON.stringify(`[data-granted-dashboard="${grantedDashboardId}"]`)}); return location.hash === ${JSON.stringify(dashboardHash)} && section instanceof HTMLElement && section.innerText.includes(${JSON.stringify(grantedName)}) && section.innerText.includes("Managed by your organization") && section.innerText.includes("Weekly report"); })()`, { timeoutMs: 90_000, label: "granted organization dashboard rendered in Desktop", }); const initialState = await evalIn(desktop, `(() => { const section = document.querySelector(${JSON.stringify(`[data-granted-dashboard="${grantedDashboardId}"]`)}); if (!(section instanceof HTMLElement)) return null; const allText = document.body.innerText; const weeklyTile = [...section.querySelectorAll("[data-dashboard-entry]")] .find((tile) => tile.textContent?.includes("Weekly report")); const searchButton = [...document.querySelectorAll("button")] .find((button) => button.textContent?.includes("Search sessions")); const dashboardButton = [...document.querySelectorAll("button")] .find((button) => button.textContent?.trim() === "Dashboard"); return { boardVisible: section.innerText.includes(${JSON.stringify(grantedName)}), privateBoardVisible: allText.includes(${JSON.stringify(privateName)}), readOnlyRunVisible: Boolean(section.querySelector('button[aria-label="Run Weekly report"]')), automaticAttemptVisible: weeklyTile instanceof HTMLElement && weeklyTile.innerText.includes("Refresh failed"), removeVisible: Boolean(section.querySelector('button[aria-label="Remove Weekly report"]')), addAppVisible: [...document.querySelectorAll("button")] .some((button) => button.textContent?.trim() === "Add app"), managedLabelVisible: section.innerText.includes("Managed by your organization"), dashboardImmediatelyAfterSearch: searchButton instanceof HTMLElement && dashboardButton instanceof HTMLElement && searchButton.parentElement?.nextElementSibling?.contains(dashboardButton) === true, }; })()`); expect(initialState).toEqual({ boardVisible: true, privateBoardVisible: false, readOnlyRunVisible: true, automaticAttemptVisible: false, removeVisible: false, addAppVisible: false, managedLabelVisible: true, dashboardImmediatelyAfterSearch: true, }); await waitFor(desktop, `(() => { const section = document.querySelector(${JSON.stringify(`[data-granted-dashboard="${grantedDashboardId}"]`)}); if (!(section instanceof HTMLElement)) return false; const automaticTile = [...section.querySelectorAll("[data-dashboard-entry]")] .find((tile) => tile.textContent?.includes("Automatic ticket summary")); const cacheState = automaticTile instanceof HTMLElement ? automaticTile.querySelector("[data-dashboard-cache-state]")?.getAttribute("data-dashboard-cache-state") : null; return automaticTile instanceof HTMLElement && (cacheState === "refreshing" || automaticTile.innerText.includes("Refresh failed")) && !automaticTile.querySelector('button[aria-label="Run Automatic ticket summary"]'); })()`, { timeoutMs: 90_000, label: "organization-authorized modifying app attempted automatic load", }); const organizationPolicyState = await evalIn(desktop, `(() => { const section = document.querySelector(${JSON.stringify(`[data-granted-dashboard="${grantedDashboardId}"]`)}); const tile = section instanceof HTMLElement ? [...section.querySelectorAll("[data-dashboard-entry]")] .find((entry) => entry.textContent?.includes("Automatic ticket summary")) : null; const cacheState = tile instanceof HTMLElement ? tile.querySelector("[data-dashboard-cache-state]")?.getAttribute("data-dashboard-cache-state") : null; return { automaticAttemptVisible: tile instanceof HTMLElement && (cacheState === "refreshing" || tile.innerText.includes("Refresh failed")), cacheState, runVisible: Boolean(tile?.querySelector('button[aria-label="Run Automatic ticket summary"]')), }; })()`); expect(organizationPolicyState).toMatchObject({ automaticAttemptVisible: true, runVisible: false }); evidence.recordAssertionEvidence( "Desktop places Dashboard directly below Search in the left sidebar", `state=${JSON.stringify(initialState)}`, isRecord(initialState) && initialState.dashboardImmediatelyAfterSearch === true, ); evidence.recordAssertionEvidence( "Organization admins can authorize automatic launch even for an app that modifies data", `tile=Automatic ticket summary; state=${JSON.stringify(organizationPolicyState)}`, isRecord(organizationPolicyState) && organizationPolicyState.automaticAttemptVisible === true && organizationPolicyState.runVisible === false, ); evidence.recordAssertionEvidence( "Desktop renders only dashboards granted to the signed-in member", `org=${orgId}; granted=${grantedName}; ungranted=${privateName}; state=${JSON.stringify(initialState)}`, isRecord(initialState) && initialState.boardVisible === true && initialState.privateBoardVisible === false, ); evidence.recordAssertionEvidence( "Managed app metadata cannot trigger a first-visit launch without member opt-in", `tile=Weekly report; state=${JSON.stringify(initialState)}`, isRecord(initialState) && initialState.readOnlyRunVisible === true && initialState.automaticAttemptVisible === false, ); const cacheSeeded = await evalIn(desktop, `(() => { const page = document.querySelector("[data-dashboard-cache-scope]"); const section = document.querySelector(${JSON.stringify(`[data-granted-dashboard="${grantedDashboardId}"]`)}); if (!(page instanceof HTMLElement) || !(section instanceof HTMLElement)) return false; const weeklyTile = [...section.querySelectorAll("[data-dashboard-entry]")] .find((tile) => tile.textContent?.includes("Weekly report")); const scope = page.dataset.dashboardCacheScope; const consentScope = page.dataset.dashboardConsentScope; const entryId = weeklyTile instanceof HTMLElement ? weeklyTile.dataset.dashboardEntry : undefined; if (!scope || !consentScope || !entryId) return false; localStorage.setItem(consentScope, JSON.stringify({ [entryId]: { autoLaunch: true } })); localStorage.setItem(scope, JSON.stringify({ [entryId]: { cachedAt: Date.now(), workspaceId: ${JSON.stringify(desktop.workspaceId)}, app: { serverName: "openwork-app-host-connect-0123456789ab", toolName: "render_report", resourceUri: "ui://fixture/report/view.html", html: "
Saved weekly report
", csp: { connectDomains: [], resourceDomains: [], frameDomains: [], baseUriDomains: [] }, prefersBorder: true, }, result: { content: [{ type: "text", text: "Saved weekly report" }], structuredContent: { report: "saved" }, }, }, })); location.reload(); return true; })()`); expect(cacheSeeded).toBe(true); await waitFor(desktop, `(() => { const section = document.querySelector(${JSON.stringify(`[data-granted-dashboard="${grantedDashboardId}"]`)}); if (!(section instanceof HTMLElement)) return false; const weeklyTile = [...section.querySelectorAll("[data-dashboard-entry]")] .find((tile) => tile.textContent?.includes("Weekly report")); return weeklyTile instanceof HTMLElement && Boolean(weeklyTile.querySelector("iframe")) && (weeklyTile.innerText.includes("Saved locally · refreshing") || weeklyTile.innerText.includes("Saved locally · refresh failed")); })()`, { timeoutMs: 90_000, label: "saved dashboard view remained visible during background refresh", }); const cachedState = await evalIn(desktop, `(() => { const section = document.querySelector(${JSON.stringify(`[data-granted-dashboard="${grantedDashboardId}"]`)}); const weeklyTile = section instanceof HTMLElement ? [...section.querySelectorAll("[data-dashboard-entry]")] .find((tile) => tile.textContent?.includes("Weekly report")) : null; return { cachedViewVisible: weeklyTile instanceof HTMLElement && Boolean(weeklyTile.querySelector("iframe")), refreshActive: weeklyTile instanceof HTMLElement && (weeklyTile.innerText.includes("Saved locally · refreshing") || weeklyTile.innerText.includes("Saved locally · refresh failed")), readOnlyRunVisible: Boolean(section?.querySelector('button[aria-label="Run Weekly report"]')), }; })()`); expect(cachedState).toEqual({ cachedViewVisible: true, refreshActive: true, readOnlyRunVisible: false, }); evidence.recordAssertionEvidence( "Desktop renders saved dashboard data immediately and keeps it visible during background refresh", `tile=Weekly report; state=${JSON.stringify(cachedState)}`, isRecord(cachedState) && cachedState.cachedViewVisible === true && cachedState.refreshActive === true && cachedState.readOnlyRunVisible === false, ); evidence.recordAssertionEvidence( "Managed dashboards stay non-removable and have no local authoring controls", `state=${JSON.stringify(initialState)}`, isRecord(initialState) && initialState.removeVisible === false && initialState.addAppVisible === false && initialState.managedLabelVisible === true, ); });