ScreenshotNeo

BlogHow-to

How to Take a Playwright Screenshot of an Indian Railway Booking Page

Capture an authorized railway booking page with Playwright. Choose a viewport, full-page, or element screenshot, and handle dynamic content safely.

By the ScreenshotNeo team4 October 20267 min read

Use Playwright’s page.screenshot() to save the current browser view, add fullPage: true to capture the full scrollable page, or call locator.screenshot() to capture one section. These methods capture the page state your browser can access; they do not bypass a login, bot check, or site restriction.

The examples below use the public IRCTC homepage as a navigation target. They do not assume a particular live layout, selector, login flow, or that automated access will succeed. If the page requires a user session, use an authorized session and capture only information you are permitted to access. Keep passenger details, OTPs, payment information, and booking references out of published screenshots.

1. Install Playwright and save a viewport screenshot

This runnable Node.js example opens Chromium, navigates to the site, saves the visible browser viewport as a PNG, and closes the browser even if navigation or capture fails.

import { chromium } from 'playwright';

const browser = await chromium.launch();
try {
  const page = await browser.newPage({
    viewport: { width: 1440, height: 1000 },
  });
  await page.goto('https://www.irctc.co.in/', {
    waitUntil: 'domcontentloaded',
    timeout: 60_000,
  });
  await page.screenshot({ path: 'railway-booking-page.png' });
} finally {
  await browser.close();
}

Save the file as screenshot.mjs, install Playwright, install its Chromium browser, and run it:

npm init -y
npm install playwright
npx playwright install chromium
node screenshot.mjs

page.screenshot() without fullPage captures the visible viewport. The chosen viewport controls the browser’s CSS-pixel width and height; it does not guarantee that the live page will render identically on every run.

2. Choose viewport, full-page, or element capture

Capture Playwright call Best for
Viewport page.screenshot({ path }) A record of what is visible without scrolling.
Full page page.screenshot({ path, fullPage: true }) A tall image containing the full scrollable document.
One element page.locator(selector).screenshot({ path }) A result card, timetable, or other specific region.

Full-page screenshot

Set fullPage: true when content below the fold belongs in the image. The output may be very tall on long pages, so consider whether a viewport or element capture is more useful for sharing.

await page.screenshot({
  path: 'railway-booking-page-full.png',
  fullPage: true,
});

Screenshot one element

Use a locator when only a specific part of the page matters. Identify a selector from the page under test; this example deliberately uses a placeholder because no current IRCTC selector has been verified.

const section = page.locator('YOUR_SELECTOR');
await section.screenshot({ path: 'booking-section.png' });

Wait for the intended element before capturing it, and use a selector that identifies exactly one region. A locator screenshot scrolls the element into view as needed. If the selector does not match the page’s current markup, the capture will fail rather than produce the intended region.

3. Wait for the page state you need

Choose a navigation wait condition based on the page. domcontentloaded waits for the initial document to be parsed, while load waits for the load event. Neither guarantees that client-rendered results, images, or a particular form are ready. For a known page state, wait for a locator that you have verified in your own environment:

await page.goto('https://www.irctc.co.in/', {
  waitUntil: 'domcontentloaded',
  timeout: 60_000,
});

// Replace with a selector verified on the page you are allowed to access.
await page.locator('YOUR_SELECTOR').waitFor({
  state: 'visible',
  timeout: 15_000,
});
await page.screenshot({ path: 'page-ready.png' });

A fixed delay can help when the page has a known delayed update, but it is less reliable than waiting for a specific expected state. Do not treat a timeout extension as a way around access controls or a site that refuses automation.

4. Make visual captures more repeatable

Live booking pages can change between runs because content, loading, and page state vary. For visual regression checks, Playwright Test’s toHaveScreenshot() waits for two consecutive screenshots to match before comparing against the expected image. Its screenshot assertions support options such as animation handling, masking dynamic regions, and CSS-pixel versus device-pixel scale. A stable capture setup helps compare intended changes, but it cannot make a changing live railway page deterministic.

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

test('booking page visual snapshot', async ({ page }) => {
  await page.goto('https://www.irctc.co.in/', {
    waitUntil: 'domcontentloaded',
  });
  await expect(page).toHaveScreenshot('railway-page.png', {
    animations: 'disabled',
  });
});

Install the test package and browser if you use this example:

npm install --save-dev @playwright/test
npx playwright install chromium
npx playwright test

For assertion options and their behavior, see the official Playwright PageAssertions documentation. For the basic screenshot APIs, see Playwright’s Screenshots guide.

5. Protect private booking information

  • Capture only a page and session you are authorized to access.
  • Do not publish real passenger names, contact details, OTPs, payment details, or booking references.
  • Prefer a public page or synthetic test data for documentation and visual tests.
  • Do not assume a test guide describes the current production booking flow. The available IRCTC International User Guide is a guide with dated examples and includes the warning: “This is testing website. PNR booked using this website is not authorized for journey.” It does not establish current production layout or automation behavior.

6. cURL, Python, and Node.js with ScreenshotNeo

If you need a screenshot API rather than managing a browser process, ScreenshotNeo takes a URL and returns an image or PDF. See the ScreenshotNeo API documentation for request options. These examples request a screenshot of the public IRCTC homepage; they do not provide authenticated access to a booking session.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://www.irctc.co.in/ \
  -o railway-page.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={
        "access_key": "YOUR_API_KEY",
        "url": "https://www.irctc.co.in/",
    },
    timeout=90,
)
r.raise_for_status()
open("railway-page.webp", "wb").write(r.content)

Node.js

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

Or skip the browser setup

One API call can return a screenshot without installing or managing Playwright locally. ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month without a card; paid plans start at $5 for 3,000.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://www.irctc.co.in/ \
  -o railway-page.webp

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

Troubleshooting

Symptom Likely cause What to do
Browser executable is missing The Playwright package is installed, but its browser binary is not. Run npx playwright install chromium.
Navigation times out The page is slow, still loading resources, or automation is not being served. Use an appropriate wait condition and timeout; inspect the page and browser logs. Do not assume a longer timeout will resolve access restrictions.
The screenshot shows a loading or incomplete state The capture happened before the relevant content appeared. Wait for a verified locator or page state before calling screenshot.
Element locator times out The selector is a placeholder, stale, hidden, or absent in the current page state. Inspect the page you are permitted to access and replace it with a verified selector; wait for it to be visible.
Full-page image is unexpectedly large The page has a long scrollable document. Capture a viewport or a single element if that is sufficient, or review the full image before sharing it.
Visual test changes on every run Live content or animation is changing between captures. Use a controlled test page where possible; disable animations and mask dynamic regions using supported screenshot assertion options.
ScreenshotNeo request fails The key, URL, response, or network request may be invalid or unsuccessful. Check the API key and encoded URL, inspect the HTTP status and response headers, and consult the API documentation.

Performance, reliability, and cost

  • Playwright: the browser must launch and load the page, so capture time depends on the environment and page. Reuse a browser for batches of captures rather than launching one for every page. Always close browser resources after use.
  • Capture size: full-page screenshots can produce much taller files than viewport or element screenshots. Pick the smallest capture that serves the documentation or test.
  • Repeatability: a live booking page may vary across runs. A verified wait condition and visual-test controls reduce avoidable variation, but do not promise a fixed layout or successful unattended access.
  • ScreenshotNeo pricing: Free includes 1,000 shots per month; Starter is $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free. Every feature is available on every plan.

FAQ

Does Playwright log in to IRCTC for me?

The screenshot API captures the browser state you provide. This guide does not provide or imply a way to bypass authentication or site restrictions.

Can I screenshot a booking result?

Yes, if it is available in a session and page state you are authorized to access. Use a verified locator for a result region, and remove private passenger or booking data before sharing the image.

Does full-page capture include content that loads only when scrolled?

fullPage: true captures the full scrollable page, but page-specific lazy loading can affect what has rendered. Check the output and wait for the content your use case requires.

Is the IRCTC international guide a current automation specification?

No. It is an international user guide with dated examples, not evidence of current production layout or automation requirements.