tests/login.md · one sentence per flow · no test code

End-to-end tests for Express.

Supertest tells you the route returns the right body. It does not tell you the session cookie is dropped behind a proxy in production, which is the Express bug that always ships. The agent drives a real browser, where cookies are real.

tests/login.md
---
title: "A user stays signed in across a page load"
---

Sign in with the test account, reload the page, and confirm
the account menu still shows the signed-in name.

One reload is the whole test, and it is the one supertest structurally cannot do: a real browser, real cookie jar, two requests.

how do I write end-to-end tests for a Express app?

Supertest covers an Express route's request and response inside the process. What it cannot cover is the state a browser carries between requests, and that is where the Express bugs that reach production live: a session cookie without Secure or SameSite that works on localhost and is dropped behind TLS, trust proxy left unset so every user shares the load balancer's address, a redirect chain that only loops once a real cookie jar is involved. To test those, write one sentence per flow and run npx smolanalytics test --suite tests/ --url against a running URL. An agent drives a real browser, reads the page through its accessibility tree, and returns passed, failed, stale or errored, with one comment per pull request saying what broke, edited in place, posted from your own CI runner with the GITHUB_TOKEN GitHub Actions provides. A passing run is recorded and replays afterwards with no model call at all. If your Express service is a pure JSON API with no user interface, this is the wrong tool and supertest is the right one — the agent drives browsers only. The same walk also writes and maintains your tracking calls in the analytics you already use. 14-day trial at Pro limits, no card, then $19/month.

The Express failures that reach production are almost all about state between requests, which is the one thing an in-process request assertion cannot model. A session cookie missing Secure or SameSite behaves perfectly on localhost and is dropped by the browser once there is a proxy and TLS in front of it. trust proxy left unset gives every user the load balancer's address, so a rate limiter locks everybody out at once. A redirect chain that works when you follow it manually and loops when the browser carries a cookie you did not. Every one of those is green under supertest, because supertest is not a browser and does not keep a cookie jar across a redirect the way one does.

The second category is middleware order, which is invisible until it is catastrophic: an error handler registered before a route, a body parser after it, a CORS layer that answers the preflight and not the request. The route's own test still passes.

There is a boundary worth stating. If your Express service is a pure JSON API with no UI anywhere, a browser is the wrong instrument and supertest is the right one. This is for the app in front of it, and for the session and redirect behaviour that only exists in a real browser.

The instrumentation half is the same walk. Server-side events are the ones most often missing, because nobody wires analytics into a route handler, and the agent has just exercised those handlers through the UI. It writes and maintains the tracking calls in the SDK you already run: PostHog, Mixpanel, Amplitude, Google Analytics, Plausible or Segment.

How it works walks the whole loop from the sentence to the comment on the pull request, instrumentation covers the second half — the tracking calls the same walk writes and maintains — and the free tools run without an account. The docs have the flags, the suite format and the CI step.

Pro $19/mo, 100 tested pull requests included, unlimited projects, after a 14-day trial at Pro limits with no card. full pricing, including overage →

One sentence, on your Express app, tonight.

Point it at a URL that is already running and describe what should work. The first run uses the agent; once it passes it is recorded, so every run after that replays with no model at all — measured on our own site, 8.0s the first time and 1.4s the second.

questions

We have full supertest coverage. What is left?
Everything that needs two requests and a browser in between. Sessions, cookie attributes, redirect chains, CSRF tokens that must round-trip, and the middleware ordering bugs that leave a route's own test green. Those are not gaps in your discipline; they are outside what an in-process assertion can express. Keep supertest for the routes and put a handful of sentences on the flows a customer walks.
Does it need my server to run in a special mode?
No. It needs a URL that answers, which can be staging, a review app, or your local server through a tunnel. Nothing is installed into your project and nothing is written to your repository. It also does not create data, so use an account that already exists on that environment and write the sentence around it.
What do I actually get back after a run on Express?
One of four words, and the difference between them is the product. Passed. Failed, which means your app did not do what the test describes, so it is a bug report. Stale, which means a recording no longer fits the page — a rename and a removal look identical to a replay, so this is never worded or coloured as a failure and the agent goes and works out which it was. Errored, which means our runner could not run at all: no browser, no network, no key. That one is our fault and it says so, because telling you your checkout is broken when our own runner fell over is the fastest way to lose you.

keep reading