the whole setup · one sentence per flow · no test code

End-to-end tests for Angular.

Protractor was deprecated and everybody was told to pick a replacement themselves. Most teams picked one, wrote a dozen specs, and stopped. Write a sentence per flow instead, and let an agent work out the selectors it would have had to maintain.

the whole setup
$ npx smolanalytics test \
    --url https://staging.yourapp.com \
    --test "an admin can invite a teammate and see them listed as pending"

No ChromeDriver to pin, no webdriver-manager, no config file. The URL is the setup.

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

Since Protractor was deprecated, end-to-end testing an Angular app means picking a runner and then maintaining the selectors it needs, which is the part that quietly stops happening. The alternative here is that there is no test code: you write one sentence per flow, run npx smolanalytics test --suite tests/ --url against a running URL, and an agent drives a real browser, decides what to click by reading the accessibility tree, and returns a verdict. Nothing refers to Angular's generated markup, so an _ngcontent attribute changing or a Material version bump cannot turn the suite red. On a pull request it leaves one comment saying what broke, edited in place, running on your own CI runner and commenting with the GITHUB_TOKEN GitHub Actions provides free. A run that passes is recorded and replays after that with no model call at all, so the agent is only paid for when something actually changed; a recording that no longer fits is reported as stale rather than as a failure, because a rename and a removal look identical to a replay. Setup is a URL you already have and nothing is written to your repo. 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.

Angular markup is generated, and that is what made the old suites so expensive to keep. Component styles get _ngcontent attributes, Material renders a control as a stack of divs with generated ids, and a selector written against any of it survives exactly until someone upgrades a package. The specs then go red for reasons that have nothing to do with the product, somebody adds a retry, and within a month the pipeline stage is allowed to fail. Nothing in these tests refers to markup at all: the agent reads the accessibility tree, which is the layer Material is careful to get right, and finds the control by its role and its name.

The Angular-specific failure worth a sentence is the guard: a route guard that resolves differently for a role, or a resolver that rejects and leaves the router mid-navigation with the previous view still on screen. The URL changed, the view did not, no error was thrown. A test that says "an admin can invite a teammate and see them listed as pending" fails on that, because the agent is looking for the teammate rather than for a route change.

The second half is instrumentation. Angular apps put the moment worth measuring in a service, not a template, which is where a hand-written analytics call most often goes missing when the service is refactored. The same agent that just performed the action knows the action exists, so it writes and maintains those 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 Angular 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 migrated our Protractor specs to another runner. Should we throw them away?
No. Keep them, especially the ones that are still green and still meaningful. The question is not whether Angular can be end-to-end tested — it obviously can — it is whether anybody will still be maintaining those selectors in six months. This is for the flows nobody got round to covering, and for the specs that go red every time a component library is upgraded. When the UI changes here there is no selector to update, because there was never a selector.
Does it handle Angular Material dialogs, overlays and the CDK?
Yes, and better than a selector would, because the CDK is deliberate about roles and aria labels: a dialog is announced as a dialog, a menu as a menu, and the agent reads exactly that. Overlays that render at the end of the body rather than inside the component are a classic source of selector pain and are simply not a special case here. What it cannot do is see something the accessibility tree does not expose, which is worth knowing as a general rule: if a screen reader cannot find a control, neither can this.
What do I actually get back after a run on Angular?
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