agentleFS
MKS-01MKS-01/appscreenmap/.claude/skills/add-exporter/SKILL.md

add-exporter

Skill2 starsChanged 19 days agoMITView on GitHub

Add or improve an AppScreenMap exporter that turns a crawl into tests for an E2E tool (Maestro, Appium, Espresso/UI Automator, Playwright-style page objects, Detox, XCUITest, or a user's own template) — and build the pluggable exporter interface itself. Use when asked to support another test tool, make export plug-and-play, add `--format`, or fix a generated test that doesn't run.

  • Installs packages

The file

We split this skill into the rules it gives an agent

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

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    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:

    Do this before adding a second tool, and move Maestro behind it without changing its output (the existing export tests must still pass …

    line 20
  2. Distinctive:

    Read the tool's docs for its selector and wait model: Don't generate from memory.

    line 38
  3. Very specific:

    Use reach_path (steps from launch) and each screen's autofill (type values before the tap that needs them).

    line 43
  4. Distinctive:

    Start from a clean launch (force-stop, then launch), because that is what the path means.

    line 46
  5. Distinctive:

    Declare capabilities: If the tool can't express a step (long-press, back, a gesture), the exporter skips that screen and reports it, with …

    line 47
  6. Distinctive:

    If the tool ships a parser or linter, run generated output through it in a test (skipped when not installed).

    line 60

≈ “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

Exporters for E2E tools

Goal: users pick the test tool they already use. The crawl (map.json) stays tool-neutral; an exporter only translates it. Read .claude/skills/extend-crawler/SKILL.md for the general checklist, and docs/MAP_SCHEMA.md for the data.

Current state (verify before relying on it)

Export is one hard-coded function: export.maestro_flow(data, screen) plus mermaid(data), both called from export.export_run(). There is no exporter interface, registry or --format flag yet. Check packages/exporters/ and apps/engine/src/appscreenmap/engine/cli/verify.py (cmd_export) first; if that changed, follow the code, not this paragraph.

Step 0: build the interface (once, then reuse it)

Do this before adding a second tool, and move Maestro behind it without changing its output (the existing export tests must still pass byte-for-byte).

  1. Interface: an Exporter with name, capabilities, and export(data: dict, screen: dict) -> dict[str, str] (relative path → file text). It receives plain map.json dicts, never live objects.
  2. Registry: built-ins registered by name, plus third-party plugins through the appscreenmap.exporters entry-point group (so pip install appscreenmap-<tool> adds a format).
  3. CLI: appscreenmap export <run> --format maestro,appium-python (default: maestro, so nothing breaks) and a crawl-time default in config. Keep logic in the module; the CLI (apps/engine/src/appscreenmap/engine/cli/) only parses and prints.
  4. Neutral steps: --format json writes the resolved path per screen (launch → steps → assertion) so any tool in any language can generate its own tests. Treat this shape as public API: additive changes only.
  5. Templates: --template file renders the neutral steps through a user-supplied template, for people who only want different syntax.
  6. Docs: README (formats, how to write a plugin), docs/MAP_SCHEMA.md (the neutral step format), docs/PLAN.md (§8 roadmap row).

Adding one exporter

  1. Read the tool's docs for its selector and wait model. Don't generate from memory; wrong syntax is the most common failure, and nothing in the unit tests will catch it unless you test against the tool's own grammar.
  2. Map the neutral step to the tool's commands:
    • Selector preference: resource-id → text / content-desc → point. Say in a comment when you fell back to a point (coordinates are brittle, and the user should know which tests to harden).
    • Use reach_path (steps from launch) and each screen's autofill (type values before the tap that needs them).
    • scroll_depth > 0 means the element is below the fold: use the tool's scroll-until-visible.
    • Assertion: the screen's title text, else a stable resource-id (see export._assertion).
    • Start from a clean launch (force-stop, then launch), because that is what the path means.
  3. Declare capabilities. If the tool can't express a step (long-press, back, a gesture), the exporter skips that screen and reports it, with the reason. Never emit a test that silently does less than the path.
  4. Secrets. Typed values come from config.placeholders (${ENV} placeholders). Never write a literal test password into generated files; packages/crawler/tests/test_secrets.py shows the expectation. Add the tool's way of reading env vars to the generated file's header comment.
  5. Output layout. tests/<format>/… or the tool's convention, one file per screen unless the tool prefers a page-object class per screen plus a path helper. Include a generated-file header with the run id.

Tests (no device needed)

  • Golden test per exporter in packages/exporters/tests/test_export.py style: a synthetic map → expected file text.
  • Cases to cover: id / text / desc / point selectors, autofill with a placeholder, scrolled element, a screen the exporter must skip, special characters in labels (quotes, regex metacharacters, unicode).
  • If the tool ships a parser or linter, run generated output through it in a test (skipped when not installed). Otherwise validate the format structurally (valid YAML / compiles / imports).
  • uv run pytest -q && uv run ruff check && uv run ruff format.

Licensing

An exporter writes text in the tool's documented format. Don't import, bundle or copy the tool's code or templates. Add a short entry to THIRD_PARTY_NOTICES.md (the tool, its license, "format only, not bundled, not affiliated") and use the tool's name descriptively only ("exports Appium tests"), never as a project name.

Verify for real

Generate for the Playground sample (runs/playground/<run-id>), run the output with the actual tool on the emulator for at least the launch screen and one three-step path, and say in your report which tool version you used. If you couldn't run it, say that plainly: "generated, not executed."

Report

List: formats added, capabilities and what's skipped, selector fallbacks (counts of point selectors), tests added, and whether the output was executed against the real tool.

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.