# Check out a cart

> Test a checkout from the cart to the order confirmation.

Source: https://rehearsal.dev/docs/examples/check-out-a-cart

This example uses Parcel, a demo store at `parcel.example.com`. Parcel is a demo project, not a customer.

One person signs in, puts two items in the cart and places the order. The test checks the order total.

## Before you start

Add a [test account](https://rehearsal.dev/docs/reagent/test-accounts.md) that signs in with a password. Name it `owner`, and give it `owner@parcel.example.com` and its password.

## Ask Re:agent

Open **Re:agent** and type: "Sign in as the owner and buy two small boxes and one roll of packing tape. A box costs $6.00, tape costs $3.50 and shipping is $3.00. Check the order total."

Say what the total should be. Re:agent takes the rules of your business from you, not from what the page happens to show.

## What Re:agent does

Each line below is a row in the chat, in the app's own words. What follows a dot is the detail the chat shows beside the row.

- Checked your projects
- Opened a browser on **parcel.example.com** as owner
- Opened **parcel.example.com/sign-in**
- Filled **Email** · `owner@parcel.example.com`
- Filled **Password**
- Clicked **Sign in**
- Clicked **Store**
- Clicked **Small box**
- Chose an option in **Quantity** · 2
- Clicked **Add to cart**
- Clicked **Packing tape**
- Clicked **Add to cart**
- Clicked **Cart**
- Read the page · $15.50
- Clicked **Check out**
- Clicked **Place order**
- Read the page · $18.50
- Saved the flow

The cart shows $15.50 before shipping. The order confirmation shows $18.50 with shipping, as you said it should.

## The test

Rehearsal writes a Playwright test from the saved flow. It looks like this.

```ts
import { expect, test } from '@playwright/test';
import { participant } from '@rehearsal/codegen/runtime';

test('Checkout shows the right total', async ({ browser }) => {
  const owner = await participant(browser, 'owner');
  try {
    await test.step('Sign in', async () => {
      await owner.page.goto('/sign-in');
      await owner.page.getByLabel('Email').fill('owner@parcel.example.com');
      await owner.page.getByLabel('Password').fill(owner.password());
      await owner.page.getByRole('button', { name: 'Sign in' }).click();
      await owner.page.waitForURL('**/projects');
    });
    await test.step('Add two small boxes to the cart', async () => {
      await owner.page.getByRole('link', { name: 'Store' }).click();
      await owner.page.getByRole('link', { name: 'Small box' }).click();
      await owner.page.getByLabel('Quantity').selectOption('2');
      await owner.page.getByRole('button', { name: 'Add to cart' }).click();
    });
    await test.step('Add packing tape to the cart', async () => {
      await owner.page.getByRole('link', { name: 'Packing tape' }).click();
      await owner.page.getByRole('button', { name: 'Add to cart' }).click();
    });
    await test.step('Open the cart', async () => {
      await owner.page.getByRole('link', { name: 'Cart' }).click();
      await owner.page.waitForURL('**/cart');
    });
    await test.step('Check the cart subtotal', async () => {
      await expect(owner.page.getByTestId('cart-subtotal')).toHaveText('$15.50');
    });
    await test.step('Place the order', async () => {
      await owner.page.getByRole('button', { name: 'Check out' }).click();
      await owner.page.getByRole('button', { name: 'Place order' }).click();
      await owner.page.waitForURL('**/orders/**');
    });
    await test.step('Check the order total', async () => {
      await expect(owner.page.getByTestId('order-total')).toHaveText('$18.50');
    });
  }
  finally {
    await owner.close();
  }
});
```

Each check is a step of its own. When one fails, the run names that step and shows what the page said instead.

## Run it

Press **Run now** on the card in the chat, or **Run** on the test's row in **Tests**. From the terminal:

```sh
rehearsal runs start --test <test-id>
rehearsal runs wait <run-id>
```

A wrong total fails the test at **Check the order total**. That failure [counts as a test run](https://rehearsal.dev/docs/billing/plans-and-runs.md), because the check ran and found a different total.

## Next steps

- Let your coding agent [fix a failure](https://rehearsal.dev/docs/examples/fix-a-failure.md) in this test.
- Learn to [read a run](https://rehearsal.dev/docs/tests/read-a-run.md) and watch its recording.
