diff --git a/docs/project/research/current/research-2026-02-01-visual-testing-web-snapshots.md b/docs/project/research/current/research-2026-02-01-visual-testing-web-snapshots.md new file mode 100644 index 00000000..69b02a4e --- /dev/null +++ b/docs/project/research/current/research-2026-02-01-visual-testing-web-snapshots.md @@ -0,0 +1,693 @@ +# Research: Visual Testing and Web Snapshot Strategies for Agentic Development + +**Date:** 2026-02-01 + +**Author:** Claude (with human guidance) + +**Status:** Complete + +## Overview + +This research document explores the landscape of visual testing and web snapshot generation for modern development workflows, with particular focus on: + +1. **Agentic development** - Enabling AI coding agents to generate, review, and iterate on visual web output +2. **PR-based visual review** - Making visual changes easy to review in pull requests +3. **Lightweight automation** - Finding the right balance between capability and complexity +4. **Modern tooling compatibility** - Integration with pnpm, Bun, and modern JavaScript runtimes + +The goal is to establish best practices for projects that need automated visual validation of HTML/web output, particularly in CLI tools, static site generators, and component libraries. + +## Questions to Answer + +1. What are the most effective tools for generating PNG screenshots from HTML? +2. How do different approaches compare in terms of performance, complexity, and rendering fidelity? +3. How can vision models (Claude, GPT-4V) be integrated into visual testing workflows? +4. What are the best practices for integrating visual tests into CI/CD pipelines? +5. How well do these tools work with modern package managers (pnpm) and runtimes (Bun)? + +## Scope + +**Included:** +- HTML-to-PNG conversion tools (headless browsers, wkhtmltoimage, canvas-based) +- Visual regression testing frameworks (Percy, Chromatic, BackstopJS) +- AI vision model integration for automated review +- CI/CD integration patterns (GitHub Actions) +- Modern runtime compatibility (Node.js, Bun, pnpm) + +**Excluded:** +- Native mobile app screenshot testing +- Browser-based visual testing services (only mentioned for context) +- Detailed pricing comparisons of commercial tools + +--- + +## Findings + +### 1. The Markform Approach (This Project) + +In PR #124, we implemented a lightweight visual testing approach for the Fill Record visualization feature: + +**Stack:** +- **wkhtmltoimage** - HTML to PNG conversion using a bundled WebKit engine +- **ImageMagick** - Post-processing optimization (resize, compression) +- **TypeScript/tsx** - Test script execution + +**Implementation:** (`packages/markform/tests/visual/fill-record-visual.ts`) +```typescript +// Generate PNG snapshots if wkhtmltoimage is available +if (hasCommand('wkhtmltoimage')) { + for (const { name } of testCases) { + const htmlPath = join(snapshotDir, `fill-record-${name}.html`); + const pngPath = join(snapshotDir, `fill-record-${name}.png`); + + execSync( + `wkhtmltoimage --width 900 --quality 90 --enable-local-file-access "${htmlPath}" "${pngPath}"`, + { stdio: 'pipe' }, + ); + + // Optimize with ImageMagick if available + if (hasImagemagick) { + execSync(`convert "${pngPath}" -resize 50% -quality 85 "${pngPath}"`, { stdio: 'pipe' }); + } + } +} +``` + +**Pros:** +- Zero JavaScript dependencies for screenshot generation +- Fast execution (~1s per screenshot) +- Works in CI environments without browser installation +- Small output files (~40KB per PNG after optimization) +- Fail-fast error handling with proper exit codes + +**Cons:** +- Limited CSS support (uses legacy Qt WebKit) +- No JavaScript execution in many modes +- Requires system package installation (`apt-get install wkhtmltopdf`) +- Not actively maintained (legacy project) + +--- + +### 2. Headless Browser Approaches + +#### Playwright (Recommended for Most Use Cases) + +Playwright is Microsoft's cross-browser automation library with built-in visual testing support. + +**Key Features:** +- Built-in `toHaveScreenshot()` assertion for visual comparisons +- Cross-browser support (Chromium, Firefox, WebKit) +- Native parallel test execution +- Automatic waiting and deterministic rendering options +- Video recording and tracing for debugging + +**Installation:** +```bash +pnpm add -D @playwright/test +npx playwright install # Downloads browsers +``` + +**Example - Screenshot Generation:** +```typescript +import { test, expect } from '@playwright/test'; + +test('capture fill record visualization', async ({ page }) => { + await page.goto('file:///path/to/fill-record.html'); + + // Wait for content to be stable + await page.waitForLoadState('networkidle'); + + // Full page screenshot + await page.screenshot({ + path: 'snapshots/fill-record.png', + fullPage: true + }); + + // Or use built-in visual comparison + await expect(page).toHaveScreenshot('fill-record.png', { + maxDiffPixelRatio: 0.01, // Allow 1% pixel difference + }); +}); +``` + +**Performance:** ~4.5s average execution time for navigation-heavy scenarios + +**Best For:** +- Projects needing cross-browser visual testing +- Teams already using Playwright for E2E tests +- Complex pages with JavaScript-dependent rendering + +#### Puppeteer (Chrome/Chromium Only) + +Puppeteer is Google's Node.js library for Chrome DevTools Protocol control. + +**Key Features:** +- Tighter Chrome integration +- Slightly faster for short, simple tasks (~30% faster in some benchmarks) +- PDF generation support +- Well-documented, mature ecosystem + +**Installation:** +```bash +pnpm add puppeteer # Includes Chrome download +# or +pnpm add puppeteer-core # BYOB (bring your own browser) +``` + +**Example:** +```typescript +import puppeteer from 'puppeteer'; + +const browser = await puppeteer.launch({ headless: true }); +const page = await browser.newPage(); +await page.setViewport({ width: 900, height: 1200 }); +await page.goto('file:///path/to/page.html'); +await page.screenshot({ path: 'output.png', fullPage: true }); +await browser.close(); +``` + +**Performance:** Fastest for short automation tasks, comparable to Playwright for longer E2E scenarios + +**Best For:** +- Chrome-only testing needs +- Quick automation scripts +- PDF generation workflows + +--- + +### 3. Lightweight/No-Browser Approaches + +#### wkhtmltoimage (Legacy but Functional) + +Uses a bundled Qt WebKit engine for HTML-to-image conversion. + +**Installation:** +```bash +# Debian/Ubuntu +apt-get install wkhtmltopdf + +# macOS +brew install wkhtmltopdf +``` + +**Usage:** +```bash +wkhtmltoimage --width 900 --quality 90 page.html output.png +``` + +**Pros:** Fast, no browser download, works offline +**Cons:** Legacy WebKit (poor modern CSS support), limited JavaScript, not actively maintained + +#### html-to-image (Client-Side) + +Modern fork of dom-to-image with active maintenance. + +```typescript +import { toPng } from 'html-to-image'; + +const dataUrl = await toPng(document.getElementById('container')); +``` + +**Best For:** In-browser screenshot generation, simple DOM elements + +#### dom-to-image + +Converts DOM elements to images via SVG-to-canvas conversion. + +**Limitations:** Basic CSS support, no cross-origin resources + +#### html2canvas + +Popular client-side library that renders HTML to ``. + +```typescript +import html2canvas from 'html2canvas'; + +const canvas = await html2canvas(document.body); +const dataUrl = canvas.toDataURL('image/png'); +``` + +**Limitations:** May not render all CSS properties accurately, browser-only + +--- + +### 4. Visual Regression Testing Frameworks + +#### BackstopJS (Open Source, Self-Hosted) + +Free, open-source visual regression testing with Puppeteer/Playwright support. + +**Configuration:** (`backstop.json`) +```json +{ + "viewports": [ + { "label": "desktop", "width": 1280, "height": 800 } + ], + "scenarios": [ + { + "label": "Fill Record Dashboard", + "url": "file:///path/to/fill-record.html", + "delay": 500 + } + ], + "engine": "playwright" +} +``` + +**Commands:** +```bash +backstop test # Run comparison +backstop approve # Accept current as new baseline +backstop reference # Generate baseline images +``` + +**Pros:** Free, self-hosted, flexible, generates HTML diff reports +**Cons:** No cloud dashboard, requires infrastructure management + +#### Percy (BrowserStack) + +Cloud-based visual testing platform with AI-powered diff detection. + +**Features:** +- Cross-browser rendering in the cloud +- OCR-based text diff handling (reduces false positives) +- CI/CD integrations +- Team collaboration with visual review UI + +**Integration:** +```typescript +import percySnapshot from '@percy/playwright'; + +test('visual test', async ({ page }) => { + await page.goto('/dashboard'); + await percySnapshot(page, 'Dashboard'); +}); +``` + +**Best For:** Teams needing collaborative visual review, cross-browser testing + +#### Chromatic (Storybook-Focused) + +Visual testing platform built by the Storybook maintainers. + +**Best For:** Component libraries, Storybook-based development +**Consideration:** Requires Storybook; less suitable for full-page testing + +--- + +### 5. AI Vision Model Integration + +#### Claude with Puppeteer MCP Server + +Claude Code can use Puppeteer MCP server to capture and review screenshots iteratively. + +**Workflow:** +1. Generate HTML output +2. Capture screenshot via Puppeteer MCP +3. Claude analyzes the screenshot visually +4. Claude suggests code changes based on visual assessment +5. Iterate until visual output matches expectations + +**Example prompt to Claude:** +``` +Take a screenshot of the current page and tell me if the dashboard +layout looks correct. Check for: +- Proper spacing between sections +- Readable font sizes +- Correct color scheme (dark mode support) +- No overlapping elements +``` + +#### GPT-4V for Visual Analysis + +GPT-4V can analyze screenshots for UI issues and provide feedback. + +**Use Cases:** +- Identifying layout problems +- Suggesting design improvements +- Automated accessibility review +- Comparing implementation to design mockups + +**Integration Pattern:** +```typescript +import OpenAI from 'openai'; +import fs from 'fs'; + +const openai = new OpenAI(); + +const image = fs.readFileSync('screenshot.png', { encoding: 'base64' }); + +const response = await openai.chat.completions.create({ + model: 'gpt-4-vision-preview', + messages: [{ + role: 'user', + content: [ + { type: 'text', text: 'Analyze this dashboard screenshot for visual issues.' }, + { type: 'image_url', image_url: { url: `data:image/png;base64,${image}` } } + ] + }] +}); +``` + +#### Claude's Computer Use + +Anthropic's Claude can interact with applications via screenshots and mouse/keyboard control. + +**Capabilities:** +- Take screenshots to understand current state +- Perform mouse clicks, text entry, scrolling +- Execute test scenarios described in natural language + +**Best For:** Full E2E testing with natural language test definitions + +--- + +### 6. CI/CD Integration Patterns + +#### GitHub Actions - Basic Screenshot Artifacts + +```yaml +name: Visual Tests + +on: [push, pull_request] + +jobs: + visual-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install system dependencies + run: sudo apt-get install -y wkhtmltopdf imagemagick + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install dependencies + run: pnpm install + + - name: Generate visual snapshots + run: pnpm tsx tests/visual/fill-record-visual.ts + + - name: Upload snapshots + uses: actions/upload-artifact@v4 + with: + name: visual-snapshots + path: tests/visual/snapshots/ +``` + +#### GitHub Actions - Playwright with Visual Comparison + +```yaml +name: Playwright Visual Tests + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install dependencies + run: pnpm install + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + + - name: Run visual tests + run: npx playwright test --project=chromium + + - name: Upload diff report + if: failure() + uses: actions/upload-artifact@v4 + with: + name: playwright-report + path: playwright-report/ +``` + +#### Sentry's Visual Snapshot Action + +The `getsentry/action-visual-snapshot` action automates diff generation: + +```yaml +- uses: getsentry/action-visual-snapshot@v2 + with: + snapshot-path: tests/visual/snapshots + diff-path: tests/visual/diffs +``` + +#### Percy CI Integration + +```yaml +- name: Percy Visual Test + run: npx percy exec -- npx playwright test + env: + PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }} +``` + +--- + +### 7. Modern Runtime Compatibility + +#### pnpm Compatibility + +| Tool | pnpm Support | Notes | +|------|-------------|-------| +| Playwright | Excellent | `pnpm add @playwright/test` works perfectly | +| Puppeteer | Excellent | `pnpm add puppeteer` with browser download | +| BackstopJS | Good | May need `pnpm add -D backstopjs` | +| wkhtmltoimage | N/A | System package, not npm | + +#### Bun Compatibility + +| Tool | Bun Support | Notes | +|------|-------------|-------| +| Playwright | Partial | [Known issues](https://github.com/oven-sh/bun/issues/23826) with Chromium launch | +| Puppeteer | Good | `bun add puppeteer` works, ~12% faster than pnpm | +| html-to-image | Good | Pure JS, works well | +| html2canvas | Good | Pure JS, works well | + +**Recommendation:** For maximum stability in Bun environments, prefer Puppeteer over Playwright, or use Node.js for visual testing tasks specifically. + +#### Lightpanda (Emerging Alternative) + +A new AI-native headless browser built in Zig: +- 11x faster execution than Chrome +- 9x less memory usage +- CDP-compatible (works with Puppeteer/Playwright) +- Best stability with Puppeteer + +--- + +### 8. Handling Common Challenges + +#### Platform-Specific Rendering Differences + +Different operating systems and GPU drivers can cause pixel-level differences. + +**Solutions:** +1. **Use Docker containers** for consistent rendering environment +2. **Set `maxDiffPixelRatio`** to allow small variations +3. **Run CI on same OS as development** (e.g., `ubuntu-latest` matching WSL2) +4. **Generate baselines in CI** rather than locally + +#### Dynamic Content + +Timestamps, ads, and user-specific content cause false positives. + +**Solutions:** +1. **Mask dynamic elements** in Playwright: + ```typescript + await expect(page).toHaveScreenshot({ + mask: [page.locator('.timestamp'), page.locator('.avatar')] + }); + ``` +2. **Freeze time** with mock libraries +3. **Use test fixtures** with static data + +#### Font Rendering + +Font rendering varies by platform and font availability. + +**Solutions:** +1. **Bundle fonts** with the application +2. **Use system font stacks** that are widely available +3. **Allow font-related pixel variation** in comparison thresholds + +--- + +## Options Compared + +### Option A: Lightweight (wkhtmltoimage + ImageMagick) + +**Description:** System-level tools for simple HTML-to-PNG conversion. + +**Pros:** +- No npm dependencies for screenshot generation +- Fast execution (<1s per screenshot) +- Works offline, no browser download +- Small file sizes with optimization +- Simple CI setup + +**Cons:** +- Legacy WebKit engine (limited modern CSS) +- No JavaScript execution +- Not actively maintained +- Requires system package installation + +**Best For:** Static HTML pages, simple dashboards, quick CI validation + +### Option B: Playwright Full Visual Testing + +**Description:** Cross-browser visual regression testing with built-in assertions. + +**Pros:** +- Modern browser rendering (Chromium, Firefox, WebKit) +- Built-in visual comparison with `toHaveScreenshot()` +- JavaScript execution support +- Excellent documentation and ecosystem +- Native parallel execution + +**Cons:** +- Browser download required (~300MB+) +- More complex setup +- Slower execution for simple cases +- Potential Bun compatibility issues + +**Best For:** Production applications, cross-browser testing, JavaScript-heavy pages + +### Option C: Puppeteer for Chrome-Only + +**Description:** Google's Chrome automation library for screenshot generation. + +**Pros:** +- Fastest for simple tasks +- Excellent Chrome integration +- Good Bun compatibility +- PDF generation support + +**Cons:** +- Chrome/Chromium only +- No built-in visual comparison (need BackstopJS or custom solution) +- Browser download required + +**Best For:** Chrome-only workflows, quick automation, PDF generation + +### Option D: BackstopJS (Self-Hosted Visual Regression) + +**Description:** Open-source visual regression testing framework. + +**Pros:** +- Free and self-hosted +- Flexible configuration +- HTML diff reports +- Works with Puppeteer or Playwright + +**Cons:** +- No cloud dashboard +- Manual baseline management +- Requires infrastructure setup + +**Best For:** Teams wanting control over visual testing infrastructure + +### Option E: Percy/Chromatic (Cloud Visual Testing) + +**Description:** Cloud-based visual regression testing platforms. + +**Pros:** +- AI-powered diff detection (reduces false positives) +- Cross-browser cloud rendering +- Collaborative review UI +- Professional team features + +**Cons:** +- Paid service (usage-based pricing) +- External dependency +- May have screenshot budget limits + +**Best For:** Teams with budget for tooling, needing cross-browser visual testing + +--- + +## Recommendations + +### For Markform and Similar CLI Projects + +**Current approach (wkhtmltoimage) is appropriate** for the immediate use case of generating PR-reviewable snapshots of static HTML dashboards. The lightweight approach minimizes dependencies and CI complexity. + +**Consider upgrading to Playwright** if: +- JavaScript-dependent rendering is needed +- Modern CSS features (CSS Grid, Container Queries) are added +- Cross-browser consistency becomes important +- Automated visual regression testing is desired + +### For New Projects + +1. **Start with Playwright** for most web projects - it provides the best balance of features, cross-browser support, and ecosystem integration. + +2. **Use BackstopJS** if you want free, self-hosted visual regression testing without cloud dependencies. + +3. **Use wkhtmltoimage** only for simple, static HTML-to-PNG conversion where modern CSS isn't critical. + +4. **Consider Percy/Chromatic** for teams with budget who need collaborative visual review and AI-powered diff detection. + +### For Agentic Workflows + +1. **Enable Puppeteer MCP server** in Claude Code for iterative visual development. + +2. **Store PNG snapshots in git** for easy review in PRs (keep files small with ImageMagick optimization). + +3. **Upload larger reports as CI artifacts** rather than committing to the repository. + +4. **Use vision models (Claude, GPT-4V)** for intelligent visual analysis beyond pixel-diff comparison. + +--- + +## Next Steps + +- [ ] Evaluate adding Playwright-based visual tests for complex pages +- [ ] Consider BackstopJS integration for automated regression detection +- [ ] Explore Puppeteer MCP server for interactive visual development with Claude +- [ ] Document CI patterns for different visual testing approaches + +--- + +## References + +### Playwright & Puppeteer +- [Playwright Visual Comparisons](https://playwright.dev/docs/test-snapshots) +- [Playwright vs Puppeteer (BrowserStack)](https://www.browserstack.com/guide/playwright-vs-puppeteer) +- [Puppeteer vs Playwright Performance (Skyvern)](https://www.skyvern.com/blog/puppeteer-vs-playwright-complete-performance-comparison-2025/) +- [Playwright Snapshot Testing (BrowserStack)](https://www.browserstack.com/guide/playwright-snapshot-testing) + +### Visual Regression Tools +- [Visual Regression Testing Comparison (Sparkbox)](https://sparkbox.com/foundry/visual_regression_testing_with_backstopjs_applitools_webdriverio_wraith_percy_chromatic) +- [Percy vs Chromatic vs BackstopJS (Medium)](https://medium.com/@sohail_saifi/visual-regression-testing-percy-vs-chromatic-vs-backstopjs-0291477a23ef) +- [Top Visual Regression Testing Tools (Apidog)](https://apidog.com/blog/best-visual-regression-testing-tools/) + +### HTML to Image Conversion +- [wkhtmltopdf Alternatives (AlternativeTo)](https://alternativeto.net/software/wkhtmltopdf/) +- [html2canvas vs Puppeteer (npm-compare)](https://npm-compare.com/dom-to-image,html2canvas,puppeteer) +- [DOM to Image Approaches (Medium)](https://medium.com/@danielsternlicht/capturing-dom-elements-screenshots-server-side-vs-client-side-approaches-6901c706c56f) + +### AI Vision Integration +- [Claude Computer Use for E2E Testing (Medium)](https://medium.com/@itsmo93/automating-e2e-ui-testing-with-claudes-computer-use-feature-c9f516bbbb66) +- [Claude Code Best Practices (Anthropic)](https://www.anthropic.com/engineering/claude-code-best-practices) +- [GPT-4V Screenshot Analyzer (GitHub)](https://github.com/jeremy-collins/gpt4v-screenshot-analyzer) + +### CI/CD Integration +- [Playwright Visual Regression with GitHub Actions (Medium)](https://medium.com/@haleywardo/streamlining-playwright-visual-regression-testing-with-github-actions-e077fd33c27c) +- [Sentry Visual Snapshot Action (GitHub)](https://github.com/getsentry/action-visual-snapshot) +- [Test Screenshots in GitHub Actions (Marmelab)](https://marmelab.com/blog/2023/11/20/screenshot-ci.html) + +### Modern Runtime Compatibility +- [Bun + Playwright (BrowserStack)](https://www.browserstack.com/guide/bun-playwright) +- [Bun Performance for Test Automation (Medium)](https://medium.com/@vitalicset/bun-is-it-fast-for-test-automation-90c9ef845e98) +- [Lightpanda Headless Browser (Roundproxies)](https://roundproxies.com/blog/lightpanda/) diff --git a/packages/markform/tests/visual/fill-record-visual.ts b/packages/markform/tests/visual/fill-record-visual.ts index 2e34de70..7618d572 100644 --- a/packages/markform/tests/visual/fill-record-visual.ts +++ b/packages/markform/tests/visual/fill-record-visual.ts @@ -7,6 +7,7 @@ */ import { writeFileSync, mkdirSync, existsSync } from 'node:fs'; +import { execSync } from 'node:child_process'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { @@ -422,7 +423,76 @@ console.log(`formatTokens(500) = "${formatTokens(500)}"`); console.log(`formatTokens(1500) = "${formatTokens(1500)}"`); console.log(`formatTokens(15000) = "${formatTokens(15000)}"`); -console.log('\n✅ All visual snapshots generated successfully!'); +console.log('\n✅ All HTML snapshots generated successfully!'); + +// Check if a command is available +function hasCommand(cmd: string): boolean { + try { + execSync(`which ${cmd}`, { stdio: 'ignore' }); + return true; + } catch { + return false; + } +} + +// Generate PNG snapshots if wkhtmltoimage is available +if (hasCommand('wkhtmltoimage')) { + console.log('\n--- Generating PNG snapshots ---'); + const hasImagemagick = hasCommand('convert'); + let failedCount = 0; + const generatedPngs: string[] = []; + + for (const { name } of testCases) { + const htmlPath = join(snapshotDir, `fill-record-${name}.html`); + const pngPath = join(snapshotDir, `fill-record-${name}.png`); + try { + // Use wkhtmltoimage to convert HTML to PNG + // --width 900 matches the max-width of .fr-dashboard + execSync( + `wkhtmltoimage --width 900 --quality 90 --enable-local-file-access "${htmlPath}" "${pngPath}"`, + { stdio: 'pipe' }, + ); + + // Optimize with ImageMagick if available (reduce size for PR attachment) + if (hasImagemagick) { + execSync(`convert "${pngPath}" -resize 50% -quality 85 "${pngPath}"`, { stdio: 'pipe' }); + } + + console.log(`✓ Generated: ${pngPath}`); + generatedPngs.push(pngPath); + } catch (error) { + const errorMsg = error instanceof Error ? error.message : String(error); + console.error(`✗ Failed to generate PNG for ${name}: ${errorMsg}`); + failedCount++; + } + } + + // Report results based on success/failure + if (failedCount === 0) { + console.log('\n✅ PNG snapshots generated!'); + if (hasImagemagick) { + console.log(' (optimized with ImageMagick for smaller file sizes)'); + } + console.log(`\nPNG files for PR attachment:`); + for (const pngPath of generatedPngs) { + console.log(` ${pngPath}`); + } + } else if (generatedPngs.length > 0) { + console.log(`\n⚠ PNG generation partially failed: ${failedCount}/${testCases.length} failed`); + console.log(`\nSuccessfully generated:`); + for (const pngPath of generatedPngs) { + console.log(` ${pngPath}`); + } + process.exitCode = 1; + } else { + console.error('\n✗ All PNG generation failed!'); + process.exitCode = 1; + } +} else { + console.log('\n⚠ wkhtmltoimage not found - skipping PNG generation'); + console.log(' Install with: apt-get install wkhtmltopdf'); +} + console.log(`\nOpen the HTML files in a browser to review:`); console.log(` file://${snapshotDir}/fill-record-completed.html`); console.log(` file://${snapshotDir}/fill-record-failed.html`); diff --git a/packages/markform/tests/visual/snapshots/fill-record-cancelled.html b/packages/markform/tests/visual/snapshots/fill-record-cancelled.html index f297b6de..06083b7f 100644 --- a/packages/markform/tests/visual/snapshots/fill-record-cancelled.html +++ b/packages/markform/tests/visual/snapshots/fill-record-cancelled.html @@ -570,7 +570,7 @@
claude-sonnet-4-20250514
-
Jan 30, 2026 at 6:30 AM
+
Jan 30, 2026 at 2:30 PM
diff --git a/packages/markform/tests/visual/snapshots/fill-record-cancelled.png b/packages/markform/tests/visual/snapshots/fill-record-cancelled.png new file mode 100644 index 00000000..3d7ab635 Binary files /dev/null and b/packages/markform/tests/visual/snapshots/fill-record-cancelled.png differ diff --git a/packages/markform/tests/visual/snapshots/fill-record-completed.html b/packages/markform/tests/visual/snapshots/fill-record-completed.html index c55e96e7..7ebc9a0c 100644 --- a/packages/markform/tests/visual/snapshots/fill-record-completed.html +++ b/packages/markform/tests/visual/snapshots/fill-record-completed.html @@ -570,7 +570,7 @@
claude-sonnet-4-20250514
-
Jan 30, 2026 at 6:30 AM
+
Jan 30, 2026 at 2:30 PM
diff --git a/packages/markform/tests/visual/snapshots/fill-record-completed.png b/packages/markform/tests/visual/snapshots/fill-record-completed.png new file mode 100644 index 00000000..512454d1 Binary files /dev/null and b/packages/markform/tests/visual/snapshots/fill-record-completed.png differ diff --git a/packages/markform/tests/visual/snapshots/fill-record-failed.html b/packages/markform/tests/visual/snapshots/fill-record-failed.html index 45b60842..0c9330a5 100644 --- a/packages/markform/tests/visual/snapshots/fill-record-failed.html +++ b/packages/markform/tests/visual/snapshots/fill-record-failed.html @@ -570,7 +570,7 @@
claude-sonnet-4-20250514
-
Jan 30, 2026 at 6:30 AM
+
Jan 30, 2026 at 2:30 PM
diff --git a/packages/markform/tests/visual/snapshots/fill-record-failed.png b/packages/markform/tests/visual/snapshots/fill-record-failed.png new file mode 100644 index 00000000..93dea497 Binary files /dev/null and b/packages/markform/tests/visual/snapshots/fill-record-failed.png differ diff --git a/packages/markform/tests/visual/snapshots/fill-record-partial.html b/packages/markform/tests/visual/snapshots/fill-record-partial.html index c32132db..6862289f 100644 --- a/packages/markform/tests/visual/snapshots/fill-record-partial.html +++ b/packages/markform/tests/visual/snapshots/fill-record-partial.html @@ -570,7 +570,7 @@
claude-sonnet-4-20250514
-
Jan 30, 2026 at 6:30 AM
+
Jan 30, 2026 at 2:30 PM
⚠ PARTIAL: max_turns
diff --git a/packages/markform/tests/visual/snapshots/fill-record-partial.png b/packages/markform/tests/visual/snapshots/fill-record-partial.png new file mode 100644 index 00000000..d8e7e51f Binary files /dev/null and b/packages/markform/tests/visual/snapshots/fill-record-partial.png differ