How to Screenshot Product Prices on BigCommerce with Playwright
Use Playwright to find and capture a BigCommerce product price reliably. Learn how to choose a store-specific locator, wait for price updates, and save focused or contextual screenshots.
Use Playwright to open the product page, inspect its rendered markup, locate the price in the context of the correct product, wait until that price is ready, then take a screenshot of the price or the surrounding page. There is no single price selector that works across every BigCommerce storefront: themes and custom storefronts can render different markup, so verify the locator against the target store.
This guide uses Playwright’s JavaScript API. It shows how to capture a price element, preserve product context, handle delayed or changing prices, and save a repeatable image.
1. Install Playwright and prepare a script
For a one-off capture, install Playwright and its Chromium browser in a project directory:
npm init -y
npm install playwright
npx playwright install chromium
Save the following as screenshot-price.js. Set PRODUCT_URL to the product page and update the locator after inspecting that storefront’s rendered markup.
const { chromium } = require('playwright');
const productUrl = process.env.PRODUCT_URL;
if (!productUrl) {
throw new Error('Set PRODUCT_URL to a BigCommerce product page URL.');
}
(async () => {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1440, height: 1000 },
locale: 'en-US',
});
try {
const page = await context.newPage();
await page.goto(productUrl, { waitUntil: 'domcontentloaded', timeout: 60000 });
// Replace this example with a locator verified on the target storefront.
// Prefer an accessible locator or an explicit test ID if the store provides one.
const price = page.getByTestId('product-price');
await price.waitFor({ state: 'visible', timeout: 15000 });
await price.screenshot({ path: 'product-price.png', type: 'png' });
} finally {
await browser.close();
}
})().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Run it with PRODUCT_URL='https://store.example/product/' node screenshot-price.js. The sample test ID is illustrative; it will work only if the page actually exposes that test ID. Do not treat it as a BigCommerce-wide selector.
2. Inspect the store and choose a price locator
Playwright locators are designed to wait and retry as the page changes. Its locator guidance recommends selecting elements by user-facing semantics or an explicit test contract, such as a test ID, where those are available. CSS and XPath selectors tied to DOM structure can break when the implementation changes. See the Playwright locator guide.
- Open the exact product page and the same locale, variant, and customer state that the screenshot should represent.
- Inspect the rendered page in browser developer tools. Find the visible price and determine whether it has an accessible name, a stable test ID, or a useful product-specific container.
- Scope the price lookup to the relevant product container when the page has multiple products, prices, or recommendations.
- Check the locator against the actual rendered price before capturing. Confirm it resolves to one intended, visible element.
For example, if the store exposes an appropriate accessible label, use a role or label locator. If it provides a testing contract, use that test ID. If neither exists, use a CSS locator based on the markup you inspected and keep it narrow enough to identify the intended price. Avoid copying a selector from another BigCommerce theme and assuming it applies here.
// Examples only: choose one that matches the inspected page.
const byTestId = page.getByTestId('product-price');
const byLabel = page.getByLabel('Price');
const byText = page.getByText('$49.00', { exact: true });
const byCss = page.locator('[data-product-price]');
These examples are not interchangeable. A label may not be exposed; price text can vary; and the CSS attribute may not exist. Prefer a stable contract provided by the site, then verify the actual match.
3. Wait for the price to be ready
A navigation event alone does not guarantee that a product price has rendered or settled. Store scripts may update product details after the document loads, and selecting a variant can change the displayed price. Choose a readiness condition based on what the page does.
// Wait for the exact price element to appear and become visible.
await price.waitFor({ state: 'visible', timeout: 15000 });
// If the page has a known loading indicator, wait for it to disappear.
await page.locator('.product-loading-indicator').waitFor({
state: 'hidden',
timeout: 15000,
});
// If the task requires a particular variant, select it before waiting
// for and capturing the resulting price.
// await page.getByLabel('Size').selectOption('large');
await price.waitFor({ state: 'visible', timeout: 15000 });
The loading-indicator selector and variant control above are examples. Replace them with elements present on the target page. If the application updates the price in place, wait for the expected price text or other store-specific state rather than assuming that the first visible price is the final one.
4. Capture the price or include product context
Use a locator screenshot when the price itself is the evidence. Use a page screenshot when a reviewer needs to see which product the price belongs to. Playwright documents both page and locator screenshot methods, along with options such as output path, image type, full-page capture, scale, and masking.
// Focused evidence: capture only the resolved price.
await price.screenshot({ path: 'product-price.png', type: 'png' });
// Context: capture the current viewport around the product.
await page.screenshot({ path: 'product-context.png', type: 'png' });
// Content below the viewport: capture the entire page.
await page.screenshot({
path: 'product-full-page.png',
fullPage: true,
type: 'png',
});
A locator screenshot scrolls the element into view when needed. A viewport screenshot records what is currently visible; use full-page capture when the product information is below the fold. If the page has sensitive or distracting content, Playwright’s page screenshot options support masking matched locators. Mask only content that is irrelevant to the purpose of the screenshot.
5. Make repeat captures comparable
For visual comparisons, keep the browser version, operating system, viewport, locale, color scheme, and capture settings consistent. Playwright notes that browser rendering can differ with the host operating system, browser version, settings, hardware, power source, and headless mode; see its visual comparison guidance.
- Set a fixed viewport and device scale factor in the browser context.
- Set the intended locale when currency, language, or localized product information matters.
- Use the same browser and runtime environment across captures.
- Wait for the same product state, including the same variant or sale state.
- Use a consistent file type and output naming scheme.
BigCommerce storefront themes contain their own templates, JavaScript, and assets, so the rendered page depends on the storefront implementation. For localized storefronts, select the intended locale before capture. The BigCommerce documentation describes Stencil theme structure and Catalyst multi-language behavior.
6. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Locator timeout | The selector is not present, the price has not loaded, or the page is in a different state. | Inspect the rendered DOM and confirm the locator matches the intended element. Wait for the store-specific loading or product state. |
| Strict mode violation or multiple matches | The locator finds several prices, such as a sale price, original price, or recommendation card. | Scope it to the correct product container and refine the locator. Check which price the task requires. |
| Screenshot shows a stale or unexpected price | The page updated the price after initial rendering or the selected variant differs. | Set the intended variant and locale, then wait for a known expected state before capturing. |
| Price element is hidden | The theme renders desktop and mobile price nodes, or a hidden template alongside the visible price. | Inspect visibility and scope the locator to the active product area or intended viewport. |
| Screenshot is clipped or lacks context | A locator screenshot captures the element only, or the relevant content is outside the viewport. | Use a page viewport screenshot for context, or set fullPage: true when below-the-fold content matters. |
| Images or layout differ between runs | Browser or host conditions, viewport, locale, or page state changed. | Pin the browser environment and context settings, and capture the same product state consistently. |
| Navigation times out | The page may keep background requests open or load slowly. | Use an appropriate navigation condition such as domcontentloaded, then separately wait for the price and any required page state. Increase the timeout only when the store’s expected load time warrants it. |
7. Performance, reliability, and cost
Launching a browser has more setup and runtime overhead than calling a screenshot API, but it gives you direct control over navigation, state, locator choice, and capture scope. Reuse a browser process for batches of pages when practical, create a separate context for isolated locale or session state, and avoid waiting for all network activity to stop unless the page actually needs that condition. Third-party analytics or chat requests can remain active after the product price is ready.
For reliable captures, fail clearly when the price locator does not resolve, record the product URL and relevant locale or variant alongside the image, and keep selector checks close to the storefront code or capture workflow. Screenshot comparison should use a stable browser and host, because environmental rendering differences can create image changes unrelated to the price.
Playwright is an open-source browser automation framework; this workflow’s direct costs depend on where the script runs and the compute resources it uses. If you prefer a managed request instead of operating a browser, see the option below.
8. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request can return a screenshot or PDF. Its capture flow accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response includes page-verdict and billing headers. AI agents can use its MCP server tools, including take_screenshot, get_page_info, and capture_pdf.
For a quick capture, call the API with the product URL. 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://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Replace https://stripe.com with the BigCommerce product URL. ScreenshotNeo offers 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000 screenshots. Learn about ScreenshotNeo or sign up for 1,000 free screenshots a month with no card.
9. FAQ
Does every BigCommerce store use the same price selector?
No. Verify the selector against that storefront’s rendered markup and scope it to the intended product.
Should I capture the price element or the whole page?
Capture the locator for focused price evidence. Capture the viewport or full page when a reviewer needs product context or the relevant content is below the fold.
How do I capture a localized price?
Set the browser context to the intended locale and open the corresponding storefront state before locating and capturing the price.


