Day 12 of 20

The cart suite, and the bug your machine catches

Four tests. Three greens. One red that is telling the truth.

Lesson 13 of 210 complete

Everything so far protected search and sign-in; today you build the suite for the part that touches money, and it is going to catch something real. First, teach the page object the cart. Add these locators to the constructor:

this.cartCount = page.getByTestId('cart-count');
this.cartSubtotal = page.getByTestId('cart-subtotal');
this.cartTotal = page.getByTestId('cart-total');

And these actions below it. If you built addToOrder in the Day 7 exercise, compare mine with yours:

cardNamed(name) {
  return this.productCard.filter({ hasText: name });
}

async addToOrder(name) {
  await this.cardNamed(name).getByTestId('add-to-order').click();
}

async removeFromBox(name) {
  await this.page.getByRole('button', { name: 'Remove ' + name }).click();
}

Read the remove action: the store labels each remove button for screen readers as Remove plus the dish name, so the locator speaks the user’s language and Day 1’s ranking pays off again.

Four tests on the money path

In a new file, tests/cart.spec.js, with the same beforeEach world-building as Day 10:

test('verify that adding a dish updates the count', async () => {
  await store.addToOrder('Deluxe Plantain Plate');
  await expect(store.cartCount).toHaveText('1');
});

test('verify that the subtotal adds every dish in the cart', async () => {
  await store.addToOrder('Full Jerk Combo');
  await store.addToOrder('Baked Cheese Patty');
  await expect(store.cartSubtotal).toHaveText('10,000 JMD');
});

test('verify that removing a dish updates the subtotal', async () => {
  await store.addToOrder('Full Jerk Combo');
  await store.addToOrder('Baked Cheese Patty');
  await store.removeFromBox('Baked Cheese Patty');
  await expect(store.cartSubtotal).toHaveText('8,200 JMD');
});

test('verify that removing a dish updates the total', async () => {
  await store.addToOrder('Full Jerk Combo');
  await store.addToOrder('Baked Cheese Patty');
  await store.removeFromBox('Baked Cheese Patty');
  await expect(store.cartTotal).toHaveText('8,200 JMD');
});

Run the file. Three greens and one red, and the red reads: expected “8,200 JMD”, received “10,000 JMD”. Walk to the store and do it by hand: add both dishes, remove the patty, and watch. The item vanishes, the subtotal corrects itself to 8,200, and the total sits there still saying 10,000. The store recalculates its total on add and on discount, and never on remove. A customer who trims their order is looking at the wrong price.

Your locators are fine, the steps executed, the assertion is on the promise a customer depends on, and the product broke it. A machine you built caught that, on a path where the mistake costs money. If you took QA Fundamentals, you hunted this same bug by hand there; this time nobody had to remember to look.

What an honest suite does with a known red

File the bug first; the failure output is most of the report. Then decide what the suite shows while the fix is pending. Leaving the red in every run trains the team to skim past red, and skimmed reds are how real regressions slip through. Deleting the test throws away the guard. The honest middle is quarantine with a name on it:

test.fixme('verify that removing a dish updates the total', async () => {
  // TK-12: cart total goes stale after a remove. Red until the fix ships.
  await store.addToOrder('Full Jerk Combo');
  await store.addToOrder('Baked Cheese Patty');
  await store.removeFromBox('Baked Cheese Patty');
  await expect(store.cartTotal).toHaveText('8,200 JMD');
});

test.fixme skips the test and marks it as needing a fix, visibly, in every report. The ticket number rides in the comment, so nobody has to archaeology their way to why. The day the fix ships, delete one word and the test guards that regression forever.

A machine you built just caught a real bug. That is the entire promise of automation, kept.

Do this today

Build the cart suite, watch the red, confirm it by hand, then write the bug report: steps, expected, actual, with the failure output pasted in. Quarantine with the ticket note. Tomorrow, the question that decides what else deserves a seat in this suite.

Before you move on

Do the practice, then mark it complete

Completion is for you. It means you produced the evidence the lesson asked for, not only that you reached the bottom of the page.