RenderCheck
Developer BetaVerify what users actually see in AI-generated UI.
See what your users see
Drop a screenshot. RenderCheck reads it in your browser, checks every word's confidence and contrast, and writes the Playwright assertion for you.
Drop a screenshot, paste one, or try the sample.
- Passed
- Confidence < 80%
- Contrast or text mismatch
The Problem
AI coding tools generate UI fast. But your tests pass while users see:
- Wrong currency ($ vs £)
- Broken confirmations (missing order numbers)
- Invisible text (white on white)
- Truncated messages
- Localisation failures (date formats, translated text)
DOM tests pass. DOM is correct. Logic is correct. But visible text is wrong.
How RenderCheck Works
RenderCheck compares rendered-output text against your expectations in Playwright and Cypress tests.
- 1. Take a screenshot: Use `page.screenshot()` in Playwright or `cy.screenshot()` in Cypress
- 2. Assert with toShowText(): RenderCheck reads the screenshot locally and compares it with the expected text
- 3. Get results: the assertion passes, or fails with what OCR read and how it differs
- 4. Assert: `expect(result.outcome).toBe('pass')` in your test
Use Cases
AI-Generated UI
Verify that AI coding assistants generated the correct UI. Catch when LLMs hallucinate button labels or missing copy.
Localisation Testing
Verify translated text, locale-specific formatting (dates, currency, numbers), and RTL layout.
Critical Confirmations
Ensure order numbers, payment confirmations, and legal disclaimers appear correctly after state changes.
Generated Documents
Verify PDFs, invoices, and dynamic reports render correctly before sending to users.
vs Other Approaches
| Approach | Verifies | Limitation |
|---|---|---|
| DOM assertions | Page structure, text nodes | Can miss rendered visual issues |
| Screenshot diffing | Pixel changes | Noisy, doesn't parse text meaning |
| Manual review | Human judgment | Slow, inconsistent |
| RenderCheck | Visible text in screenshots | OCR accuracy depends on image quality |
Install
npm install @freetextfromimage/rendercheckPackage: @freetextfromimage/rendercheck. Runs OCR locally: no API key, no upload, no network calls. Requires Node ≥18 and Playwright or Cypress.
Quick Start
import { test } from '@playwright/test';
import { expect } from '@freetextfromimage/rendercheck/playwright';
test('checkout shows the correct total', async ({ page }) => {
await page.goto('https://example.com/checkout');
await expect(page).toShowText('Total: $14.00', {
minConfidence: 85,
minContrastRatio: 4.5,
});
});
// If the page shows "Total: €14.00" instead:
// Expected to find text "[Total: $14.00]" but OCR read "[Total: €14.00]" (Confidence: 96%)
// Diff: Total: [$]14.00 → Total: [€]14.00API Reference
await expect(page | locator).toShowText(expected: string, options?: {
region?: { x: number; y: number; width: number; height: number };
minConfidence?: number; // OCR confidence 0-100 (default 80)
minContrastRatio?: number; // WCAG contrast, e.g. 4.5 (off unless set)
exact?: boolean; // whole region text must equal expected
ignoreCase?: boolean; // default false
dom?: boolean; // locator only: also compare with innerText (default true)
timeout?: number; // retry window in ms (default 5000)
});
// Cypress: cy.matchText(expected, options)
// Any runner: verifyText({ image, expected, options }) from '@freetextfromimage/rendercheck/core'Why an assertion fails
- Text not found: says what OCR read instead, with a character-level diff
- Low confidence: the text was found but OCR was not sure of it
- Insufficient contrast: the text was read, but is too faint (WCAG)
- DOM mismatch: the pixels and the element's DOM text disagree
Limitations
Verifies visible text, and its contrast. Does not check layout or spacing.
OCR accuracy depends on image quality. High-contrast, clear text yields best results.
Not a replacement for visual regression testing. Use alongside tools like Percy or Chromatic for visual assertions.
Ready to verify rendered UI?
Install the package and start catching UI bugs in your tests. No account and no API key.