Examples
Shop
A small app that sells credits through Stripe Checkout; danwo tests itself against it.
A small app that sells credits through Stripe Checkout; danwo tests itself against it. See it on GitHub.
What it shows
- Stripe Checkout and its webhook through the Stripe emulator, with no app code changes
- An invariant: the credits granted equal the credits Stripe was paid for
danwo matrixbreaking the purchase with a duplicated webhook- Snapshots and restores between matrix runs, so no run restarts the app
Stack
Node.jsEmulates: Stripe. Runs on: A Node web app in Chromium.
Run it
From examples/shop, after bun install at the repository's root:
bun run start # node src/server.ts
bun run test:e2e # danwo test
bun run matrix # danwo matrix tests/buy-credits.danwo.tsFault matrix explains what this example leans on.
The test
import { type StripeFixtures, test as base } from "@danwo/sdk"
import { grantedCredits, paidCredits } from "../src/ledger.ts"
const test = base.extend<StripeFixtures>()
test("buys 500 credits through Stripe Checkout", async ({ app, screen, expect }) => {
await app.open("/")
await screen.getByRole("button", { name: "Buy 500 credits" }).click()
await expect(screen.getByTestId("checkout-total")).toContainText("$5.00")
/* Paying calls Stripe; readiness waits for the call and plays the webhook it causes. */
await screen.getByTestId("checkout-pay").click()
await expect(screen.getByRole("heading", { name: "Thank you for your purchase" })).toBeVisible()
await expect(screen.getByText(/^Credits: /)).toHaveText("Credits: 500")
}).invariant(async ({ app, stripe, expect }) => {
// Whichever way the purchase went, the shop grants exactly the credits Stripe was paid for.
expect(await grantedCredits(app.baseUrl, "u1")).toBe(await paidCredits(stripe, "u1"))
})