Developer Documentation
RenderCheck is an SDK for verifying rendered UI text in Playwright, Cypress, and any E2E testing framework.
Use it to catch bugs where DOM tests pass but visible text is wrong, currency symbols, truncated confirmations, locale formatting, missing copy, and invisible text.
Product State
Browser OCR
LiveFree tool at getrendercheck.com. Extract text from images in your browser. No signup required.
RenderCheck SDK
Developer Betanpm package for Playwright and Cypress. OCR runs on your machine: no API key, no upload, no network calls. The Cypress integration has been run in Cypress 13 only (Electron, Linux).
Hosted API
PlannedThe hosted API has been retired. There is nothing to sign up for and nothing is sent to our servers.
CLI Tool
PlannedCommand-line interface for one-off OCR verification. Not started.
Install
npm install --save-dev @freetextfromimage/rendercheckRequires Node 18+ and @playwright/test 1.40+ or cypress 12+. The English language data ships in the package.
Quick Start
In Playwright, import expect from RenderCheck. It is Playwright's own expect with toShowText added:
import { test } from '@playwright/test';
import { expect } from '@freetextfromimage/rendercheck/playwright';
test('checkout shows the right total', async ({ page }) => {
await page.goto('/checkout');
await expect(page).toShowText('Total: $14.00', {
minConfidence: 85, // OCR confidence of the matched words (default 80)
minContrastRatio: 4.5, // WCAG contrast of the matched words (off unless set)
});
});When the screen disagrees with what you expect, the test fails with:
Expected to find text "[Total: $14.00]" but OCR read "[Total: €14.00]" (Confidence: 96%)
Diff: Total: [$]14.00 → Total: [€]14.00Reference
Options
Shared by toShowText, cy.matchText and verifyText.
interface AssertionOptions {
region?: { x: number; y: number; width: number; height: number }; // screenshot pixels
minConfidence?: number; // 0-100, default 80
minContrastRatio?: number; // WCAG, e.g. 4.5 (normal text) or 3 (large text). Off unless set
exact?: boolean; // text must equal the expected text, not just contain it
ignoreCase?: boolean; // default false
dom?: boolean; // with a Locator, also compare with innerText. Default true
timeout?: number; // Playwright retry window in ms. Default 5000
interval?: number; // Playwright pause between attempts in ms. Default 250
fullPage?: boolean; // Playwright: capture the whole scrollable page
lang?: string; // Tesseract language code. Default 'eng'
langPath?: string; // folder with <lang>.traineddata.gz for other languages
}verifyText (core)
The framework-free function behind the matchers. Takes a PNG or JPEG buffer and returns a report.
import { verifyText } from '@freetextfromimage/rendercheck/core';
const report = await verifyText({
image: fs.readFileSync('screenshot.png'),
expected: 'Total: $14.00',
options: { minContrastRatio: 4.5 },
});
if (!report.pass) console.error(report.message);
// report.failure: 'NOT_FOUND' | 'LOW_CONFIDENCE' | 'INSUFFICIENT_CONTRAST' | 'DOM_MISMATCH'
// report.read, report.confidence (0-100), report.similarity (0-1), report.minContrastFailure kinds
- NOT_FOUND: the expected text is not in the rendered pixels (also when the DOM has it but the screen does not show it)
- LOW_CONFIDENCE: the text was found but OCR confidence is below
minConfidence - INSUFFICIENT_CONTRAST: the text is readable but below
minContrastRatio - DOM_MISMATCH: the element's DOM text and its pixels disagree
Examples
Playwright: one element and a region
import { test } from '@playwright/test';
import { expect } from '@freetextfromimage/rendercheck/playwright';
test('order confirmation displays the order number', async ({ page }) => {
await page.goto('/order-confirmation');
// One element: also compared with its DOM text.
await expect(page.locator('#order-number')).toShowText('Order #ABC123456');
// Only part of the screenshot.
await expect(page).toShowText('Pay now', { region: { x: 120, y: 340, width: 200, height: 40 } });
await expect(page).not.toShowText('Total: €14.00');
});Cypress
// cypress.config.ts
import { defineConfig } from 'cypress';
import { registerRenderCheck } from '@freetextfromimage/rendercheck/cypress/plugin';
export default defineConfig({
e2e: { setupNodeEvents(on) { registerRenderCheck(on); } },
});
// cypress/support/e2e.ts
import '@freetextfromimage/rendercheck/cypress';
// in a test
cy.visit('/checkout');
cy.matchText('Total: $14.00', { minConfidence: 85, minContrastRatio: 4.5 });
cy.get('#total').matchText('Total: $14.00');Tested in Cypress 13.17 (Electron, Linux) with 5 specs, including the failing cases. Other Cypress versions and browsers are untested.
Frequently Asked
Do I need an API key?
No. There is no hosted API. OCR runs in your test process with Tesseract.js (WebAssembly).
What happens to my screenshots?
They never leave your machine. The package makes no network requests, and Tesseract's cache is switched off, so nothing is written to your project either.
Is OCR accuracy guaranteed?
No. OCR can misread l/I/1 and O/0, and it can skip very faint text or light text on a busy coloured background. Scope the assertion to an element or a region for best results. Contrast is measured on pixels, so treat it as an estimate.
Which languages are supported?
English out of the box. For other languages, point langPath at a folder with the matching .traineddata.gz file and set lang.
Ready to get started?
Install the package and run your first assertion. No account and no key.