Files
open-design/e2e/cases/index.ts
T
Zakaria a46764fb1b
ci / Validate workspace (push) Has been cancelled
landing-page-ci / Validate landing page (push) Has been cancelled
landing-page-deploy / Deploy landing page (push) Has been cancelled
github-metrics / Generate repository metrics SVG (push) Has been cancelled
refresh-contributors-wall / Refresh contributors wall cache bust (push) Waiting to run
first-commit
2026-05-04 14:58:14 -04:00

406 lines
15 KiB
TypeScript

import type { UICase } from './types';
export const uiCases: UICase[] = [
{
id: 'prototype-basic',
title: 'Prototype project creates and previews a generated artifact',
kind: 'prototype',
flow: 'standard',
automated: true,
description:
'Validates the primary happy path: create a prototype project, send one prompt, persist the generated HTML, and render it in the preview iframe.',
create: {
projectName: 'UI automation smoke',
tab: 'prototype',
},
prompt: 'Create a small test artifact',
mockArtifact: {
identifier: 'mock-artifact',
title: 'Mock Artifact',
fileName: 'mock-artifact.html',
heading: 'Mock Artifact',
html:
'<!doctype html><html><body><main><h1>Mock Artifact</h1><p>Generated by Playwright.</p></main></body></html>',
},
notes: [
'This is the seed smoke test and should stay fast.',
'It uses mocked SSE so the UI path stays deterministic.',
],
},
{
id: 'deck-basic',
title: 'Deck project renders a mocked slide artifact',
kind: 'deck',
flow: 'standard',
automated: true,
description:
'Covers the deck tab in project creation and verifies that a deck artifact lands in the workspace preview.',
create: {
projectName: 'Deck automation smoke',
tab: 'deck',
},
prompt: 'Create a short deck with two slides',
mockArtifact: {
identifier: 'mock-deck',
title: 'Mock Deck',
fileName: 'mock-deck.html',
heading: 'Mock Deck',
html:
'<!doctype html><html><body><section class="slide"><h1>Mock Deck</h1></section></body></html>',
},
notes: [
'Confirms the deck creation tab still routes into the same generation path.',
],
},
{
id: 'comment-attachment-flow',
title: 'Preview comments attach to chat and send as structured context',
kind: 'prototype',
flow: 'comment-attachment-flow',
automated: true,
description:
'Exercises V1 comment mode: save a latest element comment, attach/remove it from the composer, and send it as an empty visible prompt with structured comment context.',
create: {
projectName: 'Comment attachment flow',
tab: 'prototype',
},
prompt: 'Create a commentable preview artifact',
mockArtifact: {
identifier: 'commentable-artifact',
title: 'Commentable Artifact',
fileName: 'commentable-artifact.html',
heading: 'Prototype headline',
html:
'<!doctype html><html><body><main data-od-id="hero-section"><h1 data-od-id="hero-title" data-screen-label="Hero title">Prototype headline</h1><p data-od-id="hero-copy">Preview copy for comment mode.</p></main></body></html>',
},
notes: [
'The composer textarea stays empty; selected preview comments are sent through commentAttachments.',
],
},
{
id: 'design-system-selection',
title: 'Selecting a design system carries through project creation',
kind: 'prototype',
flow: 'design-system-selection',
automated: true,
description:
'Verifies that a chosen design system is selectable in the new-project panel and remains visible in project metadata after creation.',
create: {
projectName: 'Design system selection',
tab: 'prototype',
},
prompt: 'Create a small test artifact',
notes: [
'Uses a mocked design-system list so the picker stays deterministic across environments.',
'Focuses on creation and metadata persistence instead of generation output.',
],
},
{
id: 'example-use-prompt',
title: 'Using an example prompt creates a project with a seeded draft',
kind: 'prototype',
flow: 'example-use-prompt',
automated: true,
description:
'Verifies the Examples tab fast path: click Use this prompt, create a project immediately, and carry the example prompt into the chat composer.',
create: {
projectName: 'Example prompt project',
tab: 'prototype',
},
prompt: 'Draft a warm utility landing page for a productivity app',
notes: [
'Uses a mocked skills list so the examples gallery stays deterministic.',
'Targets the pendingPrompt fast-create path instead of the standard new-project form.',
],
},
{
id: 'conversation-persistence',
title: 'Conversation history survives refresh and switching',
kind: 'workspace',
flow: 'conversation-persistence',
automated: true,
description:
'Exercises conversation creation, persistence, refresh reload, and switching between threads in one project.',
create: {
projectName: 'Conversation persistence',
tab: 'prototype',
},
prompt: 'Create a small test artifact',
secondaryPrompt: 'Create another artifact in a fresh conversation',
mockArtifact: {
identifier: 'mock-artifact',
title: 'Mock Artifact',
fileName: 'mock-artifact.html',
heading: 'Mock Artifact',
html:
'<!doctype html><html><body><main><h1>Mock Artifact</h1><p>Generated by Playwright.</p></main></body></html>',
},
notes: [
'Should use the same mock SSE flow as the prototype smoke path.',
'Reload should keep the original conversation content available from the history menu.',
],
},
{
id: 'file-mention',
title: 'Uploaded files can be mentioned and sent back to the agent',
kind: 'workspace',
flow: 'file-mention',
automated: true,
description:
'Validates the upload, staged attachment, and @ mention flow inside the chat composer.',
create: {
projectName: 'File mention flow',
tab: 'prototype',
},
prompt: 'Review @reference.txt and use it as context',
notes: [
'Seeds a tiny text fixture through the project file API, then exercises the composer mention flow.',
],
},
{
id: 'deep-link-preview',
title: 'Deep-linking to a file route opens the expected preview tab',
kind: 'workspace',
flow: 'deep-link-preview',
automated: true,
description:
'Verifies that /projects/:id/files/:name restores the matching open tab and preview frame after navigation or refresh.',
create: {
projectName: 'Deep link preview',
tab: 'prototype',
},
prompt: 'Create a small test artifact',
mockArtifact: {
identifier: 'mock-artifact',
title: 'Mock Artifact',
fileName: 'mock-artifact.html',
heading: 'Mock Artifact',
html:
'<!doctype html><html><body><main><h1>Mock Artifact</h1><p>Generated by Playwright.</p></main></body></html>',
},
notes: [
'Can reuse the generated HTML from prototype-basic, then revisit with a routed URL.',
],
},
{
id: 'file-upload-send',
title: 'Composer file picker uploads a file and sends it with the prompt',
kind: 'workspace',
flow: 'file-upload-send',
automated: true,
description:
'Exercises the real attach button and hidden file input, then verifies the staged file is sent and shown back on the user message.',
create: {
projectName: 'File upload send flow',
tab: 'prototype',
},
prompt: 'Use the uploaded reference as context',
notes: [
'Uses Playwright setInputFiles on the hidden composer picker instead of seeding through the API.',
],
},
{
id: 'design-files-upload',
title: 'Design Files panel uploads an image and opens it in the workspace',
kind: 'workspace',
flow: 'design-files-upload',
automated: true,
description:
'Exercises the Design Files upload flow in the workspace, then verifies the uploaded image can be previewed and opened as a tab.',
create: {
projectName: 'Design files upload flow',
tab: 'prototype',
},
prompt: 'Upload an image through the design files browser',
notes: [
'Uses the FileWorkspace upload input rather than the chat composer upload path.',
],
},
{
id: 'design-files-delete',
title: 'Design Files panel deletes an uploaded file and clears its tab',
kind: 'workspace',
flow: 'design-files-delete',
automated: true,
description:
'Uploads a file through the Design Files panel, deletes it from the row menu, and verifies it disappears from both the list and open tabs.',
create: {
projectName: 'Design files delete flow',
tab: 'prototype',
},
prompt: 'Delete an uploaded image through the design files browser',
notes: [
'Builds on the same workspace file flow as design-files-upload, then verifies cleanup behavior.',
],
},
{
id: 'design-files-tab-persistence',
title: 'Open file tabs survive refresh with the correct active tab',
kind: 'workspace',
flow: 'design-files-tab-persistence',
automated: true,
description:
'Uploads multiple files through the Design Files flow, switches the active tab, reloads the page, and verifies both the tab set and selected tab are restored.',
create: {
projectName: 'Design files tab persistence',
tab: 'prototype',
},
prompt: 'Restore open file tabs after refresh',
notes: [
'Covers the persisted tabs state stored by ProjectView and restored by FileWorkspace.',
],
},
{
id: 'conversation-delete-recovery',
title: 'Deleting the active conversation falls back cleanly',
kind: 'workspace',
flow: 'conversation-delete-recovery',
automated: true,
description:
'Creates multiple conversations, deletes the active one, and verifies the UI falls back to the remaining thread instead of getting stuck.',
create: {
projectName: 'Conversation delete recovery',
tab: 'prototype',
},
prompt: 'Create a small test artifact',
secondaryPrompt: 'Create another artifact before deleting this thread',
mockArtifact: {
identifier: 'mock-artifact',
title: 'Mock Artifact',
fileName: 'mock-artifact.html',
heading: 'Mock Artifact',
html:
'<!doctype html><html><body><main><h1>Mock Artifact</h1><p>Generated by Playwright.</p></main></body></html>',
},
notes: [
'Confirms the project still has a live conversation after deleting the current thread.',
],
},
{
id: 'question-form-selection-limit',
title: 'Question form checkbox limits block selecting more than the allowed maximum',
kind: 'workspace',
flow: 'question-form-selection-limit',
automated: true,
description:
'Verifies that a discovery-style checkbox question with maxSelections=2 cannot be pushed past two selected options.',
create: {
projectName: 'Question form selection limit',
tab: 'prototype',
},
prompt: 'Help me plan a restaurant homepage',
notes: [
'Mocks a question-form response instead of an artifact so the test can exercise the inline clarifying UI.',
'Confirms both the interaction guard and the rendered checked state stay capped at two options.',
],
},
{
id: 'question-form-submit-persistence',
title: 'Question form answers persist into chat history and reload in a locked state',
kind: 'workspace',
flow: 'question-form-submit-persistence',
automated: true,
description:
'Verifies that answering a question form writes a user follow-up message, then rehydrates the form in an answered and locked state after reload.',
create: {
projectName: 'Question form submit persistence',
tab: 'prototype',
},
prompt: 'Plan a small restaurant homepage',
notes: [
'Mocks an inline question form on the first assistant turn and a plain acknowledgment on the follow-up turn.',
'Confirms the answered state survives a full page reload instead of relying only on local submit state.',
],
},
{
id: 'generation-does-not-create-extra-file',
title: 'Generated artifacts stay stable when no new prompt is sent',
kind: 'workspace',
flow: 'generation-does-not-create-extra-file',
automated: true,
description:
'Generates one HTML artifact, then verifies reload and idle time do not create any additional project files without a new user prompt.',
create: {
projectName: 'No extra generated file',
tab: 'prototype',
},
prompt: 'Create one landing page artifact',
mockArtifact: {
identifier: 'stable-artifact',
title: 'Stable Artifact',
fileName: 'stable-artifact.html',
heading: 'Stable Artifact',
html:
'<!doctype html><html><body><main><h1>Stable Artifact</h1><p>Only one file should exist.</p></main></body></html>',
},
notes: [
'Targets the trust-sensitive bug where a project can appear to generate a fresh file on its own.',
'Uses the files API after reload to assert the project file set is unchanged.',
],
},
{
id: 'deck-pagination-next-prev-correctness',
title: 'Deck preview previous and next controls move in the correct direction',
kind: 'deck',
flow: 'deck-pagination-next-prev-correctness',
automated: false,
description:
'Should verify that deck preview pagination moves to the actual previous and next slide instead of routing both actions to the same page.',
create: {
projectName: 'Deck pagination controls',
tab: 'deck',
},
prompt: 'Review pagination behavior in a multi-slide deck preview',
},
{
id: 'deck-pagination-per-file-isolated',
title: 'Each HTML deck tab preserves its own pagination state',
kind: 'deck',
flow: 'deck-pagination-per-file-isolated',
automated: false,
description:
'Should verify that switching between multiple deck HTML files does not leak page position across tabs or reset both files to page 1.',
create: {
projectName: 'Deck pagination isolation',
tab: 'deck',
},
prompt: 'Keep pagination state isolated per generated deck file',
},
{
id: 'uploaded-image-renders-in-preview',
title: 'Uploaded reference images render correctly in generated deck preview',
kind: 'workspace',
flow: 'uploaded-image-renders-in-preview',
automated: false,
description:
'Should verify that uploaded images resolve to loadable src paths inside generated HTML instead of rendering as broken images.',
create: {
projectName: 'Uploaded image preview render',
tab: 'prototype',
},
prompt: 'Use uploaded brand images inside a generated deck preview',
},
{
id: 'python-source-preview',
title: 'Python files should open with a readable inline source preview',
kind: 'workspace',
flow: 'python-source-preview',
automated: false,
description:
'Should verify that opening a .py file in the main workspace renders a readable source/code preview instead of an unsupported blank state.',
create: {
projectName: 'Python source preview',
tab: 'prototype',
},
prompt: 'Open a generated Python file and inspect its source inline',
notes: [
'Candidate follow-up to the Python preview gap in the file viewer.',
'Likely automation shape: seed a .py file through the project files API, open it, and assert the viewer renders code text.',
],
},
];
export function automatedCases(): UICase[] {
return uiCases.filter((entry) => entry.automated);
}