Files
claude-skills-reference/engineering-team/playwright-pro/templates/checkout/add-to-cart.md
Alireza Rezvani d33d03da50 feat: add playwright-pro plugin — production-grade Playwright testing toolkit (#254)
Complete Claude Code plugin with:
- 9 skills (/pw:init, generate, review, fix, migrate, coverage, testrail, browserstack, report)
- 3 specialized agents (test-architect, test-debugger, migration-planner)
- 55 test case templates across 11 categories (auth, CRUD, checkout, search, forms, dashboard, settings, onboarding, notifications, API, accessibility)
- TestRail MCP server (TypeScript) — 8 tools for bidirectional sync
- BrowserStack MCP server (TypeScript) — 7 tools for cross-browser testing
- Smart hooks (auto-validate tests, auto-detect Playwright projects)
- 6 curated reference docs (golden rules, locators, assertions, fixtures, pitfalls, flaky tests)
- Leverages Claude Code built-ins (/batch, /debug, Explore subagent)
- Zero-config for core features; TestRail/BrowserStack via env vars
- Both TypeScript and JavaScript support throughout

Co-authored-by: Leo <leo@openclaw.ai>
2026-03-05 13:50:05 +01:00

4.1 KiB

Add to Cart Template

Tests adding items to cart and quantity updates.

Prerequisites

  • Authenticated (or guest) session
  • Product: ID {{productId}}, name {{productName}}, price {{productPrice}}
  • App running at {{baseUrl}}

TypeScript

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

test.describe('Add to Cart', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('{{baseUrl}}/products/{{productId}}');
  });

  // Happy path: add single item
  test('adds product to cart', async ({ page }) => {
    await page.getByRole('button', { name: /add to cart/i }).click();
    await expect(page.getByRole('status', { name: /cart/i })).toContainText('1');
    await expect(page.getByRole('alert')).toContainText(/added to cart/i);
  });

  // Happy path: add multiple items increments count
  test('increments cart count on repeated add', async ({ page }) => {
    await page.getByRole('button', { name: /add to cart/i }).click();
    await page.getByRole('button', { name: /add to cart/i }).click();
    await expect(page.getByRole('status', { name: /cart/i })).toContainText('2');
  });

  // Happy path: add with quantity selector
  test('adds specified quantity to cart', async ({ page }) => {
    await page.getByRole('spinbutton', { name: /quantity/i }).fill('3');
    await page.getByRole('button', { name: /add to cart/i }).click();
    await expect(page.getByRole('status', { name: /cart/i })).toContainText('3');
  });

  // Happy path: cart persists on navigation
  test('cart persists after navigating away', async ({ page }) => {
    await page.getByRole('button', { name: /add to cart/i }).click();
    await page.goto('{{baseUrl}}/products');
    await expect(page.getByRole('status', { name: /cart/i })).toContainText('1');
  });

  // Error case: out of stock product cannot be added
  test('add to cart button disabled for out-of-stock product', async ({ page }) => {
    await page.goto('{{baseUrl}}/products/{{outOfStockProductId}}');
    await expect(page.getByRole('button', { name: /add to cart/i })).toBeDisabled();
    await expect(page.getByText(/out of stock/i)).toBeVisible();
  });

  // Error case: quantity exceeds stock
  test('shows error when quantity exceeds available stock', async ({ page }) => {
    await page.getByRole('spinbutton', { name: /quantity/i }).fill('{{overStockQuantity}}');
    await page.getByRole('button', { name: /add to cart/i }).click();
    await expect(page.getByRole('alert')).toContainText(/only.*available|exceeds.*stock/i);
  });

  // Edge case: cart opens after add
  test('cart drawer opens after adding item', async ({ page }) => {
    await page.getByRole('button', { name: /add to cart/i }).click();
    await expect(page.getByRole('dialog', { name: /cart/i })).toBeVisible();
    await expect(page.getByRole('dialog').getByText('{{productName}}')).toBeVisible();
  });
});

JavaScript

const { test, expect } = require('@playwright/test');

test.describe('Add to Cart', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('{{baseUrl}}/products/{{productId}}');
  });

  test('adds product to cart', async ({ page }) => {
    await page.getByRole('button', { name: /add to cart/i }).click();
    await expect(page.getByRole('status', { name: /cart/i })).toContainText('1');
  });

  test('add to cart disabled for out-of-stock', async ({ page }) => {
    await page.goto('{{baseUrl}}/products/{{outOfStockProductId}}');
    await expect(page.getByRole('button', { name: /add to cart/i })).toBeDisabled();
  });

  test('cart persists after navigation', async ({ page }) => {
    await page.getByRole('button', { name: /add to cart/i }).click();
    await page.goto('{{baseUrl}}/products');
    await expect(page.getByRole('status', { name: /cart/i })).toContainText('1');
  });
});

Variants

Variant Description
Single add Product added, cart count = 1
Repeated add Cart count increments
Quantity selector Specified quantity added
Persist on nav Cart count survives page change
Out of stock Button disabled, label shown
Quantity exceeds stock Error alert
Cart drawer Slide-in cart opens showing added item