How to Compare Mobile and Desktop Website Screenshots for Indian Ecommerce Stores
Compare mobile and desktop store screenshots to find missing content, layout defects, and blocked buying flows—without mistaking responsive changes for bugs.
Compare each mobile screenshot with an approved mobile reference, and each desktop screenshot with its desktop reference. Review the same page, content, and interaction state at both sizes. Look for content that disappears, controls that become hard to use, overflow, clipping, and broken image crops. A mobile page is meant to rearrange itself; a raw pixel difference between mobile and desktop is not evidence of a defect.
For an Indian storefront, set and record the actual locale and storefront state you want to review. Check the language, currency, delivery or pincode information, and payment options the store presents; their availability and presentation vary by store. This guide covers a repeatable manual workflow and a runnable Playwright example.
1. Choose pages and meaningful states
Start with a compact journey through the store. Capture the same pages and states at mobile and desktop sizes:
- Home or campaign landing page, including any promotion that is in scope.
- Collection or listing page, with the expected products and filters.
- Product detail page, including a selected variant and expanded details where relevant.
- Cart, including an empty state if the store supports it.
- Checkout steps available in the review environment, including a validation error if safe test data can trigger one.
Also include interaction states that can change what is visible: an open menu, expanded accordion or tab, selected size or color, applied filter, and validation message. A screenshot of only the initial page can miss content or controls that appear after interaction.
Shopify’s [content parity guidance](https://help.shopify.com/en/manual/online-store/themes/theme-structure/sections-and-blocks) recommends checking that mobile and desktop retain expected content. Its practical checks include sections, text, links, images, accordions, tabs, and structured data. Apply these to the actual store rather than assuming every feature exists.
2. Fix and record capture conditions
Before capturing, write down the conditions so a later comparison is meaningful:
- Page URL and the exact page state, including selected variant, cart contents, or open menu.
- Viewport width and height, browser and version, and device scale factor if controlled.
- Locale, currency or storefront selector state, test account, and catalogue or inventory data.
- Capture timing, such as after a specific selector appears or after a known delay.
- Any authentication, cookie-consent, or test setup needed to reach the page.
Use identical conditions between runs. For a fair mobile-versus-desktop review, keep browser, data, locale, state, and timing consistent while changing the viewport. Lighthouse’s [emulation documentation](https://github.com/GoogleChrome/lighthouse/blob/main/docs/emulation.md) explains its screen emulation settings; its default configuration emulates a mobile device. A configured emulation is useful for repeatable review, but it does not reproduce every physical device or browser behavior.
3. Capture both viewports
Manual capture in Chrome DevTools
- Open the target page in Chrome and set up the intended locale and page state.
- Open DevTools and toggle device emulation.
- Enter a fixed mobile width and height. Capture after images, fonts, and the relevant page state have settled.
- Switch to a fixed desktop viewport, keeping the page state and browser the same, and capture again.
- Name each file with the page, state, viewport, browser, and date or build. For example:
product-blue-mobile-390x844-chrome-build42.png.
Repeat this for every selected page and state. Emulation is an efficient first pass. For high-risk layouts or interactions, confirm on a real mobile browser when one is available.
Automated capture with Playwright and Node.js
This script captures a public product page at one mobile and one desktop viewport. It uses Playwright’s bundled Chromium, waits for the page to load, and writes full-page PNGs. Install Node.js, then run:
mkdir screenshot-review
cd screenshot-review
npm init -y
npm install playwright
npx playwright install chromium
Save as capture.mjs and replace the example URL with a page you are authorized to review:
import { chromium } from 'playwright';
const target = process.env.TARGET_URL ?? 'https://example.com/products/example';
const captures = [
{ name: 'mobile', width: 390, height: 844, deviceScaleFactor: 1 },
{ name: 'desktop', width: 1440, height: 1000, deviceScaleFactor: 1 },
];
const browser = await chromium.launch({ headless: true });
try {
for (const viewport of captures) {
const page = await browser.newPage({
viewport: { width: viewport.width, height: viewport.height },
deviceScaleFactor: viewport.deviceScaleFactor,
locale: 'en-IN',
timezoneId: 'Asia/Kolkata',
});
const response = await page.goto(target, {
waitUntil: 'networkidle',
timeout: 60000,
});
if (!response || !response.ok()) {
throw new Error(`${viewport.name}: navigation failed (${response?.status() ?? 'no response'})`);
}
// Replace this with a page-specific selector when the product content
// becomes ready before the entire page reaches network idle.
await page.locator('body').waitFor({ state: 'visible' });
await page.screenshot({
path: `store-${viewport.name}.png`,
fullPage: true,
animations: 'disabled',
});
await page.close();
}
} finally {
await browser.close();
}
Run it with TARGET_URL='https://your-store.example/products/item' node capture.mjs. The locale and timezone are examples; use the intended storefront settings. This script captures a URL at each viewport, but it does not sign in, populate a cart, select a variant, or open a menu. Add those steps explicitly using the site’s test account and stable selectors. Do not place real customer data or payment details in a visual test.
networkidle may never occur on pages with analytics, chat, or other long-lived network requests. If navigation times out, use waitUntil: 'domcontentloaded' and wait for a reliable page-specific selector, such as the product title or primary action. If lazy-loaded sections are below the fold, scroll them into view or use a capture method that loads them before taking the full-page screenshot.
4. Compare each viewport with its own reference
Keep an approved mobile reference and an approved desktop reference for each relevant browser and state. Compare a new mobile capture to its mobile reference and a new desktop capture to its desktop reference. Comparing the mobile image directly with the desktop image mostly measures expected reflow, changed dimensions, and different line wrapping.
Review images side by side first. A transparent overlay or image diff can help locate changes, but it cannot decide whether a difference is a regression. A baseline is an approved reference capture. Android Developers describes this general pattern in its [screenshot testing guide](https://developer.android.com/training/testing/ui-tests/screenshot): a screenshot test compares a UI capture with a previously approved reference. That page discusses app UI; the baseline idea is useful here, but it is not a web-specific standard.
For recurring pull-request or release checks, a visual testing framework can capture screen, element, or full-page images and compare them to baselines. [WebdriverIO visual testing](https://webdriver.io/docs/visual-testing/) documents these comparison scopes and desktop and mobile browser environments. [BrowserStack Percy responsive testing](https://www.browserstack.com/docs/percy/visual-testing-workflows/view-percy-build-results/responsive-testing) documents captures at specified widths; each width counts as a separate screenshot under its usage model. Choose a workflow based on browser coverage, state setup, baseline review, dynamic-content handling, CI integration, and operational cost. The cited documentation establishes capabilities, not comparative accuracy or value across vendors.
5. Inspect layout, content, and buying actions
At each viewport, check both what is visible and what can be reached by scrolling or interacting. Use this store-focused checklist:
- Product identity: name, price, selected variant, images, description, and specifications remain present and readable. Collapsed details should open correctly.
- Collection content: the expected products and links remain available when the grid changes column count. Check filters and sorting, including their open and applied states.
- Images: images load, use an appropriate crop, and show the intended product. Responsive image delivery may use different asset sizes on mobile and desktop; the displayed subject should still be correct.
- Navigation: menus, search, back navigation, and category links are visible and usable at the intended width.
- Purchase path: variant selection, quantity, primary call to action, cart access, and relevant delivery information are visible and functional.
- Indian storefront details: verify the specific store’s language, currency, delivery or pincode flow, and payment options in the intended locale. Do not infer these from the store being based in India.
- Responsive geometry: look for clipping, overlapping, horizontal page overflow, very narrow text columns, unexpectedly broken line wraps, and controls too close to other controls.
- Hidden content and semantics: confirm important links and content are not missing at one viewport. Where relevant to the review, inspect structured data separately; pixels alone do not show whether it is present.
A viewport that scales the whole desktop page down can make text difficult to read. Chrome’s [viewport sizing guidance](https://developer.chrome.com/docs/lighthouse/pwa/viewport/) covers viewport configuration; the associated legacy Lighthouse PWA audit is deprecated, so do not use that audit as a complete current responsive QA method. A screenshot review also cannot establish accessibility, page speed, or successful order completion by itself. Test those separately.
6. Separate real changes from capture noise
Differences can come from a real code change or from unstable content and rendering. Common sources include rotating promotions, personalized recommendations, changing inventory, time-sensitive banners, animations, font loading, and browser or platform rendering. Before comparing:
- Use stable test data and the same account, locale, and catalogue state.
- Wait for fonts and key content to load; disable animations when your capture tool supports it.
- Keep browser version and viewport configuration fixed for repeat captures.
- Mask only regions that are expected to vary and are not under review. Never mask a product price, promotion, image, or layout simply because it creates a diff.
- Review each visual diff before accepting it. If the change is intentional, document it and update only the affected viewport and state reference.
Platform rendering can introduce small differences, so a diff is a review signal, not automatic proof of a defect. [Percy’s recommended guidelines](https://www.browserstack.com/docs/percy/overview/recommended-guidelines) discuss full-page checks, comparison sensitivity, and reviewing builds.
7. Make the review repeatable
- Build a page-and-state list for the release, assigning an owner where useful.
- Capture the same browser, locale, data, and states at the chosen mobile and desktop viewports.
- Review viewport pairs against their respective approved references.
- Record each finding with the page, viewport, state, expected behavior, actual result, and screenshot.
- Fix confirmed regressions; label intentional updates and refresh the right baseline after review.
- For high-risk flows, repeat key checks on a real device or browser and run functional checks for the interaction itself.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. Capture the same URL at two viewport sizes, then compare the returned images against the matching references. Here is the cURL example; change the URL and add the viewport parameters documented in the [ScreenshotNeo API docs](https://screenshotneo.com/docs/):
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,
)
r.raise_for_status()
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())));
These examples use the supplied basic request shape; consult the docs for viewport configuration and other parameters. Cookie banners and consent dialogs are accepted like a visitor would accept them, and 60+ known consent platforms, newsletter popups, and chat widgets are removed before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and responses identify the page verdict and billing status in headers. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up for ScreenshotNeo’s free plan and get 1,000 screenshots a month with no card.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Mobile and desktop diff is enormous | You compared different viewport sizes directly or against the wrong reference. | Compare mobile to mobile and desktop to desktop, using matching page state and browser settings. |
| Playwright navigation times out | Analytics, chat, or another persistent request prevents network idle, or the page is slow. | Wait for domcontentloaded and then a stable, page-specific selector; set a suitable timeout. |
| Product content is missing in one image | It may be below the fold, lazy-loaded, hidden behind an accordion, or absent due to a different state. | Scroll to load lazy content, capture the expanded state, and confirm the same variant and data were used. |
| Diffs appear without a code change | Dynamic promotions, personalization, inventory, fonts, animation, or platform rendering changed. | Stabilize data and timing, fix browser settings, and mask only genuinely out-of-scope variable regions. |
| Mobile content is cut off or page scrolls sideways | A fixed-width element, oversized image, or layout rule exceeds the viewport. | Inspect the element at the narrow width and fix its responsive sizing; do not accept the diff as harmless without review. |
| Automated capture shows a consent wall or sign-in page | The capture context lacks the expected cookie state, session, or access. | Use an authorized test session and reproduce the intended storefront state. Do not treat a gated page as the product page baseline. |
| Checkout screenshots differ between runs | Cart contents, inventory, session state, address, or validation state is unstable. | Reset the test cart and use controlled test data; capture each checkout state explicitly. |
| ScreenshotNeo response is not an image | The request may have returned an error or a non-clean page verdict. | Check HTTP status and response headers, including X-Page-Verdict and X-Billed; check the API docs for request parameters and credentials. |
Performance, reliability, and cost
Each additional page, state, viewport, browser, and device creates more capture and review work. Prioritize high-traffic templates and risky purchase steps, then expand coverage where regressions occur. Full-page captures reveal content below the fold but take longer to inspect; element captures are useful for a component question but can miss page-level overflow and interactions.
Keep the capture matrix stable and small enough to run regularly. Reuse test data, avoid needless duplicate states, and treat a failed capture as an infrastructure or setup issue to diagnose rather than as a visual pass. Keep browser and device emulation details with the baseline so a later rendering change is interpretable. For a hosted capture API, account for its plan limits and verify each result before using it as a reference. ScreenshotNeo plans are 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), and Business ($249 for 1,000,000); yearly billing gives two months free, and every feature is on every plan.
FAQ
Should the mobile and desktop screenshots look the same?
No. The layout can change with width. Check that content and essential actions remain available and usable, then compare each viewport to its own reference.
How many viewport widths should I capture?
At minimum, capture the mobile and desktop widths that matter to your users and supported layouts. Add widths near breakpoints where the design changes or where defects have appeared.
Does a screenshot comparison prove checkout works?
No. It shows visible output for the captured state. Run functional checks for variant selection, cart updates, validation, and checkout completion separately.
Do I need a real phone?
Emulation is useful for repeatable broad checks. Confirm high-risk layouts and interactions in a real mobile browser when one is available.


