How to Run Screenshot-Based Visual Tests for a Web App on an Indian Linux Server
Set up reproducible Playwright screenshot tests on a Linux server, manage visual baselines, and diagnose common CI differences.
Use Playwright Test to capture a page and compare it with a reviewed reference screenshot. On a Linux server or CI runner, install the same pinned browser version and operating-system dependencies used to create the baseline, run tests in a consistent environment, and review every proposed baseline change.
The setup is the same for an Indian Linux server as for Linux servers elsewhere. The available Playwright guidance does not establish a special Indian hosting, regional, legal, or network requirement for visual tests.
1. Add Playwright and write a visual test
For a Node.js project, install Playwright Test and add a test that captures a stable route:
npm install --save-dev @playwright/test
npx playwright install
import { test, expect } from '@playwright/test';
test('home page visual appearance', async ({ page }) => {
await page.goto('https://your-app.example');
await expect(page).toHaveScreenshot('home.png');
});
Save this as tests/home.visual.spec.ts. Configure the project’s test runner in playwright.config.ts if needed:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
use: {
baseURL: 'https://your-app.example',
browserName: 'chromium',
viewport: { width: 1280, height: 800 },
},
});
The first run creates a reference screenshot if one does not exist. Subsequent runs compare the new capture with that reference. Treat the baseline as a reviewed project artifact: inspect and commit it when a UI change is intentional. See the official Playwright visual comparison guide.
2. Run it on Linux CI or a server
Commit the lockfile and pin the Playwright package version. On a Linux runner, install dependencies, install Playwright browsers and operating-system packages, then run the test suite:
npm ci
npx playwright install --with-deps
npx playwright test
For a project that uses Playwright’s Python test integration, the corresponding setup is:
python -m pip install playwright pytest
playwright install --with-deps
pytest
Playwright also documents Linux Docker images as a way to supply browsers and dependencies consistently. If you use a Playwright image, pin its tag together with the Playwright version in your project. Update both intentionally, then review any resulting screenshot changes. The official CI guide covers both Linux dependency installation and Docker-based setups; the Python CI guide covers the Python flow.
Host installation or container?
| Approach | Useful when | Tradeoff |
|---|---|---|
| Install on the CI host | The runner is already managed and you want a short setup. | You must keep host packages and browsers aligned with the baseline environment. |
| Use a pinned Linux container | You want browser and system dependencies controlled alongside the job. | The team must maintain the image tag and update it deliberately. |
In either case, create and compare baselines in the same rendering environment. Playwright notes that operating system, browser version, settings, hardware, and headless mode can affect screenshots. Its advice is to use the environment that generated the baseline. See Visual comparisons.
3. Make screenshots repeatable
Fix the inputs that your application renders, not just the screenshot threshold. Keep these choices deliberate and consistent between baseline creation and CI comparisons:
- Playwright package, browser project, and browser image or installation version.
- Viewport size and device scale factor.
- Locale, timezone, and test data.
- Authentication, feature flags, and application state.
- Page readiness: wait for the app’s meaningful ready state and for fonts or images needed in the capture.
Use deterministic data where possible. For changing regions that cannot be made deterministic, Playwright’s screenshot options include stylePath, which can apply styles to hide or neutralize volatile content. Set a threshold such as maxDiffPixels only after examining actual, expected, and diff images and deciding what amount of variation is acceptable. A higher threshold can hide a real regression. Option details are in the snapshot documentation.
Update a baseline intentionally
- Run the test and open the expected, actual, and diff images produced for the failure.
- Decide whether the change is an intended design update, environment drift, nondeterministic content, or a genuine defect.
- For an intended visual change, run
npx playwright test --update-snapshots. - Review the resulting image changes alongside the code change, then commit them.
Do not automatically update snapshots on every failing CI run. That would make unintended changes appear accepted without review.
4. Choose browsers and display mode
Playwright supports Chromium, Firefox, and WebKit test projects. Run the projects that match the browsers and behavior important to your users; each additional project adds work to the CI job. Linux WebKit can be useful for CI, but Playwright says macOS WebKit is closer to Safari. If Safari-specific rendering is the target, Linux WebKit is not an exact substitute. See the official browser guidance.
A desktop session is not required for the normal headless workflow. For headed Linux runs that need a display, Playwright documents Xvfb as the virtual display option. Prefer headless execution for routine CI and reserve headed runs for investigations that need them. Setup options are covered in the CI guide.
5. Handle proxies and custom certificates
If the server uses an outbound proxy, Playwright documents HTTPS_PROXY for browser downloads and NODE_EXTRA_CA_CERTS for a trusted custom certificate authority. For Linux dependency installation behind a proxy, its browser documentation says to run the installation as root so the package manager receives the proxy environment variables. These are general proxy instructions, not India-specific requirements. Consult Playwright’s proxy guidance for the environment-specific setup.
6. Diagnose common failures
| Symptom | Likely cause | Fix |
|---|---|---|
| Browser executable is missing | The package is installed but its browser binaries are not available on the runner. | Run npx playwright install --with-deps in the CI setup, or use the matching pinned Playwright image. |
| Browser fails to launch on Linux | Required system dependencies are missing, or the environment differs from the documented setup. | Install dependencies with the Playwright CLI or use the Linux Docker image. Check the runner logs for launch errors. |
| Screenshots differ only in CI | Host OS, browser, settings, hardware, headless mode, or uncontrolled page inputs differ from the baseline environment. | Generate and compare baselines in the same pinned environment; stabilize viewport, data, locale, and page state. |
| Images or fonts are absent in the screenshot | The test captured before those resources or the relevant application state were ready. | Wait for the app’s real ready condition and ensure required fonts and images have loaded before capturing. |
| Diffs change from run to run | Dynamic content or state is varying between captures. | Use deterministic test data or hide volatile content with stylePath; inspect the diff before changing thresholds. |
| Baseline update creates broad unexpected changes | The browser or OS version changed, or the update command ran without a targeted review. | Check the pinned Playwright and image versions, inspect the diff images, and update snapshots only for intentional changes. |
| Browser download or package installation fails behind a proxy | The download or package manager cannot use the proxy or trust its certificate. | Set the documented proxy and trusted certificate environment variables; for Linux dependency installation, pass proxy variables to the package manager as described by Playwright. |
| Safari users still report a rendering difference | Linux WebKit does not match macOS Safari as closely as macOS WebKit. | Use macOS WebKit when closer Safari rendering is a requirement. |
7. Performance, reliability, and cost
Visual tests need a browser launch, page load, and image comparison, so the total job time depends on the app, routes, browser projects, and CI environment. Keep the suite focused on important pages and states, and avoid repeating identical captures without a reason. Adding browser projects improves coverage but increases CI work; choose based on user browser coverage and runner availability.
Reliability comes from controlling the rendering environment and application inputs, reviewing baselines, and investigating failed captures before accepting changes. A Linux container can reduce differences between machines, but it does not make changing application data deterministic by itself.
The dossier provides no benchmark or server cost figure for this workflow. Your cost depends on the CI provider, runner size, duration, browser matrix, and how often the suite runs. Measure those in your own pipeline rather than assuming a specific runtime or price.
Or skip the browser setup
If you need a screenshot of a live URL without maintaining browser binaries on the server, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. A single GET request returns an image or PDF. See the ScreenshotNeo API documentation for parameters and response details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://your-app.example -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://your-app.example"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://your-app.example',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
Use an API capture as an input to your own comparison workflow when that fits your needs; Playwright Test remains the method above for browser-based visual assertions and reviewed test baselines. ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up for ScreenshotNeo and get 1,000 free screenshots a month, with no card.
FAQ
Does the server need a graphical desktop?
No. Playwright’s routine CI workflow is headless. Use Xvfb for Linux headed runs that need a virtual display.
Can I create the baseline on my laptop and compare it on Linux?
You can, but differences in operating system, browser, settings, hardware, or headless mode can affect the image. For dependable comparisons, create and compare baselines in the same environment.
Is Linux WebKit the same as Safari?
No. Playwright describes macOS WebKit as closer to Safari. Use macOS WebKit when Safari fidelity is the requirement.
Does an Indian server need a special Playwright setup?
The cited Playwright guidance describes Linux CI generally. It does not establish a special India-only setup; apply proxy instructions if your server’s network requires them.


