Skip to content
Back to skills

E2e Maestro

DSecurity

Writes and runs Maestro E2E flows on iOS simulators and Android emulators - testID steps, debug-link setup, screenshot baselines. Use when adding a flow or an e2e or screenshots run fails. Not for Jest (unit-and-component-tests).

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 18, 2026
developmentrustgojavashellbashreactnodegitapiperformance

Works with

  • cli
  • api

Security analysis

D50/100
  • criticalPipes output to a shell interpreter
  • criticalDownloads and executes remote scripts — classic supply chain attack

Pro scans all 19 files and shows the line behind each finding

Scanned October 18, 2026

npx -y skills add zakariaf/ReactNative-Skills --skill e2e-maestro --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of E2e Maestro?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for E2e Maestro
[![Security: D — Skills Directory](https://www.skillsdirectory.com/api/skills/zakariaf-e2e-maestro/badge)](https://www.skillsdirectory.com/skills/zakariaf-e2e-maestro)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: e2e-maestro
description: Writes and runs Maestro E2E flows on iOS simulators and Android emulators - testID steps, debug-link setup, screenshot baselines. Use when adding a flow or an e2e or screenshots run fails. Not for Jest (unit-and-component-tests).
---

# End-to-end flows with Maestro

The app's wiring is proven on real Release builds: Maestro flows drive the journeys on a simulator
and an emulator the repo owns, a socket sampler proves the app's network policy while they run, the
accessibility flows pass at the largest text size, and every screen is captured per platform, locale
and theme against reviewed baselines. This skill sets up that tooling, writes the flows, runs them,
and its scripts prove the setup, every flow (statically) and each run's reports. Verified on
2026-10-14 with Maestro 2.10.0, Expo SDK 57 (expo 57.0.26), React Native 0.86.3 and Xcode 26.6 with
the iOS 26.5 runtime; the Maestro facts were read in the 2.10.0 jar (re-verify:
references/maestro-setup.md, "Changing the pin"). The templates pass tsc, ESLint and Jest in the
reference app, and on 2026-10-14 the runner, the capture and the report checker ran end to end on a
Release preview build of the reference app: an iOS 26.5 simulator and an Android API 35 emulator,
phone and tablet each. The Android facts were observed on API 35; the default API 36 image is not yet
run end to end. The sampler liveness proof, the per-platform capture folders and the two-link matrix
setup came after that run and are proven by the self-test and Jest only.

## Rules that must hold

1. **Maestro comes only from the pinned installer and runs quietly.** `scripts/e2e/install-maestro.sh`
   downloads 2.10.0, checks its SHA-256, and unzips into the git-ignored `tools/maestro/`; Maestro runs
   with Java 17 and `MAESTRO_CLI_NO_ANALYTICS`, `MAESTRO_CLI_ANALYSIS_NOTIFICATION_DISABLED` and
   `MAESTRO_DISABLE_UPDATE_CHECK` set to `true`. Why: Homebrew and `curl | bash` are unpinned and
   unverified, and by default Maestro sends analytics and checks for updates.
   (`maestro-pin`, `maestro-install-source`, `maestro-env`)
2. **Every Maestro run names its device and a driver port of its own, before the command.**
   `maestro --device <udid or serial> --driver-host-port <free port> test ...`, built by
   `maestroGlobalArgs`; never the per-command `--udid` alone, never port 7001. `simctl` names a UDID,
   `adb` gets `-s <serial>`, and the devices are the repo's own `<prefix>-<purpose>`. Why: on a shared
   machine the default driver port answered from another session's simulator.
   (`maestro-device`, `shared-device`, `run-command-device`)
3. **Flows run only through the runner, on a Release build of a test variant with ads off.**
   `npm run e2e:ios` and `npm run e2e:android` refuse a Debug build (no embedded bundle: Metro's
   WebSocket hides the app's traffic), the production variant (no debug link) and a build whose
   `expo.extra` misses `contracts/e2e.json` `buildExtra` (`adsMode: off` for an app with ads: an
   ads-on build shows the consent form over every cleared launch and its ad SDK opens sockets).
   Evidence is the full run: no tag filter, the large-text step included. (`runner-build-guard`,
   `e2e-ads-off`, `runner-steps`, `run-record`, `run-filtered`)
4. **Select elements by `id:` only, with ids from the contracts.** `contracts/screens.json`
   (screen-contracts) plus `contracts/e2e.json` `extraTestIDs`; text only for OS-owned UI under a
   `# system-ui: <why>` comment; never a crop-only part (inside an accessible element, or hidden from
   screen readers). Why: the flow then runs in every locale on both platforms, and an unknown id fails
   in a second instead of after a 15 s timeout. (`text-selector`, `testid-format`, `unknown-testid`,
   `unreachable-testid`, `no-testid-step`)
5. **State comes from a cleared launch and one debug link per setup.** Each flow starts with
   `launchApp: { clearState: true }`; state is set only through `subflows/debug-setup.yaml`
   (debug-menu-and-test-hooks' `<scheme>://debug/setup?...`), whose query ends on the screen it opens
   (`open=`) and waits for that screen's testID. A language that can flip the layout direction goes
   alone, first, through `subflows/set-language.yaml` (the launch link; it waits out the restart). No
   `openLink` in flows, no tapping through menus; the one tap is the control under test. Why: setting
   up through the UI is slow and flaky, waiting for the start screen passes with a lost link, and a
   direction restart drops the rest of a link. (`first-step-launch`, `raw-open-link`, `debug-query`,
   `debug-open`, `debug-lang-alone`)
6. **iOS's "Open in …?" alert is accepted by its title, and tools never use `simctl openurl`.** Guard
   on `'Open in .*\?'` and tap `Open` below it with `optional: true`. Why: Maestro's text match ignores
   case, so a bare `'Open'` also matches any in-app OPEN button, and `openurl` leaves the alert up so
   the app never gets the link. Android-only steps (`back`, `pressKey: back`, airplane mode) run
   under `runFlow: { when: { platform: Android } }`: iOS skips them silently. (`open-alert-guard`,
   `openurl-prompt`, `platform-guard`)
7. **A flow never sets `APP_ID`, `APP_SCHEME`, `LANG` or `THEME` in `env:`.** Why: in Maestro 2.10
   a flow's `env:` beats `-e`, so every run would silently use the flow's value. (`env-shadows-cli`)
8. **Flows live in `.maestro/flows/<area>/<nn>-<name>.yaml`.** Shared steps in `subflows/`, the matrix
   in `screenshots/`, hand-run flows in declared manual folders. Why: Maestro runs only the top level
   of the folder it is given, so a nested flow never runs and a sub-flow under `flows/` runs alone and
   fails. (`flow-location`, `flow-name`, `subflow-in-flows`, `runflow-missing`, `flow-header`,
   `flow-tags`, `flow-parse`)
9. **No AI commands and nothing that uploads.** `assertWithAI`, `assertNoDefectsWithAI`,
   `extractTextWithAI`, `maestro cloud`, `maestro login`, `test --analyze`, `record` without
   `--local`. Why: they send screenshots or the app to a third party. (`ai-command`, `maestro-upload`)
10. **A flaky flow is a bug.** Wait on ids (`extendedWaitUntil`), never sleep, no `retry:` around app
    steps; a non-smoke flow may be quarantined for 7 days with `# quarantine YYYY-MM-DD: <reason>`, a
    smoke flow never. Why: retries and sleeps hide the races users hit. (`retry-app-assertion`,
    `quarantine-note`, `smoke-quarantine`)
11. **The run proves the network policy at runtime, on its own devices, with live samplers.** One
    sampler per device of the run lists the app's sockets (`lsof` on iOS, `/proc/net` by uid on
    Android); every socket `contracts/e2e.json` `network` does not allow (`offline-only`: any other
    host; `allowlist`: hosts outside `allowHosts`) fails the run, and so does a sampler that did not
    sample until the end or never found the app (`network-samplers.json`). Why: iOS simulators have no
    airplane mode, a JS-only check misses native SDKs, and a dead sampler leaves the same empty report
    as a quiet app. (`e2e-contract`, `runner-network`, `sampler-own-devices`, `sampler-liveness`,
    `network-sampler`, `network-sockets`)
12. **The accessibility flows pass at the largest text size.** `flows/a11y/` runs on the phone and
    the tablet in every `largeText.locales` entry (a left-to-right and, when the app has one, a
    right-to-left locale). Why: clipping and overlap at the largest system size (iOS AX5, about 3.6x in
    React Native; Android font scale 2.0) only show on a device, and each a11y flow sets the locale it
    is given through `set-language.yaml`. (`runner-steps`, `large-text-lang`, `large-text-missing`,
    `large-text-failed`)
13. **Screenshots come only from a still, deterministic screen, with a fixed tolerance.** Status bar
    9:41, animations held (`motion=still`), a fixed day, one device model per baseline set, baselines
    per platform; 0.2 % of pixels at a 0.1 colour distance, never raised. Each capture empties
    `reports/screenshots/<platform>/` first and records a combination that failed instead of stopping.
    Why: an animating screen differed by about 1 % between two captures a second apart, and a shared or
    stale summary passed for another platform or an earlier run. (`deterministic-capture`,
    `screenshot-tolerance`, `capture-evidence`, `matrix-incomplete`, `screenshot-capture-failed`,
    `screenshot-platform`)
14. **Baselines change only on purpose.** `--update` narrowed to the sets a change touched, every new
    or changed PNG and its diff opened, one commit with a `Gate-Change:` trailer. Why: an unread
    baseline freezes a bug for every later run. (`baseline-matrix`, `screenshot-changed`)
15. **Hand-run flows live in declared manual folders the runner never lists.** Flows that need
    production SDK behaviour or a real system prompt sit in `contracts/e2e.json` `manualFolders`; when
    `launchApp` would pre-grant the permission under test they start outside Maestro and never call it.
    Why: `launchApp` grants every permission by default, so the prompt would never show.
    (`manual-folder`, `runner-steps`)

## Workflow

1. **Prerequisites.** Screen testIDs in `contracts/screens.json` (screen-contracts), the debug link and
   `contracts/debug-links.json` (debug-menu-and-test-hooks), Release builds of the preview variant
   (ios-simulator-build, android-emulator-build, or eas-build-and-submit with `--local`), and Java 17.
   If neither `/usr/libexec/java_home -v 17` nor Android Studio's JDK exists, stop and ask the developer.
2. **Install the templates** (line 1 names each repo path): `templates/scripts/e2e/` (with every test),
   `templates/.maestro/` and `templates/contracts/e2e.json` with its schema; fill `productionAppIds`,
   `network`, `largeText` and `screenshots`, and the flows' testIDs (`assets/template-placeholders.json`
   lists what each placeholder stands for). Add the four npm scripts and `/tools/maestro/` to
   `.gitignore`; declare `screenshots` and each manual folder in `contracts/naming.json`
   `extraE2eFolders`. Read [references/maestro-setup.md](references/maestro-setup.md) and
   [references/runner-and-devices.md](references/runner-and-devices.md) the first time. Run
   `npx jest scripts/e2e --ci --maxWorkers=2`, `npm run typecheck` and `npx eslint scripts/e2e --max-warnings 0`.
3. **Check the setup:** `node ${CLAUDE_SKILL_DIR}/scripts/check-e2e-setup.mjs .`; fix every `FAIL`
   (file, rule, fix) and rerun.
4. **Write or change a flow:** read [references/flows.md](references/flows.md); one link per setup,
   ids from the contracts (screen-contracts' `list-screen.mjs` prints a screen's ids), the one tap the
   control under test; a canvas tap follows [examples/canvas-tap-flow.yaml](examples/canvas-tap-flow.yaml).
   Then `node ${CLAUDE_SKILL_DIR}/scripts/check-flows.mjs .`, and once Maestro is
   installed add `--syntax` (Maestro's own `check-syntax`, about 3 s per file).
5. **Run them:** `npm run e2e:ios` and `npm run e2e:android` (`-- --sim <purpose>` for this session's
   own devices, `-- --help` for every option). While iterating, `-- --include-tags smoke
   --skip-large-text` is fine; it is never evidence. Then
   `node ${CLAUDE_SKILL_DIR}/scripts/check-e2e-report.mjs . --platform ios` (and `android`). For a
   failure open `reports/e2e/<platform>/` and rerun that flow alone; a line in `network.txt` is a real
   finding: find the code that opened it ([references/network-proof.md](references/network-proof.md)).
   Open every screenshot under `reports/e2e/<platform>/large-text/`.
6. **Screenshot matrix** (after UI changes, before a release): read
   [references/screenshot-matrix.md](references/screenshot-matrix.md), run `npm run screenshots:ios`
   and `npm run screenshots:android` (each writes `reports/screenshots/<platform>/`), open every changed
   PNG and its diff, then `node ${CLAUDE_SKILL_DIR}/scripts/check-e2e-report.mjs . --platform ios --screenshots`
   (and `android`). Commit new
   baselines with `Gate-Change: <which screens and why>`; before a release add
   `check-e2e-setup.mjs . --baselines`.
7. **Report and clean up:** paste the `evidence:` lines the report checker prints
   ([examples/evidence-report.md](examples/evidence-report.md) shows them), name any
   quarantined flow, and shut down the devices the run started (by UDID or serial, your own only).
   [references/checks.md](references/checks.md) explains every rule and contract key.

## Definition of done

- [ ] Every new flow is in `.maestro/flows/<area>/<nn>-<name>.yaml`, selects by id, sets state through
      `debug-setup.yaml`, and was seen passing on an iOS simulator and an Android emulator.
- [ ] `npx jest scripts/e2e --ci --maxWorkers=2`, `npm run typecheck` and ESLint pass on the tooling.
- [ ] `npm run e2e:ios` and `npm run e2e:android` passed without a tag filter and with the large-text
      step; no smoke flow is quarantined; the large-text screenshots were opened.
- [ ] Every Maestro line of the run log names this session's device and a driver port of its own.
- [ ] After UI changes the matrix ran on both platforms, every changed PNG and diff was opened, and
      every baseline change has a `Gate-Change:` trailer; the tolerance is unchanged.
- [ ] Only `<prefix>-<purpose>` devices were started, each targeted by UDID or serial, and shut down.
- [ ] Allowed SKIP lines: `SKIP contracts/screens.json [unknown-testid] not yet created (screen-contracts creates it)`
      (and `[unreachable-testid]`), `SKIP contracts/debug-links.json [debug-query] not yet created (debug-menu-and-test-hooks creates it)`,
      `SKIP scripts/ios/simulators.ts [runner-file-missing] not yet created (ios-simulator-build creates it)`
      (and `toolchain.ts`), `SKIP scripts/android/adb-args.ts [runner-file-missing] not yet created (android-emulator-build creates it)`;
      `NOT APPLICABLE: the app has no Maestro E2E yet ...` before step 2.
- [ ] `node ${CLAUDE_SKILL_DIR}/scripts/check-e2e-report.mjs . --platform ios` and `--platform android` print `RESULT: PASS`.
- [ ] `node ${CLAUDE_SKILL_DIR}/scripts/check-e2e-setup.mjs .` prints `RESULT: PASS` (with `--baselines` before a release).
- [ ] `node ${CLAUDE_SKILL_DIR}/scripts/check-flows.mjs . --syntax` prints `RESULT: PASS`

## Anti-patterns

- **`tapOn: 'Add task'` or `assertVisible: 'Tasks'`.** Breaks in every other locale and whenever the
  copy changes. Use `id: 'tasks.add-button'`.
- **Tapping Settings → Language → … to reach a state.** Slow, flaky, and every screen change breaks
  unrelated flows. One debug link that ends on the screen under test.
- **`xcrun simctl openurl` (or `adb -s <serial> shell am start -d` with the URL quoted once) from a
  script.** iOS waits on an alert nobody accepts; the device shell cuts the URL at `&`. Run the
  open-link or debug-setup sub-flow through `runMaestro`.
- **`brew install maestro` or the `curl | bash` installer.** Unknown version, no checksum, analytics
  on. Run `scripts/e2e/install-maestro.sh` (the runner calls it anyway).
- **Running on the booted simulator, on "the only emulator", or on a Debug build.** Another session's
  device breaks, and Metro's socket makes the network proof meaningless.
- **An `env:` block with `APP_ID` "so the flow runs on its own".** It overrides `-e`; pass
  `-e APP_ID=... -e APP_SCHEME=...` when running one flow by hand.
- **`retry:` or a longer timeout to make a red flow green.** Hides the race users hit. Wait on the id
  that proves the state, or fix the app.
- **`--update` for every set, or a bigger `MAX_DIFF_RATIO`, to clear a diff.** Accepts regressions
  nobody looked at. Open the diff, fix the screen, update only what you meant to change.
- **`assertNoDefectsWithAI` for "visual QA".** It uploads screenshots. Open the PNGs.
- **Adding a host to `allowHosts` to silence `network.txt`.** Find who opened the socket first; a new
  host is a privacy declaration change (privacy-and-store-declarations), agreed with the reviewer. An
  ad network's host never goes there: the E2E build has ads off (`buildExtra`).
- **Trusting an empty `network.txt` on its own.** A sampler that crashed or never matched the app
  leaves it empty too; the evidence is `network-samplers.json` with every device alive to the end.
- **`lang=${LANG}&theme=...&open=...` in one link.** In the right-to-left locale the app restarts and
  the rest is lost; run `set-language.yaml` first.
- **A shared sub-flow under `flows/`, or a flow two folders deep.** One runs alone and fails, the
  other never runs.
- **Tapping a row right after `scrollUntilVisible`.** A tap while the list still glides only stops it;
  `waitForAnimationToEnd` first.

## Files in this skill

| File | What it is | Read/run when |
|---|---|---|
| [references/maestro-setup.md](references/maestro-setup.md) | The pin, the installer, the quiet environment, device and driver port on both platforms, verified and banned commands, `check-syntax`, changing the pin | Workflow step 2, an install or command failure |
| [references/runner-and-devices.md](references/runner-and-devices.md) | What a run needs, the runner's steps, the build guard, iOS simulators and Android emulators, large text, reports, failures | Workflow steps 2 and 5 |
| [references/flows.md](references/flows.md) | Folders, names, headers and tags, id selectors, the debug-link setup, sub-flows, waits, canvas taps, manual folders, quarantine, what a flow should not prove | Workflow step 4 |
| [references/network-proof.md](references/network-proof.md) | The three network modes, how each platform's sampler works, reading `network.txt` | Workflow step 5, a network finding |
| [references/screenshot-matrix.md](references/screenshot-matrix.md) | Still screens, running the matrix, baselines per platform, review, the gallery, the large-text pass | Workflow step 6 |
| [references/checks.md](references/checks.md) | `contracts/e2e.json` keys, every checker rule with its reason, SKIP and NOT APPLICABLE lines, when multi-package | A `FAIL` line, editing the contract |
| [examples/canvas-tap-flow.yaml](examples/canvas-tap-flow.yaml) | A flow that taps a Skia canvas cell from the canvas layout probe | Writing a canvas flow |
| [examples/evidence-report.md](examples/evidence-report.md) | The evidence lines of a passing run, as a report shows them | Workflow step 7 |
| `templates/scripts/e2e/install-maestro.sh` | Pinned, checksum-verified, idempotent installer | Workflow step 2 |
| `templates/scripts/e2e/run-e2e.ts` | `npm run e2e:<platform>`: build guard, flows, large text, samplers, `run.json` | Workflow step 2 |
| `templates/scripts/e2e/e2e-cli.ts` | The runner's command line, pure (+ test) | Workflow step 2 |
| `templates/scripts/e2e/e2e-config.ts` | Reads `contracts/e2e.json` with valibot, defaults filled (+ test) | Workflow step 2 |
| `templates/scripts/e2e/e2e-device.ts` | The device interface both platforms implement | Workflow step 2 |
| `templates/scripts/e2e/build-guard.ts` | Release, test-variant and `buildExtra` (ads off) check from the build's embedded config (+ test) | Workflow step 2 |
| `templates/scripts/e2e/ios-device.ts` | An iOS simulator by UDID: boot, install, status bar, text size, appearance (+ test) | Workflow step 2 |
| `templates/scripts/e2e/android-device.ts` | An Android emulator by serial: AVD, boot, demo mode, font scale, night mode (+ test) | Workflow step 2 |
| `templates/scripts/e2e/open-device.ts` | Opens the build and the device of one platform | Workflow step 2 |
| `templates/scripts/e2e/maestro-run.ts` | `runMaestro`, the quiet environment, `appEnv`, `debugSetupArgs` (+ test) | Workflow step 2 |
| `templates/scripts/e2e/maestro-args.ts` | `maestroGlobalArgs`, `freeDriverPort`, `driverPortFor`, `maestroRunLine` (synced; do not edit here) | Workflow step 2 |
| `templates/scripts/e2e/maestro-args.test.ts` | Its test (synced; do not edit here) | With maestro-args |
| `templates/scripts/e2e/network-sampler.ts` | Pure socket parsing for both platforms and the policy judge (+ test) | Workflow step 2 |
| `templates/scripts/e2e/sample-sockets.ts` | The sampler process, one per device of a run; rewrites its status after every sample | Workflow step 2 |
| `templates/scripts/e2e/sampler-evidence.ts` | The liveness proof: `trackSampler`, `proveSamplersAlive`, `network-samplers.json` (+ test) | Workflow step 2 |
| `templates/scripts/e2e/capture-screenshots.ts` | `npm run screenshots:<platform>`: capture, compare, `capture-failed` rows, `reports/screenshots/<platform>/` summary and gallery | Workflow step 2 |
| `templates/scripts/e2e/screenshots-cli.ts` | Its command line, pure (+ test) | Workflow step 2 |
| `templates/scripts/e2e/screenshot-compare.ts` | One screenshot against its baseline, the gated tolerances | Workflow step 2 |
| `templates/scripts/e2e/png-diff.ts` | Zero-dependency PNG decode, colour distance and diff image (+ test) | Workflow step 2 |
| `templates/scripts/e2e/write-gallery.ts` | The baseline / run / diff gallery (+ test) | Workflow step 2 |
| `templates/scripts/e2e/` | The modules above with their `*.test.ts` files | Workflow step 2 |
| `templates/.maestro/subflows/` | `open-link.yaml`, `debug-setup.yaml`, `shoot-screen.yaml`, `set-language.yaml` (a language alone, as the launch link), `airplane-mode.yaml` (optional: real airplane mode on Android) | Workflow step 2 |
| `templates/.maestro/screenshots/matrix.yaml` | The capture flow: the language alone, then the rest, then one `runFlow` per screen | Workflow steps 2 and 6 |
| `templates/.maestro/flows/` | A smoke flow and an offline journey that survives a kill | Workflow steps 2 and 4 |
| `templates/contracts/e2e.json` | The app's E2E facts | Workflow step 2 |
| `templates/contracts/e2e.schema.json` | Its schema: every key, its meaning and default | Editing the contract |
| `assets/template-placeholders.json` | What each template placeholder stands for (the reference Tasks app's values) | Workflow step 2 |
| `assets/shared.json` | The synced-file manifest | When a shared file is added |
| `scripts/check-flows.mjs` | Checks every flow statically (30 rules) | Workflow step 4, definition of done |
| `scripts/check-e2e-setup.mjs` | Checks the tooling, contract, scripts and baselines (22 rules) | Workflow step 3, definition of done |
| `scripts/check-e2e-report.mjs` | Checks one run's reports, the samplers' liveness and one platform's capture, and prints the evidence lines (13 rules) | Workflow steps 5-6, definition of done |
| `scripts/lib/e2e-repo.mjs` | Layout, adoption, the contracts and the known testIDs | Never by hand |
| `scripts/lib/flow-rules.mjs` | The per-file flow rules | Never by hand |
| `scripts/lib/maestro-yaml.mjs` | Zero-dependency Maestro YAML reader with line numbers | Never by hand |
| `scripts/lib/maestro-spawns.mjs` | The `maestro-device` spawn rule (synced; do not edit here) | Never by hand |
| `scripts/check-lib.mjs` | Shared checker library (synced; do not edit here) | Never by hand |
| `scripts/selftest.mjs` | Proves the three checkers against `tests/fixtures/` | After changing a checker or a template |
| `tests/bases/` | The small app and report trees the cases start from | When adding a fixture |
| `tests/fixtures/` | Overlay cases: good (the templates), a bad case per rule, pass and error cases | When adding a rule |

## Related skills

- `screen-contracts` - the testIDs flows select by (`contracts/screens.json`).
- `debug-menu-and-test-hooks` - the debug link, its contract and the simulated clock and network.
- `ios-simulator-build` and `android-emulator-build` - the Release builds the runner tests, and the device kits it imports (`scripts/ios/`, and `adbArgs` from `scripts/android/adb-args.ts`).
- `eas-build-and-submit` - local EAS builds of the preview profile.
- `naming-conventions` - testID and flow-file names, `extraE2eFolders`.
- `golden-and-snapshot-tests` - the baseline policy screenshots share with pixel goldens.
- `run-goldens-rebaseline` - regenerating every baseline after a runtime, Xcode or design-wide change.
- `privacy-and-store-declarations` - what the network policy declares to the stores.
- `accessibility-as-code` and `rtl-and-direction` - the large-text and language-switch flows.
- `performance-budgets` - simulator and emulator cold-start and memory runs.
- `unit-and-component-tests` - everything a flow should not have to prove.
- `git-commits-and-reporting` - the Gate-Change trailer and the evidence report.

Files in this skill

  • SKILL.md23.9 KB
  • assets/shared.json496 B
  • assets/template-placeholders.json647 B
  • examples/canvas-tap-flow.yaml1.6 KB
  • examples/evidence-report.md1.8 KB
  • references/checks.md11.8 KB
  • references/flows.md16.6 KB
  • references/maestro-setup.md11.2 KB
  • references/network-proof.md7.3 KB
  • references/runner-and-devices.md15.5 KB
  • references/screenshot-matrix.md9.4 KB
  • scripts/check-e2e-report.mjs19.4 KB
  • scripts/check-e2e-setup.mjs34.4 KB
  • scripts/check-flows.mjs27.9 KB
  • scripts/lib/e2e-repo.mjs11.4 KB
  • scripts/lib/flow-rules.mjs12.1 KB
  • scripts/lib/maestro-spawns.mjs9.7 KB
  • scripts/lib/maestro-yaml.mjs7.3 KB
  • scripts/selftest.mjs749 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.