Skip to main content

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

Live

Free tool at getrendercheck.com. Extract text from images in your browser. No signup required.

RenderCheck SDK

Developer Beta

npm 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

Planned

The hosted API has been retired. There is nothing to sign up for and nothing is sent to our servers.

CLI Tool

Planned

Command-line interface for one-off OCR verification. Not started.

Install

Terminalbash
npm install --save-dev @freetextfromimage/rendercheck

Requires 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:

checkout.spec.tstypescript
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:

text
Expected to find text "[Total: $14.00]" but OCR read "[Total: €14.00]" (Confidence: 96%)
  Diff: Total: [$]14.00  →  Total: [€]14.00

Reference

Options

Shared by toShowText, cy.matchText and verifyText.

typescript
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.

typescript
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.minContrast

Failure 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

order.spec.tstypescript
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

typescript
// 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.