agentleFS
CaduS0uzaCaduS0uza/qa-supreme/skills/autonomous-exploration/SKILL.md

autonomous-exploration

Skill1 starsChanged 2 months agoMITView on GitHub

Drive the qa-supreme runner to click every reachable control of a web app, follow every link and tab, count each click on screen, and report dead buttons, broken states and click errors. Use when asked to "test the whole app", "click everything", "find dead buttons", "map the UI", or when there is no test suite at all and coverage must start somewhere.

  • Installs packages

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 3 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every control gets one verdict, decided from what the click actually caused:

    line 68
  2. Distinctive:

    Before listing controls, the runner puts the page into the state a user would actually find: the consent banner is dismissed (recorded, …

    line 86
  3. Distinctive:

    Use a seeded, disposable account.

    line 129
  4. Very specific:

    Add data-qa-skip to any element the crawler must never touch.

    line 131

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Autonomous Exploration

The fastest way to learn what an app actually does is to click all of it. This skill drives the bundled runner (runner/), which performs a breadth-first exploration of every reachable UI state and produces an evidence report.

Run it

cd runner && npm install                 # first time only
node bin/qa-supreme.mjs here                              # detects the project, starts it, tests it, stops it
node bin/qa-supreme.mjs run --url https://app.example.com # full pipeline against a running app
node bin/qa-supreme.mjs watch --url http://localhost:3000 # real window, slowed down, video recorded

here reads the project in the current directory — Next, Vite, CRA, Nuxt, Astro, Remix, Angular, Django, Rails, Laravel, or a plain static folder — starts it on its own port, waits for it to answer, runs the pipeline and shuts it down. That is what makes this usable on any project without configuring anything first.

The on-screen HUD counts every click as it happens, flashes the element being hit, and shows queue depth and error count — so a human watching, a screenshot, or a recorded video all carry the same proof.

Apps behind a login (most of them)

An unauthenticated run against a protected app explores the login page and reports an empty product. The runner names that instead of pretending: smoke fails with authentication — target is behind a login, and the run stops there rather than producing noise.

# log in once, keep the session
node bin/qa-supreme.mjs login --url https://app.example.com --login-url https://app.example.com/login \
  --user qa@example.com --pass "$QA_PASSWORD"

# every later run reuses it
node bin/qa-supreme.mjs run --url https://app.example.com --storage .qa-supreme/auth.json

The login form is found automatically (username/email + password + submit). When the markup defeats the heuristics, name the fields: --user-selector, --pass-selector, --submit-selector, --success-selector. Success is judged by the login form being gone, not by a URL change — SPAs authenticate without navigating.

While a session is active the crawler also refuses to click anything that ends it (log out, sign out), on top of the destructive-action guard. One stray click on "Sign out" would turn every remaining state into the login page.

What it produces

SignalMeaningWhat you do with it
clicks performedinteractions actually executedthe coverage number nobody else reports
states discovereddistinct UI states reachedcompare against the sitemap — gaps are unreachable UI
transitions mappedcontrol → destination edgesthe app's real navigation graph
button verdictsevery control judged, not just countedthe list of what is broken and what is dead
click errorscontrol refused a click in 4soverlay traps, disabled-but-visible, z-index bugs
guarded skipsdestructive and session-ending controls not clickedverify the guard list matches your app
clicks that needed a retrycontrol was transiently covereda rising number means overlay/timing problems

The button report

Every control gets one verdict, decided from what the click actually caused:

VerdictWhat happenedWhat it means
worksnavigation, new tab, reload, or a visible changefine
network onlynothing visible, but a request went outprobably fine — confirm the effect is real
deadno visible change, no request, no errornobody wired this control
suspecta console error or a failed requestwired, but something under it is failing
brokenan uncaught exception or a 5xxa defect, with the exception as evidence
unclickablerefused a click twice from a clean statean overlay traps it, or it is disabled but looks enabled

Effects are attributed to a control only when it owns them: errors thrown while a new page loads belong to that page, not to the link that led there. Blaming the link is exactly the false positive this repository exists to hunt, so navigations are judged by what they reached, not by what the destination logged.

What it can see (and what it still cannot)

Before listing controls, the runner puts the page into the state a user would actually find: the consent banner is dismissed (recorded, never counted as a test click), the page is scrolled to the bottom so lazy and virtualised content exists, it waits for the page to stop changing, and hover menus are opened. Then it discovers through the places a naive crawler stops:

ObstacleHow it is handled
Consent / cookie walldismissed first, so it cannot swallow every click
Content below the fold, infinite scroll, IntersectionObserverscrolled through in steps, and controls found this way are marked as needing that scroll to be reachable again
Shadow DOM (web components, design systems)open shadow roots are walked; the selector pierces them
Same-origin iframesframes are discovered and clicked through a frame locator
Hash routing (#/reports)the hash is part of the address and of the state, so three routes are three screens
Hover-only menustriggers are hovered before discovery; their items carry that requirement
A control covered by an overlayreported as unclickable, naming what sits on top of it
Something still loadingit waits for the page to settle, then sweeps again — controls that appear late are clicked too

Still out of reach, and honest about it: canvas and WebGL surfaces with no DOM behind them, drag-and-drop, cross-origin iframes, native OS dialogs, and anything gated behind a captcha.

Reading only one part of the app

node bin/qa-supreme.mjs crawl --url http://localhost:3000 --only "#settings-panel"

--only <css> limits discovery to one region — a tab panel, a drawer, the screen you just built. Everything else on the page is ignored, so the report is about your change and nothing else. Frames are skipped while a scope is set, because a scope belongs to the host document.

Triaging dead buttons

A dead verdict is not automatically a bug — it may be a no-change tab, an already-active state, or a control whose effect is server-side only. For each one, answer: what should a user expect to happen? If the answer is "something", you found a defect before any user did. Record the confirmed ones as bugs, and add the rest to denySelectors so the next run stays signal.

Safety

By default the crawler refuses to click anything whose label matches a destructive verb (delete, pay, logout, publish, transfer...). That guard is the difference between exploration and an incident.

  • Point it at local, preview, or staging environments. Not production.
  • Use a seeded, disposable account. Never a real customer's.
  • --full-send removes the guard. Only ever on a throwaway environment you can rebuild.
  • Add data-qa-skip to any element the crawler must never touch.

Turning exploration into a suite

Exploration is reconnaissance, not regression protection. Feed what it found back into real tests: the discovered journeys become e2e-authoring specs, the dead buttons become bug reports through bug-repro, and the state graph becomes the input to risk-map.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.