# Example 2: Checkout Flow — E2E Code Generation

## Input

```
/mk:qa-manual tasks/plans/260315-checkout-flow.md --generate
```

Spec extract:
```
## User Flow: Checkout
1. Add item to cart from product page
2. Navigate to cart
3. Click "Checkout"
4. Fill shipping address
5. Select payment method
6. Confirm order
7. Verify: order confirmation page with order number
```

## Detection Step

```bash
$ grep -rl "data-testid" src/ --include="*.vue" --include="*.tsx" | wc -l
23
$ grep -rl "data-cy" src/ --include="*.vue" --include="*.tsx" | wc -l
0
# → data-testid detected. Using getByTestId as primary locator.
```

## Generated Output

```
tests/e2e/checkout-flow/
├── common/
│   ├── checkoutSelectors.ts
│   ├── checkoutAssertions.ts
│   └── checkoutIntercepts.ts
└── checkout-flow.spec.ts
```

### `common/checkoutSelectors.ts`

```typescript
// Generated by mk:qa-manual
// Feature: checkout

import type { Page } from '@playwright/test';

const checkoutSelectors = {
  // Product page
  addToCartButton: (page: Page) => page.getByTestId('add-to-cart'),
  cartLink: (page: Page) => page.getByTestId('cart-link'),

  // Cart page
  checkoutButton: (page: Page) => page.getByTestId('checkout-btn'),

  // Shipping form
  fullNameInput: (page: Page) => page.getByLabel('Full Name'),
  addressInput: (page: Page) => page.getByLabel('Address'),
  cityInput: (page: Page) => page.getByLabel('City'),
  zipInput: (page: Page) => page.getByLabel('ZIP Code'),

  // Payment
  creditCardRadio: (page: Page) => page.getByRole('radio', { name: 'Credit Card' }),

  // Confirmation
  placeOrderButton: (page: Page) => page.getByTestId('place-order'),
  confirmationMessage: (page: Page) => page.getByText('Order Confirmed'),
  orderNumber: (page: Page) => page.getByText(/Order #\d+/),
};

export default checkoutSelectors;
```

### `common/checkoutAssertions.ts`

```typescript
// Generated by mk:qa-manual
// Feature: checkout

import { expect, type Page } from '@playwright/test';
import checkoutSelectors from './checkoutSelectors';

export const checkoutAssertions = {
  shouldBeOnCart: async (page: Page) => {
    await expect(page).toHaveURL(/.*\/cart/);
  },

  shouldBeOnCheckout: async (page: Page) => {
    await expect(page).toHaveURL(/.*\/checkout/);
  },

  shouldShowConfirmation: async (page: Page) => {
    await expect(page).toHaveURL(/.*\/order-confirmation/);
    await expect(checkoutSelectors.confirmationMessage(page)).toBeVisible();
    await expect(checkoutSelectors.orderNumber(page)).toBeVisible();
  },
};
```

### `common/checkoutIntercepts.ts`

```typescript
// Generated by mk:qa-manual
// Feature: checkout

import type { Page } from '@playwright/test';

const checkoutIntercepts = {
  mockPlaceOrder: async (page: Page) => {
    await page.route('**/api/orders', (route) =>
      route.fulfill({
        status: 201,
        contentType: 'application/json',
        body: JSON.stringify({ orderId: '12345', status: 'confirmed' }),
      }),
    );
  },
};

export default checkoutIntercepts;
```

### `checkout-flow.spec.ts`

```typescript
// Generated by mk:qa-manual
// Source spec: tasks/plans/260315-checkout-flow.md
// Generated at: 2026-03-27 14:45 UTC
// Feature: checkout

import { test } from '@playwright/test';
import checkoutSelectors from './common/checkoutSelectors';
import { checkoutAssertions } from './common/checkoutAssertions';
import checkoutIntercepts from './common/checkoutIntercepts';

test.describe('Checkout Flow', () => {
  test('complete checkout from product to confirmation', async ({ page }) => {
    // Step 1: Navigate to product page and add item to cart
    await page.goto('https://app.example.com/products/widget-pro');
    await checkoutSelectors.addToCartButton(page).click();

    // Step 2: Navigate to cart
    await checkoutSelectors.cartLink(page).click();
    await checkoutAssertions.shouldBeOnCart(page);

    // Step 3: Begin checkout
    await checkoutSelectors.checkoutButton(page).click();
    await checkoutAssertions.shouldBeOnCheckout(page);

    // Step 4: Fill shipping address
    await checkoutSelectors.fullNameInput(page).fill('Jane Doe');
    await checkoutSelectors.addressInput(page).fill('123 Main St');
    await checkoutSelectors.cityInput(page).fill('San Francisco');
    await checkoutSelectors.zipInput(page).fill('94102');

    // Step 5: Select payment method
    await checkoutSelectors.creditCardRadio(page).check();

    // Step 6: Confirm order
    await checkoutIntercepts.mockPlaceOrder(page);
    await checkoutSelectors.placeOrderButton(page).click();

    // Step 7: Verify order confirmation
    await checkoutAssertions.shouldShowConfirmation(page);
  });
});
```

## Selector Verification

```bash
$ grep -rn 'data-testid="add-to-cart"' src/ --include="*.vue" --include="*.tsx"
src/components/ProductCard.vue:12:    <button data-testid="add-to-cart">Add to Cart</button>
$ grep -rn 'data-testid="cart-link"' src/ --include="*.vue" --include="*.tsx"
src/components/Header.vue:8:    <a data-testid="cart-link" href="/cart">Cart</a>
$ grep -rn 'data-testid="checkout-btn"' src/ --include="*.vue" --include="*.tsx"
src/pages/Cart.vue:25:    <button data-testid="checkout-btn">Checkout</button>
$ grep -rn 'data-testid="place-order"' src/ --include="*.vue" --include="*.tsx"
src/pages/Checkout.vue:48:    <button data-testid="place-order">Place Order</button>
# All selectors verified ✓
```

## Validation

```bash
$ sh .claude/skills/qa-manual/scripts/run-playwright.sh tests/e2e/checkout-flow/checkout-flow.spec.ts
Running: tests/e2e/checkout-flow/checkout-flow.spec.ts
  ✓ Checkout Flow > complete checkout from product to confirmation (3.2s)
PASS — all tests in tests/e2e/checkout-flow/checkout-flow.spec.ts passed
```
