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 OKresponse.
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.
FAQ
Can Playwright test Magento checkout? ▼
Yes. Playwright can cover the storefront, cart, shipping address, payment options, and order confirmation in Magento Open Source or Adobe Commerce. The selectors need to match the installed theme or headless storefront.
Should a Magento production monitor place an order? ▼
Stop before placing the order unless the commerce team has approved an offline payment method, test SKU, and automated cleanup process. Full payment and order assertions usually belong in staging.
How do I monitor a headless Magento storefront? ▼
Drive the customer UI with Playwright and inspect the GraphQL operations that create the cart, set addresses, and load payment methods. Assert both the rendered state and critical API responses.
Why is Magento checkout flaky in Playwright? ▼
Checkout extensions, asynchronous totals, address validation, inventory changes, and overlays can alter the page after an action. Use web-first assertions and wait for a meaningful response or visible state instead of fixed delays.



