ScreenshotNeo

BlogHow-to

How to Capture a Full-Page Screenshot of an Indian Government Portal with Playwright

Use Playwright’s fullPage option to save an authorized government portal page from top to bottom. Get runnable code, capture settings, and fixes for common issues.

By the ScreenshotNeo team4 October 20268 min read

Use Playwright’s page.screenshot({ fullPage: true }) to capture the full scrollable extent of an Indian government portal page, rather than only the visible viewport. Replace the example URL below with the public page you are authorized to access, install Playwright and its Chromium browser, run the script, then inspect the resulting PNG.

mkdir portal-capture
cd portal-capture
npm init -y
npm install playwright
npx playwright install chromium
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  try {
    const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
    const response = await page.goto('https://portal.example.gov.in', {
      waitUntil: 'load',
      timeout: 60000,
    });

    if (response && !response.ok()) {
      throw new Error(`Portal returned HTTP ${response.status()}`);
    }

    // Add a page-specific locator check here if you know a stable heading or landmark.
    await page.screenshot({
      path: 'portal-full-page.png',
      fullPage: true,
      type: 'png',
    });
  } finally {
    await browser.close();
  }
})().catch(error => {
  console.error(error);
  process.exitCode = 1;
});

page.goto() can return a response for HTTP errors such as 404 or 500 instead of throwing, so check the status before treating the file as a valid capture. A successful response also does not prove the expected portal content loaded: inspect the screenshot or wait for a known page element.

1. What fullPage captures

With fullPage: true, Playwright captures the full scrollable page rather than the current viewport. The option defaults to false. It controls screenshot extent; it does not promise to click controls, submit forms, or trigger every page-specific lazy-loading behavior. [Playwright Page API](https://playwright.dev/docs/api/class-page#page-screenshot)

For content that appears only after a normal, authorized user action—such as scrolling to load more rows or opening a section—perform that workflow first, confirm the intended content is visible, then take the screenshot. Do not assume that a tall image contains results that the page had not loaded.

2. Configure the screenshot

The core call can be adjusted for output format, image scale, animation state, masks, and screenshot-only styling. These options affect the image; they do not change what information the portal makes available.

Option Use Consideration
path Save the image to a file, such as portal-full-page.png. Choose a writable path and a meaningful name if captures are archived.
type Choose png, jpeg, or webp. PNG is a practical default for text-heavy pages. JPEG and WebP are lossy formats; check that small text remains legible.
scale 'css' creates one image pixel per CSS pixel; 'device' uses device pixels. Device scale can increase dimensions and file size on high-density displays. Use CSS scale when predictable dimensions matter.
animations Set to 'disabled' to stop CSS animations, transitions, and Web Animations during capture. Useful for a stable visual state. Playwright handles finite and infinite animations according to its documented behavior.
caret Hide the text caret with 'hide'. Prevents a blinking insertion point from appearing in a captured form.
mask Cover selected locator bounding boxes. Do not mask information that needs to be visible as evidence. Masks cover element bounds, not arbitrary semantic data.
style Apply a stylesheet for the screenshot operation. Use cautiously: hiding or changing page content can make an evidentiary screenshot misleading.

Consult the [Playwright screenshot API reference](https://playwright.dev/docs/api/class-page#page-screenshot) for accepted values and details for the Playwright version in your project. A stable capture configuration might look like this:

await page.screenshot({
  path: 'portal-full-page.png',
  fullPage: true,
  type: 'png',
  scale: 'css',
  animations: 'disabled',
  caret: 'hide',
});

3. Handle portal loading and dynamic content

Government portals can differ in sign-in requirements, content loading, and automation behavior. The supplied Playwright API documentation does not describe a particular Indian portal, its terms, or its dynamic content. Follow the selected site’s access guidance, capture only information you are authorized to access, and avoid exposing personal or session data in screenshots.

  • Wait for a known element: If the page shell appears before its content, wait for a stable heading or content locator before capturing. Prefer a specific element to an arbitrary long sleep.
  • Use the intended workflow: If a table or section loads after scrolling, clicking, or submitting a form, complete that step through the authorized flow and verify the content first.
  • Choose navigation readiness deliberately: waitUntil: 'load' waits for the load event. Some pages continue fetching data afterward; add a locator wait for the content you need. Network activity may never fully settle on pages with long polling or analytics, so an unbounded wait for all network traffic is not a reliable substitute for a content check.
  • Keep sensitive state out of artifacts: A screenshot may include names, identifiers, notices, or account details. Review the image and store or share it only as permitted.

4. Check the result

  1. Confirm the script exited successfully and the file exists.
  2. Open the image and check the top, bottom, and any sections expected to load dynamically.
  3. Check that text is legible and that the screenshot has not included unintended private information.
  4. If you need a repeatable capture, keep the viewport, browser version, URL, wait condition, and screenshot options consistent.

5. Troubleshooting

Symptom Likely cause Fix
The screenshot shows only the first screen. fullPage was omitted or set to false, or the saved file is an older output. Set fullPage: true, use a fresh output path, and confirm the script is capturing the intended page.
The image is blank or shows an error page. The navigation failed, returned an HTTP error, redirected, or the expected content did not render. Inspect the response status and final page URL, then wait for a known content locator. Check the page manually under the same authorized access conditions.
Lower sections or table rows are missing. The page loads content only after scrolling or another interaction. Use the normal authorized page workflow to make the content appear before capturing, then verify it in the image.
The script times out at navigation. The server is slow, the page has ongoing requests, or the chosen readiness condition is too strict. Set an appropriate navigation timeout and wait for the specific content needed. Avoid treating a generic network-idle state as proof that the page is ready.
Text is too small or the file is unexpectedly large. Device-pixel scaling, a very long page, or a high-detail image format creates large dimensions. Try scale: 'css'; compare PNG with JPEG or WebP if lossy compression is acceptable. Verify readability after changing format.
The capture differs between runs. Animations, rotating content, time-dependent data, or changing page state. Use animations: 'disabled' where appropriate, set a consistent viewport, wait for a stable locator, and record the capture time if the page data changes.
The browser executable is missing. The Playwright package is installed, but its browser was not downloaded in this environment. Run npx playwright install chromium in the project environment.
The portal denies access or presents a verification challenge. The site requires a user workflow or restricts the request. Follow the portal’s instructions and access rules. Do not treat a challenge or denial page as the requested page capture.

6. Performance, reliability, and cost

Capture time depends on the portal’s response, the amount of content, image loading, browser startup, and the screenshot’s pixel dimensions. A full-page image of a long page can consume more memory and disk space than a viewport image; device-pixel scale and lossless PNG can increase output size. Use CSS scale and a suitable output format when those trade-offs fit, but check that text and fine details remain usable.

For repeatable results, pin the Playwright dependency in the project lockfile, install the matching browser in the runtime, use a known viewport, wait for content that matters, and check the HTTP response and output image. A screenshot is a visual record, not a guarantee that every item on the page loaded or that the page is accurate for another time or session.

Playwright is software; this method does not require a screenshot API subscription. Budget for the machine or CI runtime that launches the browser, storage for output files, and any infrastructure used to run the capture. No fixed runtime or file-size figure applies to every portal.

7. Optional accessibility check

A screenshot is not an accessibility audit. Playwright’s accessibility guidance describes checks for detectable issues such as difficult color contrast, unlabeled form controls, and duplicate IDs. You can run a separate analysis with @axe-core/playwright; treat its findings as a check for some detectable issues, not proof that a portal is fully accessible. [Playwright accessibility testing](https://playwright.dev/docs/accessibility-testing)

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. Its one-call API can return a screenshot as PNG, JPEG, or WebP; the example saves the response body as WebP. See the ScreenshotNeo API documentation for options and setup.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://portal.example.gov.in -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://portal.example.gov.in"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://portal.example.gov.in',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo returned HTTP ${res.status}`);
await Bun.write('shot.webp', res);

ScreenshotNeo accepts cookie and consent banners as 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 and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Every feature is on every plan. [Create a free ScreenshotNeo account](https://screenshotneo.com/account/sign-up/).

FAQ

Does fullPage include content behind a tab or collapsed section?

Only if that content is present in the rendered page state captured. Open or load the section through the authorized page workflow first, then inspect the output.

Can I use a screenshot as proof that a portal record is current?

A screenshot records a visual state at capture time. Keep relevant context such as the page URL and capture time separately, and follow the portal’s rules for evidence and record handling.

Does a screenshot tell me whether a page is accessible?

No. It records appearance. Run a separate accessibility check and review results in context; neither a screenshot nor an automated scan establishes full accessibility.