Skip to content

feat: route-based demo lab + Playwright setup for Copilot cloud agent #5

@L03TJ3

Description

@L03TJ3

Context

examples/react-web is already a working Vite + React + RN-web app on port 3000. It currently renders a single monolithic OverrideShowcase page with 5 tabs (Default / Tokens / Component / Host / Inline). It is the correct base for a full demo environment.

However, it currently has no routing, no per-component demo pages, no stable test selectors (data-testid), no Playwright config, and no .github/workflows/copilot-setup-steps.yml to bootstrap the environment in Copilot cloud agent.

This issue tracks making examples/react-web a complete, Playwright-compatible demo lab for all GoodWidget components and widget flows.

Origin: This issue was shaped by a Copilot cloud agent planning session. See the conversation that produced this plan — specifically the research summary, gap analysis, and the decision to go route-based rather than Storybook.


Decision: route-based demo app, not Storybook

Storybook is not recommended for this repo at this time. Reasons:

  • The Vite + RN-web + Tamagui stack already works in examples/react-web.
  • Storybook requires its own bundler config, story format, custom decorators for GoodWidgetProvider/TamaguiProvider, and significant effort to get RN-web aliasing right — none of which adds value over a well-structured route tree.
  • Route-based pages serve both human reviewers and Playwright identically.
  • Storybook can be revisited later as an additional layer if component isolation feedback requires it.

Wagmi mocked flows

Wallet-connected flows are an important part of GoodWidget's component surface. The demo environment must support wagmi mocked flows wherever a component or feature flow meaningfully requires wallet state to be useful or reviewable.

Concretely:

  • Use @wagmi/core mock connector or a lightweight in-process mock to provide a simulated connected account and chain for demo pages that render wallet-aware components (WalletInfo, AddressDisplay, ChainBadge, ClaimWidget, etc.).
  • Demo pages that do not need wallet state remain simple — no mock needed.
  • Demo pages that do need wallet state should set up the mock connector at the route level (not globally), so other routes are unaffected.
  • The mock should provide a stable address and chain ID so Playwright screenshots are deterministic and repeatable.
  • The wagmi mock is for demo and review purposes only — it does not need to simulate real transaction signing, only enough state for components to render in a connected state.

This is not about E2E testing real wallet interactions. It is about making the demo environment honest: if a component only makes sense when a wallet is connected, the demo should show it connected.


Scope

Phase 1 — Routing scaffold (examples/react-web)

  • Add react-router-dom to examples/react-web/package.json.
  • Replace the single-page root with a React Router tree:
    • / — index page: link grid to all demo routes
    • /components/:name — per-primitive demo pages for each component exported from packages/ui:
      • Button, Input, Alert, Badge, Spinner, Select, Checkbox, Switch, Separator, Card, GlowCard, Heading, Text, WalletInfo, TokenAmount, AddressDisplay, ChainBadge, Toast, ActionSheet, Drawer
    • /widget/claim — ClaimWidget full-flow demo (preset default + override examples inline)
    • /theme-overrides — the existing OverrideShowcase promoted to a dedicated route (keep all 5 existing tabs: Default / Tokens / Component / Host / Inline)
  • Each component page uses MiniAppShell as the frame, renders the component in realistic usage, and includes a readable code snippet showing the minimal usage.
  • Wallet-aware component pages (WalletInfo, AddressDisplay, ChainBadge, ClaimWidget) use the wagmi mock connector so they render in a connected state.

Phase 2 — Stable selectors

  • Add data-testid attributes to key interactive elements in the component demo pages.
  • Naming convention: data-testid="[ComponentName]-[variant|state]" (e.g. data-testid="Button-primary", data-testid="Alert-error", data-testid="ClaimWidget-action").
  • Add testids to:
    • The primary action button in ClaimWidget
    • The tab bar buttons in /theme-overrides
    • One representative element per component demo page

Phase 3 — Playwright configuration

  • Add playwright.config.ts at the repo root:
    // baseURL: 'http://localhost:3000'
    // projects: [{ name: 'chromium' }]
    // screenshot: 'on'
    // trace: 'on-first-retry'
    // video: 'retain-on-failure'
    // webServer: { command: 'pnpm --filter @goodwidget/example-react-web dev', url: 'http://localhost:3000', reuseExistingServer: true }
  • Add tests/demo/ directory with smoke tests:
    • Navigate to each /components/:name route → assert key element visible by testid → screenshot
    • Navigate to /theme-overrides → cycle all 5 tabs → screenshot each tab
    • Navigate to /widget/claim → assert ClaimWidget renders in mocked-connected state
  • Add "test:demo": "playwright test tests/demo" to root package.json scripts.

Phase 4 — Cloud agent bootstrap

  • Add .github/workflows/copilot-setup-steps.yml:
    steps:
      - name: Enable corepack
        run: corepack enable && corepack prepare pnpm@9.15.0 --activate
      - name: Install dependencies
        run: pnpm install
      - name: Build packages
        run: pnpm build
      - name: Install Playwright browsers
        run: pnpm exec playwright install chromium --with-deps
  • This ensures the demo app can be started immediately in a cloud-agent task with:
    pnpm --filter @goodwidget/example-react-web dev
    
    which starts on http://localhost:3000 as already configured.

Phase 5 — Documentation

  • Add docs/demo-environment.md covering:
    • How to start the demo app
    • How to run Playwright smoke tests
    • Route map and what each route shows
    • data-testid naming convention
    • Which routes use the wagmi mock connector and why
    • How cloud agents should start and interact with the demo

Non-goals

  • Storybook (not needed now)
  • E2E tests for real wallet/chain interactions (on-chain signing, live RPC calls — the mock covers demo needs)
  • Expo or HTML example automation (focus is examples/react-web only)
  • CI that runs Playwright on every push (demo tests are for agent/manual use; can be added incrementally)
  • Adding new components (this is infrastructure, not component authoring)

Acceptance criteria

  • examples/react-web has React Router with /, /components/:name, /widget/claim, /theme-overrides routes
  • Each component exported from packages/ui has at least one dedicated demo page under /components/:name
  • /theme-overrides renders the existing 5-tab OverrideShowcase unchanged in behavior
  • Wallet-aware demo pages (WalletInfo, AddressDisplay, ChainBadge, ClaimWidget) render in a visibly connected state using a wagmi mock connector with a stable address and chain ID
  • Key interactive elements have data-testid attributes following the naming convention
  • playwright.config.ts exists at repo root targeting localhost:3000, with screenshot + trace + optional video
  • tests/demo/ contains smoke tests that pass with pnpm test:demo
  • .github/workflows/copilot-setup-steps.yml exists with pnpm install + build + playwright browser install steps
  • docs/demo-environment.md documents how to start the demo and run tests, including which pages use the wagmi mock
  • Playwright MCP can navigate to each route via http://localhost:3000 and take screenshots without errors
  • No changes to packages/ui, packages/core, packages/claim-widget, or packages/embed source — demo layer only

Playwright / cloud-agent compatibility requirements

  • The demo server MUST run on localhost:3000 (already configured in vite.config.ts with --port 3000).
  • Playwright webServer config must use reuseExistingServer: true so agents can pre-start the server or let Playwright start it.
  • All routes must be client-side rendered (no SSR) — Vite SPA mode is already correct.
  • Screenshots and traces must be written to test-results/ (gitignored).
  • The wagmi mock connector must produce a stable, deterministic address and chain ID so screenshots are repeatable across runs.

Incremental delivery order

  1. Phase 4 (copilot-setup-steps.yml) — unblocks cloud agent tasks immediately
  2. Phase 1 (routing + wagmi mock scaffold) — unblocks per-component navigation
  3. Phase 2 (testids) — unblocks stable Playwright selectors
  4. Phase 3 (Playwright config + smoke tests) — closes the loop
  5. Phase 5 (docs) — last, after everything else works

Planning context

This issue was created from a Copilot cloud agent session on 2026-04-23. The session covered:

  • Full repo exploration (monorepo layout, examples/react-web, packages/ui component surface, packages/core provider, absence of .github/)
  • Gap analysis (no routing, no testids, no Playwright, no cloud-agent bootstrap)
  • Route-based vs Storybook decision (route-based chosen; reasons documented above)
  • 5-phase delivery plan
  • This update adds wagmi mocked flows as an explicit in-scope requirement based on follow-up clarification that wallet-connected demo states are needed wherever components require them.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

Status

In Review

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions