A concrete before-and-after for a Playwright test generation prompt, for a refund endpoint:
Unreliable generation prompt (code-only, no requirement, no scenario list):
Write Playwright API tests for the /refunds endpoint based on this handler code: [code].
Reliable generation prompt (requirement included, scenario categories named explicitly):
Acceptance criteria (from ticket REFUND-114):
- A refund can only be issued against an order in "delivered" or "partially_shipped" status.
- A refund amount cannot exceed the sum of items actually shipped.
- A refund request against an order still "in_fulfillment" must be rejected with a 409, not silently queued.
Implementation: [code]
Generate Playwright API tests for /refunds covering each of the following categories explicitly,
one test per named scenario, and reference which acceptance criteria line each test verifies:
1. Boundary: refund amount exactly equal to shipped total.
2. Invalid state: refund attempted while order is "in_fulfillment".
3. Partial shipment: refund attempted for more than the shipped subset.
4. Authorization: refund attempted by a user who does not own the order.
The second prompt produces tests that trace back to a specific acceptance-criteria line, which is a workflow benefit beyond just better coverage: it gives a reviewer (or an audit trail) a direct way to check "does a test exist for AC-2" without reading test internals line by line. That traceability discipline is the same practice the story-driven test generation described in the 5 things you must validate before trusting an AI-generated test checklist depends on, it's just applied one step earlier, at generation time instead of review time.
A minimal Playwright test generated from category 2 above:
test('rejects refund when order is still in_fulfillment [AC-3]', async ({ request }) => {
const order = await createOrder({ status: 'in_fulfillment', shippedTotal: 0 });
const response = await request.post(`/refunds`, {
data: { orderId: order.id, amount: 50 },
});
expect(response.status()).toBe(409);
const body = await response.json();
expect(body.error).toContain('order not eligible for refund');
});
Note the assertion checks the specific rejection reason, not just the status code, because a test that only checks `response.status()).toBe(409)` would still pass if the endpoint rejected the request for the wrong reason entirely, which is exactly the kind of shallow assertion this generation discipline is meant to prevent.