Guide

Screenshot Testing for E-commerce: Cart, Checkout, and Product Pages

Ensure your e-commerce site looks perfect across all customer touchpoints with automated visual testing.

Asad AliOctober 28, 20257 min read

E-commerce sites have unique visual testing challenges—product images, dynamic pricing, cart states, and checkout flows all need verification. This guide covers screenshot strategies for comprehensive e-commerce testing.

E-commerce Testing Challenges

Dynamic Content

  • Product prices change
  • Stock levels fluctuate
  • Personalized recommendations
  • Sale banners and promotions
  • Cart quantities and totals

Critical Pages

Page Testing Priority
Product detail page High
Category/listing page High
Cart Critical
Checkout Critical
Order confirmation Critical
Homepage Medium
Account pages Medium

Product Page Testing

Capture Product Galleries

async function testProductPage(productUrl) {
  // Main product image
  const mainImage = await captureScreenshot(productUrl, {
    viewport: { width: 1440, height: 900 },
    waitFor: '.product-image',
  });
  
  // Test image gallery navigation
  const galleryImages = await captureWithInteraction(productUrl, [
    { action: 'click', selector: '.gallery-thumbnail:nth-child(2)' },
    { action: 'wait', duration: 500 },
    { action: 'screenshot', name: 'gallery-image-2' },
    { action: 'click', selector: '.gallery-thumbnail:nth-child(3)' },
    { action: 'wait', duration: 500 },
    { action: 'screenshot', name: 'gallery-image-3' },
  ]);
  
  return { mainImage, galleryImages };
}

Test Product Variants

async function testProductVariants(productUrl, variants) {
  const screenshots = {};
  
  for (const variant of variants) {
    // Select variant (size, color, etc.)
    const screenshot = await captureWithInteraction(productUrl, [
      { action: 'click', selector: `[data-variant="${variant}"]` },
      { action: 'wait', duration: 300 },
      { action: 'screenshot' },
    ]);
    
    screenshots[variant] = screenshot;
  }
  
  return screenshots;
}

// Usage
const variants = ['red', 'blue', 'black'];
const variantScreenshots = await testProductVariants(
  'https://store.com/product/t-shirt',
  variants
);

Out of Stock States

const OUT_OF_STOCK_TEST_PRODUCTS = [
  'https://store.com/product/out-of-stock-item',
  'https://store.com/product/low-stock-item',
];

async function testStockStates() {
  const results = [];
  
  for (const url of OUT_OF_STOCK_TEST_PRODUCTS) {
    const screenshot = await captureScreenshot(url);
    
    // Verify out of stock styling is visible
    const hasOutOfStockLabel = await checkElement(url, '.out-of-stock-label');
    const buyButtonDisabled = await checkElement(url, 'button[disabled]');
    
    results.push({
      url,
      screenshot,
      hasLabel: hasOutOfStockLabel,
      buttonDisabled: buyButtonDisabled,
    });
  }
  
  return results;
}

Cart Testing

Empty Cart

async function testEmptyCart() {
  // Clear any existing cart
  await clearCart();
  
  const screenshot = await captureScreenshot('https://store.com/cart', {
    waitFor: '.empty-cart',
  });
  
  return screenshot;
}

Cart with Items

async function testCartWithItems() {
  // Add items to cart
  await addToCart([
    { product: 'SKU-001', quantity: 1 },
    { product: 'SKU-002', quantity: 2 },
  ]);
  
  const screenshot = await captureScreenshot('https://store.com/cart', {
    waitFor: '.cart-items',
  });
  
  // Verify quantities and totals are visible
  return screenshot;
}

Cart Updates

async function testCartQuantityChange() {
  await addToCart([{ product: 'SKU-001', quantity: 1 }]);
  
  const screenshots = await captureWithInteraction('/cart', [
    { action: 'screenshot', name: 'initial' },
    { action: 'click', selector: '.quantity-increase' },
    { action: 'wait', duration: 500 },
    { action: 'screenshot', name: 'after-increase' },
    { action: 'type', selector: '.quantity-input', text: '5' },
    { action: 'wait', duration: 500 },
    { action: 'screenshot', name: 'quantity-5' },
  ]);
  
  return screenshots;
}

Checkout Flow Testing

Multi-Step Checkout

async function testCheckoutFlow() {
  // Set up cart
  await addToCart([{ product: 'SKU-001', quantity: 1 }]);
  
  const checkoutScreenshots = [];
  
  // Step 1: Cart review
  checkoutScreenshots.push(await captureScreenshot('/checkout', {
    waitFor: '.checkout-step-1',
    name: 'step-1-cart',
  }));
  
  // Step 2: Shipping info
  await fillForm('.shipping-form', TEST_SHIPPING_INFO);
  checkoutScreenshots.push(await captureScreenshot('/checkout/shipping', {
    waitFor: '.checkout-step-2',
    name: 'step-2-shipping',
  }));
  
  // Step 3: Payment
  checkoutScreenshots.push(await captureScreenshot('/checkout/payment', {
    waitFor: '.checkout-step-3',
    name: 'step-3-payment',
  }));
  
  // Step 4: Review
  checkoutScreenshots.push(await captureScreenshot('/checkout/review', {
    waitFor: '.checkout-step-4',
    name: 'step-4-review',
  }));
  
  return checkoutScreenshots;
}

Guest vs Logged-In Checkout

async function testCheckoutStates() {
  const results = {};
  
  // Guest checkout
  await clearSession();
  results.guest = await captureScreenshot('/checkout', {
    waitFor: '.guest-checkout',
  });
  
  // Logged-in checkout
  await login(TEST_USER);
  results.loggedIn = await captureScreenshot('/checkout', {
    waitFor: '.user-checkout',
  });
  
  // Saved address loaded
  await selectSavedAddress();
  results.savedAddress = await captureScreenshot('/checkout', {
    waitFor: '.saved-address',
  });
  
  return results;
}

Error States

async function testCheckoutErrors() {
  const errorScreenshots = [];
  
  // Invalid card
  await fillPaymentForm({
    cardNumber: '4000000000000002', // Decline test card
  });
  await submitCheckout();
  errorScreenshots.push(await captureScreenshot('/checkout/payment', {
    waitFor: '.payment-error',
    name: 'payment-declined',
  }));
  
  // Expired card
  await fillPaymentForm({
    expiry: '01/20',
  });
  await submitCheckout();
  errorScreenshots.push(await captureScreenshot('/checkout/payment', {
    waitFor: '.expiry-error',
    name: 'card-expired',
  }));
  
  // Invalid shipping
  await fillShippingForm({
    zipCode: '00000',
  });
  errorScreenshots.push(await captureScreenshot('/checkout/shipping', {
    waitFor: '.shipping-error',
    name: 'invalid-shipping',
  }));
  
  return errorScreenshots;
}

Mobile Testing

Mobile Product Pages

const MOBILE_PRODUCTS = [
  '/product/featured-item',
  '/product/best-seller',
];

async function testMobileProductPages() {
  const results = [];
  
  for (const url of MOBILE_PRODUCTS) {
    results.push({
      url,
      portrait: await captureScreenshot(url, {
        viewport: { width: 375, height: 812 },
      }),
      landscape: await captureScreenshot(url, {
        viewport: { width: 812, height: 375 },
      }),
    });
  }
  
  return results;
}

Mobile Checkout

async function testMobileCheckout() {
  await addToCart([{ product: 'SKU-001', quantity: 1 }]);
  
  const screenshots = [];
  const steps = ['/cart', '/checkout', '/checkout/shipping', '/checkout/payment'];
  
  for (const step of steps) {
    screenshots.push(await captureScreenshot(step, {
      viewport: { width: 375, height: 812 },
      fullPage: true,
    }));
  }
  
  return screenshots;
}

Price Verification

Capture Price Display

async function testPriceDisplay(productUrl) {
  const screenshot = await captureScreenshot(productUrl, {
    waitFor: '.product-price',
  });
  
  // Also verify specific price elements
  const priceElement = await captureElement(productUrl, '.product-price');
  const salePrice = await captureElement(productUrl, '.sale-price');
  const regularPrice = await captureElement(productUrl, '.regular-price');
  
  return { full: screenshot, priceElement, salePrice, regularPrice };
}

Sale/Promotion States

async function testPromotionalPricing() {
  // Regular price
  const regular = await captureScreenshot('/product/item', {
    name: 'regular-price',
  });
  
  // With promo code
  await applyPromoCode('SAVE20');
  const withPromo = await captureScreenshot('/cart', {
    name: 'with-promo',
  });
  
  // Flash sale styling
  const flashSale = await captureScreenshot('/product/flash-sale-item', {
    name: 'flash-sale',
  });
  
  return { regular, withPromo, flashSale };
}

Category/Listing Pages

Grid vs List View

async function testListingViews(categoryUrl) {
  const screenshots = {};
  
  // Grid view
  screenshots.grid = await captureScreenshot(`${categoryUrl}?view=grid`, {
    fullPage: true,
  });
  
  // List view
  screenshots.list = await captureScreenshot(`${categoryUrl}?view=list`, {
    fullPage: true,
  });
  
  return screenshots;
}

Filters and Sorting

async function testFiltersAndSort(categoryUrl) {
  const screenshots = [];
  
  // Apply price filter
  screenshots.push(await captureScreenshot(`${categoryUrl}?price=0-50`, {
    name: 'price-filter',
  }));
  
  // Apply size filter
  screenshots.push(await captureScreenshot(`${categoryUrl}?size=large`, {
    name: 'size-filter',
  }));
  
  // Sort by price low to high
  screenshots.push(await captureScreenshot(`${categoryUrl}?sort=price-asc`, {
    name: 'sort-price-asc',
  }));
  
  return screenshots;
}

Test Organization

Page Object Pattern

class ProductPageTest {
  constructor(baseUrl) {
    this.baseUrl = baseUrl;
  }
  
  async captureMain() {
    return captureScreenshot(this.baseUrl);
  }
  
  async captureVariant(variant) {
    return captureWithInteraction(this.baseUrl, [
      { action: 'click', selector: `[data-variant="${variant}"]` },
      { action: 'screenshot' },
    ]);
  }
  
  async captureZoom() {
    return captureWithInteraction(this.baseUrl, [
      { action: 'hover', selector: '.product-image' },
      { action: 'screenshot' },
    ]);
  }
}

class CheckoutFlowTest {
  async runFullFlow() {
    const screenshots = {};
    screenshots.cart = await captureScreenshot('/cart');
    screenshots.checkout = await captureScreenshot('/checkout');
    // ... more steps
    return screenshots;
  }
}

Best Practices

1. Use Test Data

const TEST_PRODUCTS = {
  simple: '/product/basic-tshirt',
  variants: '/product/multicolor-jacket',
  outOfStock: '/product/sold-out-item',
  onSale: '/product/clearance-item',
};

2. Handle Dynamic Content

async function captureWithMasking(url) {
  const screenshot = await captureScreenshot(url, {
    maskElements: [
      '.recommended-products',
      '.recently-viewed',
      '.shipping-eta',
    ],
  });
  return screenshot;
}

3. Test Critical Paths Daily

// Priority testing schedule
const DAILY_TESTS = ['cart', 'checkout', 'product-detail'];
const WEEKLY_TESTS = ['category', 'search', 'account'];

Conclusion

E-commerce screenshot testing requires:

  1. Product pages - Variants, galleries, pricing
  2. Cart - Empty, populated, quantity changes
  3. Checkout - All steps, error states, guest/logged-in
  4. Mobile - Critical flow on mobile devices
  5. Dynamic content - Mask or exclude changing elements

Automated visual testing catches layout issues before customers encounter them, protecting conversion rates and brand perception.


Ready to test your e-commerce site?

Get your free API key → - 100 free screenshots to get started.

See also:

e-commerce
testing
visual testing
automation

About the Author

Asad Ali

Asad Ali

Full-Stack Developer and Founder of ZTabs with 8+ years of experience building scalable web applications and APIs. Specializes in performance optimization, SaaS development, and modern web technologies.

Credentials: Founder & CEO at ZTabs, Full-Stack Developer, Expert in Next.js, React, Node.js, and API optimization

Ready to capture your first screenshot?

Get started with 100 free screenshots. No credit card required.

Related Articles