How to Track Visual Changes to an Indian Airline Booking Page
Build repeatable Playwright screenshot checks for an airline booking journey, review visual diffs safely, and handle dynamic booking data without masking regressions.
Use Playwright Test visual comparisons to capture a known airline booking state as a baseline, then compare later runs with await expect(page).toHaveScreenshot(). Keep the browser, viewport, locale, test data, and journey state consistent; review each diff before updating the baseline. Stop the test before any real booking or payment.
A booking site is a sequence of screens, not one static page. Choose the exact state you want to monitor—such as flight search results or passenger details—and give each state its own screenshot. Air India describes a journey that proceeds from trip details through flight selection and passenger details to payment; IndiGo also describes a self-service View/Change Booking area. These are useful reminders to monitor the relevant state rather than only the homepage. Air India’s eZ Booking announcement describes another interaction style, available to Maharaja Club members when announced in January 2025.
1. Choose a safe, repeatable booking state
Decide what visual change matters before automating the browser. Examples include the search-results layout, fare cards, baggage information, passenger form, or a booking-management screen. Use a public page that does not require a transaction, or a controlled test account and environment. If authentication is necessary, use a dedicated account and test data with appropriate access controls.
- Do not submit a real booking, enter payment details, or let a scheduled run continue into payment.
- Choose deterministic trip inputs where the site permits them. Availability and offers can change independently of the interface.
- Save a separate named screenshot for each journey state that matters. A search-results baseline does not validate the passenger form.
- For logged-in states, keep account permissions and stored session data limited to the monitoring job.
Airline booking flows and self-service areas can have multiple steps and interaction patterns. IndiGo’s flight reservation FAQs describe View/Change Booking functions; its developer portal describes NDC APIs and technical integration context. API monitoring can provide useful service data, but it does not establish that the rendered page looks correct.
2. Set up Playwright Test
The example below uses JavaScript with Playwright Test. It targets a URL and state you control. Replace the example URL, trip inputs, and the clearly marked selectors with ones verified in your own permitted test environment. Airline page markup and access rules can change, so there is no universal selector or guaranteed public test route.
mkdir airline-visual-check
cd airline-visual-check
npm init -y
npm install --save-dev @playwright/test
npx playwright install chromium
Create playwright.config.js to fix the browser project and rendering conditions. Run baseline creation and later comparisons in the same operating environment and browser version; pinning the package version in the lockfile helps keep the Playwright version consistent.
// playwright.config.js
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
testDir: './tests',
workers: 1,
retries: 0,
use: {
browserName: 'chromium',
headless: true,
viewport: { width: 1365, height: 900 },
locale: 'en-IN',
timezoneId: 'Asia/Kolkata',
colorScheme: 'light',
reducedMotion: 'reduce',
trace: 'retain-on-failure',
},
expect: {
timeout: 15_000,
toHaveScreenshot: {
animations: 'disabled',
caret: 'hide',
// Keep this strict initially. Increase only after reviewing recurring noise.
maxDiffPixelRatio: 0.01,
},
},
});
Set maxDiffPixelRatio only if the installed Playwright version supports it; otherwise omit that setting and use the supported screenshot options documented for your version. A tolerance can prevent tiny rendering noise from failing a run, but a permissive threshold can hide a small real change.
3. Write a journey check and capture the baseline
Create tests/booking-visual.spec.js. This version monitors a search-results-like state using placeholders; adapt the navigation and assertions to a safe test route and stable page landmarks. The explicit check before the screenshot makes a login wall or error page less likely to be mistaken for the intended baseline.
// tests/booking-visual.spec.js
const { test, expect } = require('@playwright/test');
test('airline flight results remain visually reviewable', async ({ page }) => {
// Replace with a permitted, repeatable test URL.
await page.goto('https://example.com/your-test-search-route', {
waitUntil: 'domcontentloaded',
});
// Replace with a stable heading or landmark on the expected state.
await expect(page.getByRole('heading', { name: 'Replace with results heading' }))
.toBeVisible();
// Optional: dismiss a consent prompt only if that is part of your intended
// test setup and the control is stable in your test environment.
// await page.getByRole('button', { name: 'Accept' }).click();
// Keep the screenshot scoped to the meaningful results region when possible.
// Replace '[data-test=results]' with a selector verified on your test page.
await expect(page.locator('[data-test=results]'))
.toHaveScreenshot('flight-search-results.png');
});
To create the first reference, run:
npx playwright test
The initial run writes a reference image because none exists yet. Inspect it, then commit the generated snapshot directory alongside the test. On subsequent runs, Playwright compares the new image to that reference. Its screenshot assertion waits for two consecutive screenshots to match before comparison, which helps with transient rendering but cannot make live inventory deterministic. See the official visual comparison guide.
4. Stabilize rendering without hiding meaningful changes
Playwright warns that screenshots can vary with operating system, browser version, browser settings, hardware, power source, and headless mode. Use the same baseline environment for later captures. Also keep the viewport, device scale factor, locale, timezone, color scheme, fonts, and journey inputs fixed where possible. Playwright’s visual comparison documentation explains these environment differences and baseline behavior.
Choose what belongs in the comparison
- Keep: fare layout, booking controls, labels, validation messages, passenger fields, baggage information, and any content whose visual change you want to detect.
- Stabilize or exclude selectively: a clock, rotating promotion, personalized greeting, or other region that is irrelevant to the check and changes on every run.
- Investigate before masking: flight prices and availability may be dynamic, but those may also be exactly what the test is intended to monitor. Masking them would defeat that objective.
Prefer stable fixtures or a controlled environment over hiding large areas. If a small region truly is outside scope, use a screenshot stylesheet. This example hides one region only; replace the selector with a narrow, reviewed target.
/* tests/visual-stability.css */
/* Example only: use a narrow selector verified in your own environment. */
[data-test="volatile-clock"] {
visibility: hidden !important;
}
// In the test, load the reviewed stylesheet for this screenshot only.
const path = require('node:path');
await expect(page.locator('[data-test=results]')).toHaveScreenshot(
'flight-search-results.png',
{ stylePath: path.join(__dirname, 'visual-stability.css') },
);
Playwright also supports masking locators and screenshot options such as animation handling, caret behavior, thresholds, and clipping. Use the options documented for your installed version in the PageAssertions API reference. Avoid raising thresholds or masking content just to make a failing comparison pass.
5. Run checks and review visual diffs
Run the same command in local development and CI. On failure, inspect the expected image, actual image, and generated diff before deciding whether the page regressed or the baseline should change. Keep the review attached to the code change or monitoring incident where possible.
# Run the visual check
npx playwright test
# Open the HTML report after a run
npx playwright show-report
Update snapshots only after confirming that the change is intended and the capture state is correct:
# Update changed snapshots after review
npx playwright test --update-snapshots
Do not make automatic baseline updates part of a routine scheduled run. That would accept unexpected changes without review. BrowserStack documents an optional integration that routes Playwright toHaveScreenshot() assertions through Percy for hosted visual review; native Playwright comparison is sufficient to get started. Check current service plans and data-handling terms directly before adopting a hosted workflow. BrowserStack’s Percy and Playwright guide describes the integration.
6. Add browser-independent screenshot sampling when useful
Playwright visual assertions are the core regression check because they compare against a baseline under a controlled browser setup. For a separate, occasional screenshot of a public page or test URL, ScreenshotNeo can capture a page through one GET request. It can also remove known consent banners, newsletter popups, and chat widgets before capture. A screenshot by itself is a sample, not a baseline comparison or proof that a booking flow works.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://www.airindia.com/ \
-o airline-page.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={
"access_key": "YOUR_API_KEY",
"url": "https://www.airindia.com/",
},
timeout=90,
)
r.raise_for_status()
with open("airline-page.webp", "wb") as image:
image.write(r.content)
Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://www.airindia.com/',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('airline-page.webp', image));
See the ScreenshotNeo API documentation for request options. For repeatable visual regression tracking, save the captured images and compare them under a consistent process; the API capture does not replace Playwright’s journey automation or human diff review.
7. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request captures a URL as PNG, JPEG, WebP, or PDF. Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://www.airindia.com/ \
-o airline-page.webp
ScreenshotNeo also provides an MCP server for AI agents using Claude, Cursor, or another MCP client, with take_screenshot, get_page_info, and capture_pdf tools. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. See the docs for the API parameters and setup, then sign up for 1,000 free screenshots a month with no card.
8. Reliability, performance, and cost
Reliability
- Run captures in a stable, pinned environment and preserve the browser and OS context used to create the baseline.
- Make failures diagnosable: retain traces on failure and keep screenshots and reports as CI artifacts.
- Check for the expected journey state before capturing. A consent overlay, sign-in page, bot check, or error page should be surfaced as a distinct failure, not blessed as a new baseline.
- Separate visual assertions from functional checks. A screenshot can show that something looks different; it does not prove that a booking action or backend service behaves correctly.
- Use a controlled cadence appropriate to the page and environment. Frequent polling can encounter rate limits or add unnecessary load; follow the site’s terms and access guidance.
Performance and cost
Browser startup, page load, client-side rendering, and image loading dominate the runtime of a browser-based check. Capture only the states and regions that answer a real monitoring question. Keep workers limited for a third-party booking site, and avoid parallel runs that repeat the same journey unnecessarily. Playwright Test itself is open-source tooling; CI execution, browser infrastructure, and any hosted visual-review service may have their own costs. The research sources do not establish current Percy pricing.
ScreenshotNeo pricing is Free: 1,000 shots/month; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; Business: $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. These are screenshot capture costs and do not turn a capture into a visual comparison or a guaranteed airline transaction monitor.
9. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Snapshot does not exist | This is the first run, or the snapshot path/platform differs. | Review the generated image as a candidate baseline, then commit it. Use the same project and environment for later runs. |
| Large diff on every run | Different browser or OS, viewport, fonts, locale, timezone, live offers, or journey state. | Align capture conditions and test data. Identify the changing region before considering a narrow mask. |
| Heading or results selector times out | The page did not reach the expected state, the selector changed, or the site presented a gate/error screen. | Inspect the trace and actual screenshot; verify the route and selector against the permitted test page. |
| Screenshot includes a loading skeleton | The test captured before the content was ready. | Wait for a stable, meaningful landmark or a test-owned readiness condition. Avoid arbitrary long sleeps where a state assertion can be used. |
| Intermittent pixel noise | Animation, blinking caret, rotating content, or rendering variation. | Disable animations and hide the caret; stabilize the source if possible. Use a small tolerance only after reviewing diffs. |
| Baseline update hides a regression | Snapshots were updated without reviewing actual and diff images. | Revert the baseline change and repeat the run. Approve updates only after confirming the visual change is intended. |
| Capture shows CAPTCHA or blank/error page | The site blocked automation, the request failed, or the page did not load as expected. | Do not treat it as a valid baseline. Check access permissions and the failure details; use a controlled test environment if available. |
| Test accidentally reaches purchase steps | The journey lacks an explicit stopping point. | End the test at the monitored state and do not fill or submit payment details. Keep test accounts and credentials isolated. |
10. FAQ
Can I track an airline page without signing in?
Yes, if the state you need is publicly reachable and permitted for automated access. Sign-in-dependent screens require an appropriately controlled test account or test environment.
Should I compare the whole page or one element?
Compare the smallest region that fully represents the question. Use a page screenshot for overall layout changes and a locator screenshot for a specific results panel or form. Keep separate checks when both matter.
Can an airline API replace visual monitoring?
No. Airline APIs can provide structured service or inventory information, but they do not confirm how the booking interface renders to a user. IndiGo’s developer portal is useful for API context; rendered-page checks answer a different question.
Can I automatically accept every new screenshot?
That removes the value of regression tracking. Review the diff and confirm the change is expected before updating a reference image.


