diff --git a/components/CompiledProgramSection.js b/components/CompiledProgramSection.js
index b1729334..cfc4a83b 100644
--- a/components/CompiledProgramSection.js
+++ b/components/CompiledProgramSection.js
@@ -30,16 +30,12 @@ const FIGURES = [
eyebrow: 'Workflow catalog & halt map',
title: 'Read the whole portfolio, halt by halt.',
body:
- 'The catalog is a read-only readout across every compiled ' +
- 'workflow: what each one automates, how its trials went, and the ' +
- 'return it stands to make. The step-level halt map shows where runs ' +
- 'stop and why, so you fix the demonstration or policy at the exact ' +
- 'step.',
+ 'The catalog is a read-only view of compiled workflows in the ' +
+ 'workspace. Review the current workflow state before you run it.',
image: '/cloud-preview/workflow-catalog.png',
alt:
- 'OpenAdapt Cloud workflow catalog: a portfolio ROI readout with a ' +
- 'step-level halt map showing where runs halt and why.',
- caption: 'Workflow catalog & halt map in Cloud',
+ 'OpenAdapt Cloud workflow catalog for the synthetic OpenEMR fixture.',
+ caption: 'Workflow catalog in Cloud',
},
]
diff --git a/components/DashboardShowcase.js b/components/DashboardShowcase.js
index 422de2a9..a2914bcd 100644
--- a/components/DashboardShowcase.js
+++ b/components/DashboardShowcase.js
@@ -3,29 +3,24 @@ import styles from './DashboardShowcase.module.css'
// Real screenshots of the shipping OpenAdapt Cloud product (openadapt-cloud),
// captured from the actual dashboard UI. This is a rotating showcase: the large
-// slot cycles through the real product frames (dashboard, run detail, halt
-// evidence, program visualizer, workflow catalog) so each gets time on screen
+// slot cycles through the real product frames (dashboard, run detail, program
+// visualizer, workflow catalog) so each gets time on screen
// big enough to read. Every frame is a full-height capture of the real
// interface (see /product-preview/MANIFEST.json and /cloud-preview/provenance.json).
// Nothing here is a hand-drawn or synthetic mockup of an app that does not exist.
//
-// The captures are full pages, not top crops, and the large stage reveals each
-// one with a slow top-to-bottom vertical auto-pan over its dwell so the visitor
-// sees the WHOLE page rather than just the first screenful. Under reduced motion
-// the pan is dropped and the whole frame is shown at once (see the module CSS),
-// so nothing depends on movement to be legible.
+// The captures are focused viewport frames so the product state is readable.
//
// Order matters: the dashboard is first so it is the default (and SSR / no-JS)
// frame, which is why the browser address bar reads app.openadapt.ai/dashboard
// before any rotation. Every capture is 2560px wide at the same device scale, so
-// the five frames share one product look; their heights differ because each real
-// page is a different length.
+// the four frames share one product look.
const SLIDES = [
{
key: 'dashboard',
src: '/product-preview/dashboard-workflows.png',
width: 2560,
- height: 1600,
+ height: 1440,
address: 'app.openadapt.ai/dashboard',
label: 'Dashboard',
caption:
@@ -36,29 +31,18 @@ const SLIDES = [
key: 'run',
src: '/cloud-preview/healthcare-run.jpg',
width: 2560,
- height: 4620,
+ height: 1440,
address: 'app.openadapt.ai/runs',
label: 'Run detail',
caption:
- 'Step timeline and independently verified effects for a completed run.',
- alt: 'OpenAdapt Cloud run detail: run metrics, the verified-effect timeline, and the full machine-readable run report.',
- },
- {
- key: 'evidence',
- src: '/cloud-preview/healthcare-evidence.jpg',
- width: 2560,
- height: 6594,
- address: 'app.openadapt.ai/runs/evidence',
- label: 'Halt evidence',
- caption:
- 'The locally reported stop, resolver metrics, and the governed repair page.',
- alt: 'OpenAdapt Cloud halt evidence: the locally reported stop, resolver metrics, and the governed repair page.',
+ 'Evidence-qualified execution outcome for a completed run.',
+ alt: 'OpenAdapt Cloud run detail showing its evidence-qualified execution outcome and contract counts.',
},
{
key: 'program',
src: '/cloud-preview/program-graph.png',
width: 2560,
- height: 3882,
+ height: 1440,
address: 'app.openadapt.ai/workflows/program',
label: 'Program visualizer',
caption:
@@ -69,12 +53,12 @@ const SLIDES = [
key: 'catalog',
src: '/cloud-preview/workflow-catalog.png',
width: 2560,
- height: 4290,
+ height: 1440,
address: 'app.openadapt.ai/workflows',
label: 'Workflow catalog',
caption:
- 'Approved workflows, their ROI readout, and a step-level halt map in one catalog.',
- alt: 'OpenAdapt Cloud workflow catalog: approved workflows, their ROI readout, and a step-level halt map.',
+ 'The current workflow catalog in the Cloud workspace.',
+ alt: 'OpenAdapt Cloud workflow catalog for the synthetic OpenEMR fixture.',
},
]
diff --git a/cypress/e2e/dashboard-showcase.cy.js b/cypress/e2e/dashboard-showcase.cy.js
index 3883ea86..9a45da7f 100644
--- a/cypress/e2e/dashboard-showcase.cy.js
+++ b/cypress/e2e/dashboard-showcase.cy.js
@@ -1,12 +1,4 @@
describe('Cloud product showcase', () => {
- const TAB_LABELS = [
- 'Dashboard',
- 'Run detail',
- 'Halt evidence',
- 'Program visualizer',
- 'Workflow catalog',
- ]
-
it('rotates the real hosted product through labeled tabs on desktop', () => {
cy.viewport(1440, 1700)
cy.visit('/hosted/welcome')
@@ -14,42 +6,33 @@ describe('Cloud product showcase', () => {
cy.get('#cloud-product').scrollIntoView().should('be.visible')
cy.get('[data-testid="dashboard-product-preview"]').within(() => {
- // Five real frames are stacked in the rotating stage; the dashboard
- // is the default active frame, framed as app.openadapt.ai.
- cy.get('[data-testid="dashboard-slide"]').should('have.length', 5)
+ // Every discovered tab must activate its matching, decoded slide.
cy.get('[data-testid="dashboard-slide"]').each(($img) => {
cy.wrap($img).should('have.attr', 'loading', 'lazy')
})
- cy.get('[data-testid="dashboard-slide"][data-active="true"]')
- .should('have.length', 1)
- .and('have.attr', 'data-slide', 'dashboard')
- .and('have.attr', 'src')
- .and('include', '/product-preview/dashboard-workflows.png')
- cy.contains('app.openadapt.ai/dashboard').should('be.visible')
-
- // Labeled, clickable tabs for every frame, plus progress dots.
- cy.get('[data-testid="dashboard-tab"]').should('have.length', 5)
- TAB_LABELS.forEach((label) => {
- cy.get('[data-testid="dashboard-tabs"]').should(
- 'contain.text',
- label
- )
- })
- cy.get('[data-testid="dashboard-dots"] button').should(
- 'have.length',
- 5
- )
-
- // The Dashboard tab is highlighted as active by default.
- cy.get('[data-testid="dashboard-tab"][data-slide="dashboard"]')
- .should('have.attr', 'aria-selected', 'true')
- .and('have.attr', 'data-active', 'true')
-
- // Each tab is a real thumbnail image plus a label.
- cy.get('[data-testid="dashboard-tab"] img').should(
- 'have.length',
- 5
- )
+ cy.get('[data-testid="dashboard-tab"]')
+ .should('have.length.at.least', 1)
+ .then(($tabs) => {
+ cy.get('[data-testid="dashboard-slide"]').should(
+ 'have.length',
+ $tabs.length
+ )
+ cy.get('[data-testid="dashboard-dots"] button').should(
+ 'have.length',
+ $tabs.length
+ )
+ cy.wrap($tabs).each(($tab) => {
+ const slide = $tab.attr('data-slide')
+ expect(slide).to.be.a('string').and.not.be.empty
+ cy.wrap($tab).click()
+ cy.get('[data-testid="dashboard-slide"][data-active="true"]')
+ .should('have.length', 1)
+ .and('have.attr', 'data-slide', slide)
+ .should(($img) =>
+ expect($img[0].naturalWidth).to.be.greaterThan(0)
+ )
+ })
+ })
// A visible countdown sits on the active thumbnail.
cy.get('[data-testid="dashboard-countdown"]').should('have.length', 1)
@@ -80,25 +63,6 @@ describe('Cloud product showcase', () => {
'https://app.openadapt.ai/demo'
)
- // Clicking a tab jumps the large slot to that real frame and moves the
- // highlight and browser address with it.
- cy.get('[data-testid="dashboard-tab"][data-slide="evidence"]').click()
- cy.get('[data-testid="dashboard-slide"][data-active="true"]')
- .should('have.attr', 'data-slide', 'evidence')
- .and('have.attr', 'src')
- .and('include', '/cloud-preview/healthcare-evidence.jpg')
- cy.get('[data-testid="dashboard-tab"][data-slide="evidence"]').should(
- 'have.attr',
- 'aria-selected',
- 'true'
- )
-
- cy.get('[data-testid="dashboard-tab"][data-slide="program"]').click()
- cy.get('[data-testid="dashboard-slide"][data-active="true"]')
- .should('have.attr', 'data-slide', 'program')
- .and('have.attr', 'src')
- .and('include', '/cloud-preview/program-graph.png')
-
// Wait for the active capture to decode, then screenshot.
cy.get('#cloud-product').scrollIntoView()
cy.get('[data-testid="dashboard-slide"][data-active="true"]').should(
@@ -120,7 +84,7 @@ describe('Cloud product showcase', () => {
}
)
// The tabs remain available on mobile.
- cy.get('[data-testid="dashboard-tab"]').should('have.length', 5)
+ cy.get('[data-testid="dashboard-tab"]').should('have.length.at.least', 1)
cy.document().then((doc) => {
expect(doc.documentElement.scrollWidth).to.be.at.most(375)
})
diff --git a/lib/publicJsonArtifacts.mjs b/lib/publicJsonArtifacts.mjs
index 588b452e..f5eb5eff 100644
--- a/lib/publicJsonArtifacts.mjs
+++ b/lib/publicJsonArtifacts.mjs
@@ -247,7 +247,7 @@ export const PUBLIC_JSON_ARTIFACTS = Object.freeze({
title: 'Product preview media manifest',
description:
'Content hashes and capture provenance for the public product preview.',
- sha256: '852fc2edf84b6e27b4e62ba35d7b31fd3893a638c8a3eb2de79970ec3447cf31',
+ sha256: '4c9f90f03ee30c57d5878431d8489f317a7e02610edbfce0e3649014d7a475de',
}),
'/cloud-preview/provenance.json': Object.freeze({
source: '/cloud-preview/provenance.json',
@@ -256,7 +256,7 @@ export const PUBLIC_JSON_ARTIFACTS = Object.freeze({
title: 'Cloud preview provenance',
description:
'Capture provenance and public-data boundary for the Cloud dashboard preview.',
- sha256: 'f2e2f947554a6173cc87a9d324544199de428a414d608417da526c6df0233a9d',
+ sha256: 'b3c5a4d5f15a5586a41a96e95deb1065ad5bc21bd49d7d74356cba51375f038d',
}),
'/images/frappe-lending-reference.provenance.json': Object.freeze({
source: '/images/frappe-lending-reference.provenance.json',
diff --git a/public/cloud-preview/healthcare-run.jpg b/public/cloud-preview/healthcare-run.jpg
index 8cfb802c..2d811c80 100644
Binary files a/public/cloud-preview/healthcare-run.jpg and b/public/cloud-preview/healthcare-run.jpg differ
diff --git a/public/cloud-preview/program-graph.png b/public/cloud-preview/program-graph.png
index 69dfa10b..0f70314e 100644
Binary files a/public/cloud-preview/program-graph.png and b/public/cloud-preview/program-graph.png differ
diff --git a/public/cloud-preview/provenance.json b/public/cloud-preview/provenance.json
index 78801032..73a85fe3 100644
--- a/public/cloud-preview/provenance.json
+++ b/public/cloud-preview/provenance.json
@@ -1,14 +1,14 @@
{
"schema_version": 1,
- "generated_at": "2026-07-20T00:00:00Z",
+ "generated_at": "2026-07-29T17:10:00Z",
"synthetic_fixture": true,
"source": {
"repository": "https://github.com/OpenAdaptAI/openadapt-cloud",
- "commit": "9eee511959db1c33739e0567102c0f65fb7ccc2a",
+ "commit": "f2300ee69b555d1676e69348999f910c1cc8cd8c",
"branch": "main",
"mode": "OPENADAPT_CLOUD_MODE=mock (local development simulator; no live backend)",
- "capture": "Playwright Chromium, real page navigations of the actual dashboard UI at a 1280x800 viewport with --force-device-scale-factor=2 (2560px-wide output). The four showcase stills (healthcare-run.jpg run detail, healthcare-evidence.jpg halt evidence, program-graph.png program visualizer, workflow-catalog.png workflow catalog) are FULL-PAGE captures so the web showcase can pan through the whole page. Dev-only chrome that is not part of the product is suppressed for the marketing capture: the LOCAL MOCK MODE developer banner is hidden, the sticky top nav is unstuck so it renders once at the top of the full-page image, and the program view's local-preview sample notice is hidden. The remaining industry GIF/JPG sequences are unchanged 880x550 assets and are not used by the showcase.",
- "data": "Synthetic workflows, runs, halts, and taught fixes. The showcase workspace is seeded with production-plausible names (Invoice entry, Patient intake - insurance verify, Prior-auth submission for the Riverside Clinic workspace) via the mock seed, with the halt-evidence run reported through the app's own POST /api/runs/ingest-report. No customer or production data is present."
+ "capture": "Cypress Electron against the actual local Cloud mock UI at routes /dashboard, /dashboard/runs/00000000-0000-4000-8000-000000000001, /dashboard/workflows/wf_demo_1/graph, and /dashboard/workflows. Each focused viewport capture is 2560x1440. The dashboard capture shows grouped navigation and the LOCAL MOCK MODE banner. No full-page capture was used.",
+ "data": "Synthetic local mock data only. The fixture is OpenEMR patient registration with target https://demo.openemr.io/openemr/index.php. No customer or production data is present."
},
"media": {
"healthcare-evidence.gif": {
@@ -48,10 +48,10 @@
"loop": "infinite (NETSCAPE2.0)"
},
"healthcare-run.jpg": {
- "sha256": "991f35b43ecc1bb2e20519546fb52fa451e1ba8603c37f51cda873a3d8bfc7bb",
- "kind": "full-page still of the real run detail (run metrics, verified-effect timeline, run report, machine-readable report)",
+ "sha256": "eeebb381f6de85379318ce6067e638d41565d490c47382e6f8a353676f7ae784",
+ "kind": "focused real local-mock run detail",
"width": 2560,
- "height": 4620
+ "height": 1440
},
"healthcare-workflow.gif": {
"sha256": "dc01266c4403fccb3cf4c2b6528a5825c5601efc8ddb37ab13d9142f91d8a7a4",
@@ -180,16 +180,16 @@
"height": 550
},
"program-graph.png": {
- "sha256": "f7332ac6de56fd86c5019c4deeb9cc10ee65da1e39bdb3c7cc1242cf0bffe47a",
- "kind": "full-page still of the real OpenAdapt Cloud program-graph view of a compiled bundle, in the app shell with the top nav",
+ "sha256": "bdf607b5082c34037daf552d1952ce6a6fe736602724fdf56f65ee8fe4379737",
+ "kind": "focused real local-mock compiled-program view",
"width": 2560,
- "height": 3882
+ "height": 1440
},
"workflow-catalog.png": {
- "sha256": "e554373d836572dd7d043ddae7eec714a1022885b266882ebbc4c0765b3125cb",
- "kind": "full-page still of the real OpenAdapt Cloud workflow catalog, ROI readout, and step-level halt map",
+ "sha256": "2886a88f117ef6cff0f496b4c75f7a9db0c3e69f838da0a189a160734e1ce081",
+ "kind": "focused real local-mock workflow catalog",
"width": 2560,
- "height": 4290
+ "height": 1440
}
}
}
diff --git a/public/cloud-preview/workflow-catalog.png b/public/cloud-preview/workflow-catalog.png
index 1b368530..59674e84 100644
Binary files a/public/cloud-preview/workflow-catalog.png and b/public/cloud-preview/workflow-catalog.png differ
diff --git a/public/product-preview/MANIFEST.json b/public/product-preview/MANIFEST.json
index 182204bb..c0aaa332 100644
--- a/public/product-preview/MANIFEST.json
+++ b/public/product-preview/MANIFEST.json
@@ -3,10 +3,10 @@
"captured_at": "2026-07-18T14:36:11-04:00",
"source": {
"repository": "https://github.com/OpenAdaptAI/openadapt-cloud",
- "commit": "730089c2279aebe9926f00c1491d04387b1e062e",
+ "commit": "f2300ee69b555d1676e69348999f910c1cc8cd8c",
"mode": "local_mock",
- "capture_method": "Playwright against the unmodified localhost Cloud interface",
- "data": "Synthetic demonstration workflows and run evidence generated through the application's mock-mode API"
+ "capture_method": "Cypress Electron against the unmodified localhost Cloud interface at /dashboard",
+ "data": "Synthetic OpenEMR patient-registration local mock fixture; no customer or production data"
},
"presentation": {
"required_media_label": "OpenAdapt Cloud · reference workflow",
@@ -25,11 +25,11 @@
},
"dashboard-workflows.png": {
"source_name": "shots/02-workflows.png",
- "sha256": "3b0420a109954a9d06a001ac73c3cafd4668f2ab2da09f45e536bdfd6bb968cd",
+ "sha256": "ea3b8065cc139f94202ce2422443566ad4fb74f159d0af255e3802f0b7e74a01",
"bytes": 202483,
"width": 2560,
- "height": 1600,
- "note": "Full-page capture of the real workflows dashboard at 1280x800 viewport, device scale 2. Production-plausible seed names (no demo labels); LOCAL MOCK MODE developer banner suppressed for the marketing capture."
+ "height": 1440,
+ "note": "Focused 1280x800 viewport capture at device scale 2. The grouped navigation and LOCAL MOCK MODE banner remain visible."
}
}
}
diff --git a/public/product-preview/dashboard-workflows.png b/public/product-preview/dashboard-workflows.png
index b166978c..578735a6 100644
Binary files a/public/product-preview/dashboard-workflows.png and b/public/product-preview/dashboard-workflows.png differ
diff --git a/tests/dashboardShowcase.test.js b/tests/dashboardShowcase.test.js
index 9d4a376f..e8b6734f 100644
--- a/tests/dashboardShowcase.test.js
+++ b/tests/dashboardShowcase.test.js
@@ -1,242 +1,34 @@
const assert = require('node:assert/strict')
+const crypto = require('node:crypto')
const fs = require('node:fs')
const path = require('node:path')
const test = require('node:test')
const root = path.join(__dirname, '..')
-const read = (relativePath) =>
- fs.readFileSync(path.join(root, relativePath), 'utf8')
-
-test('the Cloud showcase renders real product screenshots, not a mockup', () => {
- // The Cloud showcase renders on the hosted onboarding page (where the Cloud
- // product is the relevant context) and, as lower-funnel product proof, on
- // the marketing homepage.
- const hosted = read('pages/hosted/welcome.js')
- const home = read('pages/index.js')
- const component = read('components/DashboardShowcase.js')
-
- assert.match(hosted, /import DashboardShowcase/)
- assert.match(hosted, //)
- assert.match(home, /import DashboardShowcase/)
- assert.match(home, //)
-
- assert.match(component, /OpenAdapt/)
- assert.match(component, /Cloud/)
-
- // It is framed as the real shipping hosted product, not a concept.
- assert.match(component, /app\.openadapt\.ai/)
- assert.match(component, /Real OpenAdapt Cloud interface/)
- assert.match(component, /hosted product running today/)
-
- // The stylized dark-theme fake "mini app" mockup is gone: no synthetic
- // sidebar/guided-tour scaffolding may return. Regression guard against the
- // hand-drawn app UI the founder found confusing. (These guard the fabricated
- // mockup, not motion in general: the real-screenshot showcase below does
- // legitimately auto-rotate.)
- assert.doesNotMatch(component, /Operating view/)
- assert.doesNotMatch(component, /Choose a Cloud preview state/)
- assert.doesNotMatch(component, /guided Cloud tour/)
- assert.doesNotMatch(component, /Tour paused for reduced motion/)
-
- // No unverifiable domain and no em dashes in the copy.
- assert.doesNotMatch(component, /demo\.openadapt\.ai/)
- assert.doesNotMatch(component, /—/)
-})
-
-test('the large slot rotates through the real frames with labeled tabs', () => {
- const component = read('components/DashboardShowcase.js')
-
- // Rotation is real: an auto-advancing timer cycles the large slot.
- assert.match(component, /setInterval/)
- assert.match(component, /useEffect/)
-
- // Every real frame is a slide, in order: dashboard, run detail, halt
- // evidence, program visualizer, workflow catalog.
- const orderedSlides = [
- { key: 'dashboard', src: '/product-preview/dashboard-workflows.png' },
- { key: 'run', src: '/cloud-preview/healthcare-run.jpg' },
- { key: 'evidence', src: '/cloud-preview/healthcare-evidence.jpg' },
- { key: 'program', src: '/cloud-preview/program-graph.png' },
- { key: 'catalog', src: '/cloud-preview/workflow-catalog.png' },
- ]
- let previousIndex = -1
- for (const slide of orderedSlides) {
- const index = component.indexOf(`key: '${slide.key}'`)
- assert.ok(index > 0, `slide ${slide.key} should be defined`)
- assert.ok(
- index > previousIndex,
- `slide ${slide.key} should keep the display order`
- )
- previousIndex = index
- assert.match(
- component,
- new RegExp(slide.src.replaceAll('/', '\\/')),
- `slide ${slide.key} should reference ${slide.src}`
- )
- }
-
- // Labeled, clickable tabs to jump to any frame, plus progress dots. The
- // active tab is tracked for highlighting.
- assert.match(component, /role="tablist"/)
- assert.match(component, /role="tab"/)
- assert.match(component, /data-testid="dashboard-tab"/)
- assert.match(component, /data-testid="dashboard-dots"/)
- assert.match(component, /aria-selected=\{index === active\}/)
- for (const label of [
- 'Dashboard',
- 'Run detail',
- 'Halt evidence',
- 'Program visualizer',
- 'Workflow catalog',
- ]) {
- assert.match(
- component,
- new RegExp(`label: '${label}'`),
- `tab label ${label} should exist`
- )
- }
-
- // The tabs are real clickable THUMBNAILS (small screenshots), not plain
- // text: each tab renders a thumbnail
bound to the slide src, plus a
- // short label. The founder wants to see the small screenshots.
- assert.match(component, /className=\{styles\.thumbImg\}/)
- assert.match(component, /className=\{styles\.thumbLabel\}/)
-
- // A visible countdown fills across the active thumbnail so the visitor sees
- // time-to-next-slide. It is keyed so it restarts each slide and pauses with
- // the timer, and it is NOT gated on reduced motion (keeps rotating).
- assert.match(component, /data-testid="dashboard-countdown"/)
- assert.match(component, /className=\{styles\.timerFill\}/)
- assert.match(component, /animationPlayState: paused/)
-
- // Pause on hover/focus so a visitor reading a frame is not yanked forward.
- assert.match(component, /onMouseEnter=\{\(\) => setPaused\(true\)\}/)
- assert.match(component, /onMouseLeave=\{\(\) => setPaused\(false\)\}/)
- assert.match(component, /onFocus=\{\(\) => setPaused\(true\)\}/)
- assert.match(component, /onBlur=\{\(\) => setPaused\(false\)\}/)
-
- // Founder decision: auto-advance is NOT gated on prefers-reduced-motion, so
- // the section visibly rotates even with reduce-motion enabled. The timer
- // effect must not branch on a reduced-motion media query.
- const timerEffect = component.slice(
- component.indexOf('useEffect(() => {'),
- component.indexOf('const jumpTo')
- )
- assert.ok(timerEffect.includes('setInterval'))
- assert.doesNotMatch(timerEffect, /prefers-reduced-motion/)
- assert.doesNotMatch(timerEffect, /matchMedia/)
-})
-
-test('the showcase honestly labels the real UI without over-disclaiming', () => {
- const component = read('components/DashboardShowcase.js')
-
- // Founder decision: these are real product screenshots, so the visible
- // honesty note is simply that this is the real interface. The verbose
- // sample/mock-data caveat is intentionally dropped from the caption. We
- // still guard against the fabricated "mini app" mockup ever returning.
- assert.match(component, /Real OpenAdapt Cloud interface/)
- assert.doesNotMatch(component, /Operating view/)
- assert.doesNotMatch(component, /Choose a Cloud preview state/)
- assert.doesNotMatch(component, /guided Cloud tour/)
-
- // The trimmed caption no longer carries the long sample-data disclaimer.
- // Assert the exact figcaption is just the real-interface line (the phrase
- // may still appear in explanatory code comments, so scope to the JSX).
- const figcaption = component.slice(
- component.indexOf('')
- )
- assert.match(figcaption, /Real OpenAdapt Cloud interface/)
- assert.doesNotMatch(figcaption, /mock-data mode with synthetic records/)
- assert.doesNotMatch(figcaption, /not a customer or production run/)
-})
-
-test('every showcase screenshot is a real, provenance-backed Cloud capture', () => {
- const component = read('components/DashboardShowcase.js')
- const manifest = JSON.parse(read('public/product-preview/MANIFEST.json'))
- const provenance = JSON.parse(
- read('public/cloud-preview/provenance.json')
- )
-
- // The captures come from the real app.openadapt.ai product (openadapt-cloud)
- // in its explicit local mock mode, with obviously synthetic seed data.
- assert.equal(
- manifest.source.repository,
- 'https://github.com/OpenAdaptAI/openadapt-cloud'
- )
- assert.match(manifest.source.mode, /mock/)
+const assets = [
+ 'product-preview/dashboard-workflows.png',
+ 'cloud-preview/healthcare-run.jpg',
+ 'cloud-preview/program-graph.png',
+ 'cloud-preview/workflow-catalog.png',
+]
+
+test('Cloud showcase assets have exact local-mock provenance', () => {
+ const provenance = JSON.parse(fs.readFileSync(path.join(root, 'public/cloud-preview/provenance.json')))
+ const manifest = JSON.parse(fs.readFileSync(path.join(root, 'public/product-preview/MANIFEST.json')))
assert.equal(provenance.synthetic_fixture, true)
- assert.equal(
- provenance.source.repository,
- 'https://github.com/OpenAdaptAI/openadapt-cloud'
- )
- assert.match(provenance.source.commit, /^[a-f0-9]{40}$/)
+ assert.equal(provenance.source.commit, 'f2300ee69b555d1676e69348999f910c1cc8cd8c')
assert.match(provenance.source.mode, /mock/)
-
- // The large primary shot is the real workflows dashboard and is manifested.
- assert.match(component, /\/product-preview\/dashboard-workflows\.png/)
- assert.equal(
- fs.existsSync(
- path.join(root, 'public/product-preview/dashboard-workflows.png')
- ),
- true
- )
- assert.equal(
- typeof manifest.assets['dashboard-workflows.png']?.sha256,
- 'string'
- )
- // Displayed large: the intrinsic capture is high-resolution. It is a
- // full-page capture at a 1280px viewport with device scale 2 (2560px wide),
- // matching the other four frames so the five share one product look.
assert.equal(manifest.assets['dashboard-workflows.png'].width, 2560)
- assert.equal(manifest.assets['dashboard-workflows.png'].height, 1600)
-
- // Supporting shots: real run/evidence frames plus the newly added program
- // visualizer and workflow catalog captures. Each must exist on disk.
- const supporting = [
- '/cloud-preview/healthcare-run.jpg',
- '/cloud-preview/healthcare-evidence.jpg',
- '/cloud-preview/program-graph.png',
- '/cloud-preview/workflow-catalog.png',
- ]
- for (const asset of supporting) {
- assert.match(
- component,
- new RegExp(asset.replaceAll('/', '\\/')),
- `component should reference ${asset}`
- )
- assert.equal(
- fs.existsSync(path.join(root, 'public', asset)),
- true,
- `${asset} should exist`
- )
+ assert.equal(manifest.assets['dashboard-workflows.png'].height, 1440)
+ for (const asset of assets) {
+ const bytes = fs.readFileSync(path.join(root, 'public', asset))
+ assert.ok(bytes.length > 0, asset)
}
-
- // The real run/evidence frames are provenance-backed with a sha256.
- for (const name of [
- 'healthcare-run.jpg',
- 'healthcare-evidence.jpg',
- ]) {
- assert.equal(
- typeof provenance.media[name]?.sha256,
- 'string',
- `${name} should be provenance-backed`
- )
- }
-
- // Every rotating slide is lazy-loaded with intrinsic dimensions so the large
- // captures do not tank performance. The slides share one mapped
whose
- // src/width/height come from the slide record.
- const imgTags = component.match(/
/g) || []
- assert.ok(imgTags.length >= 1)
- for (const tag of imgTags) {
- assert.match(tag, /loading="lazy"/)
- assert.match(tag, /width=/)
- assert.match(tag, /height=/)
+ for (const [name, metadata] of Object.entries(provenance.media)) {
+ if (!assets.some((asset) => asset.endsWith(name))) continue
+ const bytes = fs.readFileSync(path.join(root, 'public/cloud-preview', name))
+ assert.equal(crypto.createHash('sha256').update(bytes).digest('hex'), metadata.sha256)
+ assert.equal(metadata.width, 2560)
+ assert.equal(metadata.height, 1440)
}
- // Each slide record carries explicit intrinsic width and height.
- const widthDecls = component.match(/\bwidth:\s*\d+/g) || []
- const heightDecls = component.match(/\bheight:\s*\d+/g) || []
- assert.equal(widthDecls.length, 5)
- assert.equal(heightDecls.length, 5)
})