End-to-end tests for Qwik.
Qwik skips hydration by fetching the handler for a control the moment you touch it. That is the whole trick, and it means the first click on any control is a network request that can fail. Describe the flow in a sentence and an agent performs the real click.
--- title: "The pricing toggle switches to annual" --- Open /pricing, click the annual toggle, and confirm the headline price changes and the yearly saving is shown.
One sentence, and the criticality if you want it. There is no page object, no fixture and no selector anywhere in the suite.
how do I write end-to-end tests for a Qwik app?
To test a Qwik app end to end without writing test code, describe each flow in one sentence and run npx smolanalytics test --url against a running URL — a deploy preview, staging, or localhost through a tunnel. An agent drives a real browser and works out what to click by reading the accessibility tree. On Qwik that real click matters more than usual: resumability fetches a control's handler at the moment of interaction, so a broken chunk path gives you a page that renders perfectly and a button that does nothing the first time it is pressed. Nothing that inspects HTML catches that. The verdict comes back as passed, failed, stale or errored, and on a pull request one comment says what broke, edited in place rather than added to. It runs on your own CI runner and comments with the GITHUB_TOKEN GitHub Actions provides, so there is no GitHub App required and nothing is written to your repo. A run that passes is recorded and replays afterwards with no model call at all; the agent comes back only when the recording stops fitting the app, which is reported as stale rather than as a failure. 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.
Resumability moves work out of page load and into the first interaction, which is a genuinely better trade and a new place for things to go wrong. The handler for a button lives in a separate chunk that is fetched when the button is touched, so a misconfigured base URL, a CDN path that is right in production and wrong on a preview, or a chunk that failed to upload gives you a page that renders perfectly and a button that does nothing on the first press. Everything that reads HTML says the page is fine. Only something that actually clicks finds out.
The second Qwik-specific case is state that was serialised into the HTML and cannot be resumed — a closure capturing something unserialisable, which throws at click time rather than at build time. Again the page is fine until someone uses it. A sentence like "click the annual toggle and confirm the headline price changes" is a check on exactly that, and it does not care how the chunk was named.
The instrumentation half uses the same walk through the app. Because the agent has just performed the interactions, it knows which ones exist, so it writes and maintains your tracking calls inside the SDK you already run — PostHog, Mixpanel, Amplitude, Google Analytics, Plausible or Segment — in the $ handler where the action happens rather than in a page-level effect that fires whether or not anyone did anything.
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 Qwik 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.