ScreenshotNeo

BlogHow-to

How to Set the Indian Rupee Symbol in Playwright Screenshot Tests

Render ₹ (U+20B9) reliably in Playwright screenshot tests by checking the character, glyph coverage, and baseline environment.

By the ScreenshotNeo team4 October 20266 min read

Use the Indian Rupee Sign, ₹ (U+20B9), in your fixture, then verify that the browser’s available fonts render its glyph. For reliable visual comparisons, generate and compare Playwright baselines in the same browser and operating-system environment.

The character in your source and the glyph in the screenshot are separate concerns: correct Unicode does not guarantee that a suitable font is available. Unicode names U+20B9 the Indian Rupee Sign and distinguishes it from U+20A8, the older Rupee Sign. See the Unicode Standard and Playwright’s visual comparisons guide.

1. Put U+20B9 in the test fixture

In JavaScript or TypeScript, either the literal symbol or the Unicode escape represents the same character:

const amount = '₹1,234.56';
const amountWithEscape = '\u20B91,234.56';

For HTML, use the literal symbol or its numeric character reference:

<span>₹1,234.56</span>
<span>&#x20B9;1,234.56</span>

Use the form that makes the fixture easiest to read and maintain. If you suspect an encoding or copy-and-paste problem, inspect the string’s code points rather than relying on how it looks in the editor:

const value = '₹1,234.56';
console.log([...value].map(char => char.codePointAt(0)?.toString(16)));
// [ '20b9', '31', ... ]

For an application page, assert against the actual amount element or rendered interface. A fixture made with page.setContent() is useful for isolating glyph rendering, but it does not test your application’s encoding, CSS, or font loading.

2. Capture and compare it with Playwright Test

This runnable test uses Playwright Test’s locator screenshot assertion to isolate the symbol and amount:

import { test, expect } from '@playwright/test';

test('renders the Indian rupee sign', async ({ page }) => {
  await page.setContent('<span>₹1,234.56</span>');
  await expect(page.locator('span')).toHaveScreenshot('rupee-amount.png');
});

Run the test with your project’s usual Playwright Test command. On the first run, Playwright creates a reference snapshot; subsequent runs compare against it. Review the generated image to confirm the glyph looks correct before treating that image as the expected baseline.

When the symbol is part of a component, use a locator for the smallest region whose appearance matters. Use a page screenshot if placement, surrounding layout, or interactions are part of the requirement. Playwright documents both screenshot APIs and visual assertions in its visual comparisons guide and PageAssertions API.

3. Check the glyph and rendering environment

  1. Confirm character identity. Verify that the text contains U+20B9, not U+20A8 or a visually similar character.
  2. Inspect the rendered screenshot. Look for a missing-glyph box, unexpected mark, or a shape that differs from the intended rupee sign.
  3. Check font availability and coverage. The browser needs a font with a U+20B9 glyph. Confirm the actual browser output; no single font family is established here as universally suitable.
  4. Align baseline and comparison environments. Keep the operating system, browser project and version, and font setup consistent between baseline generation and CI comparison.
  5. Only then adjust comparison settings. A more permissive pixel threshold can hide differences; it does not fix a missing glyph or an unintended font change.

Playwright notes that browser rendering can vary with the host operating system, version, settings, hardware, power source, headless mode, and other conditions. Its screenshot assertion also waits for two consecutive screenshots to match before comparison. That helps settle capture output within a run; it does not make screenshots identical across different environments. See the Playwright guidance on rendering variability and assertion options.

4. Choose the right screenshot assertion

What you need to verify Capture scope Why
Only the rupee glyph and amount Locator Limits unrelated page changes in the comparison.
Symbol, spacing, and component layout Containing component Includes the local layout behavior under test.
Placement in the full interface Page Captures surrounding layout and position.
Appearance under a controlled test-only override Screenshot assertion with a stylesheet option Can apply deterministic screenshot styling, but may mask the font behavior being tested.

Use screenshot styles only when the override is itself part of the test design. If the goal is to verify your real font behavior, a stylesheet that substitutes or changes fonts can make the test pass while hiding the issue.

5. Common problems and fixes

Symptom Likely cause Fix
A box or replacement character appears The active font lacks a usable U+20B9 glyph, or the wrong character reached the page. Check the DOM code point, inspect font availability in the test environment, and verify the rendered output.
The symbol looks different in CI than locally Different operating system, browser version, font setup, or rendering conditions. Generate and compare baselines in a consistent environment, including fonts.
The source shows ₹ but the page does not The source representation is correct, but the rendered page may use a font without the glyph or the application may transform the text. Inspect the actual DOM text and computed rendering, then confirm glyph coverage in the browser.
The screenshot fails intermittently Other page content may still be changing, or capture conditions vary between runs. Wait for the relevant content to settle, narrow the assertion to the relevant element when appropriate, and keep the baseline environment stable.
A relaxed threshold makes the test pass, but the symbol is still wrong The comparison is tolerating pixel differences rather than correcting the rendered character. Fix the character or font issue first; tune thresholds only for understood, acceptable rendering variation.

6. Keep screenshots dependable and economical

  • Reliability: Use a stable baseline-generation and CI environment. Pin or bundle a suitable font if your project needs repeatable rendering, and verify that it covers U+20B9 in your chosen browser.
  • Performance: A locator screenshot can keep a narrowly focused glyph test smaller than a full-page comparison. Choose a wider capture only when the surrounding layout is part of what you need to validate.
  • Review cost: Baseline updates should be reviewed as images. A passing pixel comparison alone does not establish that the rupee glyph is semantically correct.
  • Thresholds: Use comparison tolerances to account for known, acceptable pixel variation, not as a substitute for consistent fonts and rendering conditions.

Or skip the browser setup

For a one-call website capture, ScreenshotNeo returns a screenshot or PDF from a URL. Its API parameters and behavior are described in the ScreenshotNeo documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

ScreenshotNeo accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed, and responses identify the page verdict and billing status in headers. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for 1,000 free screenshots a month with no card.

FAQ

Is U+20A8 the same character as the Indian rupee symbol?

No. Use U+20B9 for the Indian Rupee Sign. U+20A8 is a distinct, older Rupee Sign.

Does a successful screenshot assertion prove the right currency character is present?

No. It verifies pixel output against a baseline. Check the DOM text or fixture code point when character identity matters.

Will a baseline created on one operating system match another?

It may differ because rendering depends on host and browser conditions, including fonts. Use the same environment for baseline generation and comparison when dependable pixel matching matters.

Should I compare the whole page or just the amount?

Compare the smallest region that covers the behavior you need to protect. Expand to the component or page when layout and position are also under test.