# Cordova Scenario Runner

> Run or triage AppsFlyer Cordova E2E/smoke via ./scripts/af-scenario-runner.sh, sibling E2E copy, smoke dir, and JSON reports. Use for local reproduction, CI log triage, or report summaries.

- Skill: `appsflyersdk/cordova-scenario-runner` (Agent Skill)
- Install (CLI): `npx skillmds@latest add appsflyersdk/cordova-scenario-runner`
- Raw SKILL.md: https://api.skillmd.com/api/skills/appsflyersdk/cordova-scenario-runner/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: appsflyersdk (https://skillmd.com/u/appsflyersdk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/appsflyersdk/cordova-scenario-runner

---


# Scenario runner — AppsFlyer Cordova plugin

Use when:

- Android/iOS E2E or smoke failed in CI and you need to reproduce or summarize reports.
- Changing `.af-e2e/test-plan.json`, `.af-smoke/rc-test-plan.json`, or build scripts used by the runner.
- Validating install/launch paths after editing `test-app/` or sync scripts.

## Cordova-specific layout

| Piece | Location |
|-------|----------|
| Runner (vendored) | `scripts/af-scenario-runner.sh` (pin in `scripts/TOOLING_PIN.txt`) |
| E2E plan | `.af-e2e/test-plan.json` — build uses **sibling** `../<repo-basename>-e2e/` (default `../appsflyer-cordova-plugin-e2e/`) via `scripts/e2e-cordova-build.sh` |
| Smoke plan | `.af-smoke/rc-test-plan.json` — paths under `test-app_rc_smoke/` via `scripts/smoke-cordova-build.sh` |
| Reference app (do not `cordova build` here with `file:..`) | `test-app/` |
| Android CI scenario entry | `scripts/ci-android-e2e-scenario.sh` (single `bash …/ci-android-e2e-scenario.sh` line inside `android-emulator-runner`; see below) |
| Reports | `.af-e2e/reports/`, `.af-smoke/reports/` |

## Preconditions

- **Android:** booted emulator; `adb devices` shows `device`.
- **iOS:** booted simulator (`xcrun simctl list devices booted`).
- **`.env`:** for E2E, on the **sibling** copy (e.g. `../appsflyer-cordova-plugin-e2e/.env`) — CI writes from `ENV_FILE`; `sync-test-app-e2e-copy.sh` **protects** `.env` on rsync.
- **`jq`** installed.

## Commands (repo root)

Dry-run parse:

```sh
./scripts/af-scenario-runner.sh --platform android --plan .af-e2e/test-plan.json --dry-run
./scripts/af-scenario-runner.sh --platform ios --plan .af-e2e/test-plan.json --dry-run
```

Build + single phase (paths / install smoke):

```sh
./scripts/af-scenario-runner.sh --platform android --plan .af-e2e/test-plan.json --build --phase phase_1
./scripts/af-scenario-runner.sh --platform ios --plan .af-e2e/test-plan.json --build --phase phase_1
```

Smoke (after `scripts/sync-test-app-rc-smoke.sh` + local build):

```sh
./scripts/af-scenario-runner.sh --platform android --plan .af-smoke/rc-test-plan.json --build --phase phase_1
```

## Read the JSON report

```sh
jq '.overall_status, .total_checks, .passed, .failed' .af-e2e/reports/latest.json
```

Failed checks:

```sh
jq -r '
  .phases[]
  | .phase_id as $pid
  | .checks | to_entries[]
  | select(.value.status != "PASS")
  | "\($pid)/\(.key): \(.value.evidence)"
' .af-e2e/reports/latest.json
```

## CI: Android `script:` must be one line

`reactivecircus/android-emulator-runner` runs **each line** of `with: script:` as a **separate** `/usr/bin/sh -c` invocation (on Ubuntu **`sh` is dash**). Multi-line `if`/`fi` in YAML **breaks**; **`set -o pipefail` is invalid in dash**. **`android-e2e.yml`** uses one line: **`bash "${GITHUB_WORKSPACE}/scripts/ci-android-e2e-scenario.sh"`** so bash-only options live in that script.

## Rules

- Do not edit generated `latest.json` / phase JSON as “fixes”; fix the app, plan, or environment.
- Exit non-zero from the runner means FAIL — do not report PASS.
- No secrets or raw `DEV_KEY` in summaries.
- Contract docs: `appsflyer-mobile-plugin-tooling` — `contracts/e2e-test-contract.md`, `contracts/smoke-test-contract.md`, `docs/troubleshooting.md`.

## Repo workplan

See `docs/SCENARIO_RUNNER_ADOPTION_WORKPLAN.md` for phases (E2E CI, test-app contract, RC smoke).

