diff --git a/components/DashboardShowcase.js b/components/DashboardShowcase.js index 16f5d440..82dd01fd 100644 --- a/components/DashboardShowcase.js +++ b/components/DashboardShowcase.js @@ -19,6 +19,7 @@ const SLIDES = [ { key: 'dashboard', src: '/product-preview/dashboard-workflows.png', + thumbnailSrc: '/cloud-preview/thumbs/dashboard.webp', width: 2560, height: 1440, address: 'app.openadapt.ai/dashboard', @@ -30,6 +31,7 @@ const SLIDES = [ { key: 'run', src: '/cloud-preview/healthcare-run.jpg', + thumbnailSrc: '/cloud-preview/thumbs/run-detail.webp', width: 2560, height: 1440, address: 'app.openadapt.ai/runs', @@ -41,6 +43,7 @@ const SLIDES = [ { key: 'program', src: '/cloud-preview/program-graph.png', + thumbnailSrc: '/cloud-preview/thumbs/program-graph.webp', width: 2560, height: 1440, address: 'app.openadapt.ai/workflows/program', @@ -52,6 +55,7 @@ const SLIDES = [ { key: 'catalog', src: '/cloud-preview/workflow-catalog.png', + thumbnailSrc: '/cloud-preview/thumbs/workflow-catalog.webp', width: 2560, height: 1440, address: 'app.openadapt.ai/workflows', @@ -284,27 +288,18 @@ export default function DashboardShowcase() { onClick={() => jumpTo(index)} > - {index === active || index === nextIndex ? ( - - ) : ( - - )} + {index === active && ( { .should('have.length', 1) .and('have.attr', 'loading', 'lazy') + // The rail uses four small derivatives. It must never replace + // inactive previews with empty numbered placeholders merely to + // preserve the two-image full-resolution stage budget. + cy.get('[data-testid="dashboard-thumbnail"]') + .should('have.length', 4) + .each(($img) => { + expect($img.attr('src')).to.match( + /^\/cloud-preview\/thumbs\/.+\.webp$/ + ) + cy.wrap($img).should(($thumbnail) => + expect($thumbnail[0].naturalWidth).to.be.greaterThan(0) + ) + }) + // Every discovered tab must activate its matching, decoded slide. cy.get('[data-testid="dashboard-tab"]') .should('have.length.at.least', 1) diff --git a/public/cloud-preview/thumbs/dashboard.webp b/public/cloud-preview/thumbs/dashboard.webp new file mode 100644 index 00000000..41c840ae Binary files /dev/null and b/public/cloud-preview/thumbs/dashboard.webp differ diff --git a/public/cloud-preview/thumbs/program-graph.webp b/public/cloud-preview/thumbs/program-graph.webp new file mode 100644 index 00000000..957a8976 Binary files /dev/null and b/public/cloud-preview/thumbs/program-graph.webp differ diff --git a/public/cloud-preview/thumbs/run-detail.webp b/public/cloud-preview/thumbs/run-detail.webp new file mode 100644 index 00000000..c939af9d Binary files /dev/null and b/public/cloud-preview/thumbs/run-detail.webp differ diff --git a/public/cloud-preview/thumbs/workflow-catalog.webp b/public/cloud-preview/thumbs/workflow-catalog.webp new file mode 100644 index 00000000..f0474ba0 Binary files /dev/null and b/public/cloud-preview/thumbs/workflow-catalog.webp differ diff --git a/tests/dashboardShowcase.test.js b/tests/dashboardShowcase.test.js index e8b6734f..33499d11 100644 --- a/tests/dashboardShowcase.test.js +++ b/tests/dashboardShowcase.test.js @@ -11,6 +11,12 @@ const assets = [ 'cloud-preview/program-graph.png', 'cloud-preview/workflow-catalog.png', ] +const thumbnails = [ + 'cloud-preview/thumbs/dashboard.webp', + 'cloud-preview/thumbs/run-detail.webp', + 'cloud-preview/thumbs/program-graph.webp', + 'cloud-preview/thumbs/workflow-catalog.webp', +] test('Cloud showcase assets have exact local-mock provenance', () => { const provenance = JSON.parse(fs.readFileSync(path.join(root, 'public/cloud-preview/provenance.json'))) @@ -32,3 +38,14 @@ test('Cloud showcase assets have exact local-mock provenance', () => { assert.equal(metadata.height, 1440) } }) + +test('Cloud showcase keeps all four preview thumbnails lightweight', () => { + let totalBytes = 0 + for (const asset of thumbnails) { + const bytes = fs.readFileSync(path.join(root, 'public', asset)) + totalBytes += bytes.length + assert.equal(bytes.subarray(0, 4).toString('ascii'), 'RIFF', asset) + assert.equal(bytes.subarray(8, 12).toString('ascii'), 'WEBP', asset) + } + assert.ok(totalBytes < 100_000, `${totalBytes} thumbnail bytes`) +})