A Magento checkout monitor should prove that a customer can select a product, create a cart, reach checkout, enter a shipping address, and load the expected delivery and payment methods. Playwright can test the rendered storefront while also checking the GraphQL or REST requests behind it.

Adobe Commerce and Magento Open Source provide several testing tools, including a Functional Testing Framework and web API tests. A production Browser Check has a narrower goal: catch the customer-facing checkout failure that still returns a successful page response.

Key takeaways

  • Use a stable product and decide whether the monitor represents a guest or signed-in customer.
  • Split product, cart, shipping, and payment assertions into named Playwright steps.
  • Inspect GraphQL responses when a headless storefront fails without a visible server error.
  • Stop before order placement unless the store has an approved synthetic-order process.
  • Keep extensions and regional configuration in mind when selecting probes and test data.

Why does Magento checkout need a browser check?

Magento checkout combines inventory, customer state, shipping rates, taxes, coupons, and payment extensions. A monitor that only requests the checkout URL can miss failures such as:

  • Add-to-cart succeeds visually but no cart is created.
  • Shipping methods never finish loading.
  • Address validation blocks valid customers.
  • A payment extension fails to initialize.
  • Cart totals differ between the API and rendered UI.
  • A headless storefront receives GraphQL errors inside a 200 OK response.

Adobe's official GraphQL checkout tutorial describes a 10-step order flow for guest and signed-in customers. It also uses an offline payment method in the sample environment, which is a sensible model for complete automated orders.

Choose the scenario before writing selectors

Write down the exact path the monitor represents:

Decision Example
Storefront Luma theme, Hyva, or a headless React storefront
Customer Guest or dedicated test account
Product Permanent simple product with controlled stock
Region Country and postal code with predictable shipping
Payment boundary Method availability or completed offline order

Do not select the first featured item on a category page. Merchandising and stock changes will turn expected catalog updates into checkout alerts.

A Magento checkout monitor in Playwright

This example follows common Luma-style labels. Hyva and custom storefronts will need different locators.

import { test, expect } from '@playwright/test'

test('Magento guest checkout reaches payment methods', async ({ page }) => {
  test.setTimeout(110_000)

  await test.step('Open a stable product', async () => {
    await page.goto(process.env.MAGENTO_PRODUCT_URL, {
      waitUntil: 'domcontentloaded',
    })
    await expect(page.getByRole('heading', { level: 1 })).toBeVisible()
    await expect(page.locator('[data-price-type="finalPrice"]').first())
      .toBeVisible()
  })

  await test.step('Add the product to the cart', async () => {
    await page.getByRole('button', { name: /add to cart/i }).click()
    await expect(page.getByText(/added .* to your shopping cart/i))
      .toBeVisible()
  })

  await test.step('Open checkout', async () => {
    await page.getByRole('link', { name: /shopping cart/i }).click()
    await expect(page.getByRole('button', { name: /proceed to checkout/i }))
      .toBeEnabled()
    await page.getByRole('button', { name: /proceed to checkout/i }).click()
    await expect(page).toHaveURL(/\/checkout/)
  })

  await test.step('Enter shipping details', async () => {
    await page.getByLabel(/email address/i).fill(process.env.TEST_EMAIL)
    await page.getByLabel(/first name/i).fill('Checkout')
    await page.getByLabel(/last name/i).fill('Monitor')
    await page.getByLabel(/street address/i).first().fill('123 Test Street')
    await page.getByLabel(/city/i).fill('Austin')
    await page.getByLabel(/state\/province/i).selectOption({ label: 'Texas' })
    await page.getByLabel(/zip\/postal code/i).fill('78701')
    await page.getByLabel(/phone number/i).fill('5125550100')
  })

  await test.step('Verify shipping and payment', async () => {
    const shipping = page.locator('input[type="radio"][name^="ko_unique"]')
    await expect(shipping.first()).toBeVisible({ timeout: 30_000 })
    await shipping.first().check()
    await page.getByRole('button', { name: /next/i }).click()
    await expect(page.locator('.payment-method').first()).toBeVisible()
  })
})

Use Playwright Codegen to record the active storefront, then improve its selectors using the locator guide. Generated Knockout attributes and CSS classes are less stable than visible labels.

How do you wait for Magento totals and shipping rates?

Magento often recalculates totals after the address or shipping method changes. A fixed delay will be too short on a slow run and wastes time on a fast one.

Wait for a specific UI state:

await expect(page.locator('.totals.shipping .price')).not.toHaveText('-')
await expect(page.locator('.grand.totals .price')).toContainText('$')

For a headless storefront, wait for the relevant GraphQL operation and inspect its response:

const ratesResponse = page.waitForResponse(async response => {
  if (!response.url().includes('/graphql') || !response.ok()) return false

  const requestBody = response.request().postData() || ''
  return requestBody.includes('setShippingAddressesOnCart')
})

await page.getByLabel(/zip|postal code/i).fill('78701')
const response = await ratesResponse
const body = await response.json()

if (body.errors?.length) {
  throw new Error(`Magento GraphQL error: ${body.errors[0].message}`)
}

The network interception and API mocking guide explains how to inspect requests without replacing the production response.

How should configurable products work?

Select every required option before adding the product:

await page.getByLabel('Size').selectOption({ label: 'M' })
await page.getByLabel('Color').selectOption({ label: 'Black' })
await expect(page.getByRole('button', { name: /add to cart/i })).toBeEnabled()

Configurable inventory can change independently for each child SKU. A simple product is more reliable for routine monitoring. Use a configurable product only when option selection is itself a critical customer path.

Should the monitor place an order?

A standard production check should stop when payment methods load. This verifies most of the checkout pipeline without creating revenue, inventory, fulfillment, or analytics side effects.

Complete orders only when the commerce team has established:

  • A dedicated product and customer.
  • An offline or sandbox payment method.
  • Automatic cancellation and inventory restoration.
  • Exclusion from sales, tax, marketing, and fulfillment reports.
  • A spending and frequency limit if any real payment method is involved.

Keep a full order test in staging if production cannot meet those conditions.

How do you handle cookie banners and extensions?

Third-party extensions can add address modals, consent banners, chat widgets, and loading masks. Handle only overlays that are expected in the selected region:

await page.addLocatorHandler(
  page.getByRole('button', { name: /accept cookies/i }),
  async button => button.click()
)

The guide to blocking chat widgets during Playwright tests covers network-level blocking when a support widget interferes with staging tests. Do not block a production dependency that the monitor is meant to validate.

How to use Hyperping for Magento checkout monitoring

1. Prepare a checkout scenario

Choose a stable product, customer type, address, and safe stopping point. Document the expected shipping and payment methods.

2. Create the Magento Browser Check

Create a Hyperping Browser Check and paste the adapted Playwright journey into the editor.

3. Add configuration and secrets

Add product URLs, account credentials, and test address values as environment variables. Keep storefront-specific values out of the shared script.

4. Verify GraphQL and UI state

Run the check and confirm that API responses and rendered totals agree. Use named steps so the run log points to the failing checkout stage.

5. Schedule and route alerts

Choose a region and interval that match the store's traffic. Route failures to the team responsible for commerce operations and payment extensions.

Monitor one checkout path well

Magento supports many stores, currencies, customer groups, and extension combinations. A scheduled check should cover one high-value path consistently. Keep broad matrix coverage in CI and add another monitor only when a second production path has distinct operational risk.

For a simpler starting point, adapt the checkout Browser Check template and review the Playwright waits guide before adding address and rate calculations.