End-to-end tests for SolidJS.
Solid does not re-render: it mutates the exact node whose signal changed. That is why it is fast, and why a test holding a reference to that node can happily pass while the thing it is measuring never updated. Describe what should be on screen instead, in a sentence.
$ npx smolanalytics test \
--url http://localhost:3000 \
--test "adding two items to the cart shows a total of 2 in the header"Run it against dev on your own machine before you wire anything into CI. No account is needed for the first run.
how do I write end-to-end tests for a SolidJS app?
End-to-end testing a SolidJS app without writing test code: put one sentence per flow in a markdown file, or pass a single --test flag, and run npx smolanalytics test against a running URL. An agent opens a real browser and decides what to click by reading the page's accessibility tree, so it never holds a reference to a DOM node — which matters more in Solid than elsewhere, because fine-grained reactivity mutates nodes in place and a node reference in a test can therefore keep passing while the signal behind it stopped updating. It checks the value it can see on screen instead. The verdict is passed, failed, stale or errored, and those are kept strictly apart: failed means your app did not do what the test describes, stale means a recording no longer fits the page and the agent is going back to find out whether that was a rename or a removal, and errored means our runner could not run, which is our fault and never a statement about your app. On a pull request, one comment says what broke, edited in place. A passing run is recorded and replays with no model call at all. Setup is a URL and a sentence; nothing is written to your repo. 14-day trial at Pro limits, no card, then $19/month.
Fine-grained reactivity changes what a test can trust. In a framework that re-renders, a stale element reference throws and the test goes red. In Solid the node survives every update, so a test written against it keeps resolving and keeps asserting on whatever text happens to be in there — including text that never changed because the signal it depended on was read outside a tracking scope. That is the classic Solid bug: a value destructured out of props at the top of a component, frozen at its first value, rendering forever. It looks correct. It is correct once. The agent has no node reference to go stale, because it re-reads the page each time and checks the number it can see.
The other one worth a sentence is the resource: <Suspense> falls back, the fetch rejects, and the fallback stays up. A spinner that never resolves is the hardest failure to alert on and the easiest one to describe — "confirm the list of orders appears" fails on it every time.
Instrumentation is the second half and it comes free of the same walk. Solid apps tend to have very few components and a lot of signals, so the events worth having are the handful of real user actions the agent just performed. It writes and maintains those tracking calls in the SDK you already use — PostHog, Mixpanel, Amplitude, Google Analytics, Plausible or Segment — rather than asking you to adopt ours.
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 SolidJS 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.