CLAUDE.md
e2e/demo_app/CLAUDE.mdCLAUDE.md
Quality
81/100
Scores the file, not the repository.Length
928 words
17 headings · 2 code blocksRepository
15k
— · pushed 0 days agoLast changed
3 days ago
First indexed 3 days ago.1# CLAUDE.md23This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.45## What This Is67A Flutter demo app used as the target app for end-to-end testing of the [Maestro](https://github.com/mobile-dev-inc/maestro) mobile UI testing framework. It is not a production app — its screens exist to exercise specific Maestro features and reproduce specific bugs.89When new screens or behaviors are needed to test a Maestro feature, they are added here.1011## Build Commands1213```sh14# Run the app (requires a connected device or emulator)15flutter run1617# Build Android APK18flutter build apk1920# Build iOS simulator app21flutter build ios --simulator2223# Analyze code24flutter analyze25```2627## Maestro Flow Commands2829Flows live in `.maestro/`. **Prefer the Maestro MCP** for authoring, running, and debugging flows interactively (`list_devices` → `inspect_screen` / `take_screenshot` → `run`): it returns the view hierarchy and screenshots inline, which is far more effective for iterating than parsing CLI output. Use the CLI below for scripted or CI-style runs, or when no MCP is available.3031```sh32# Run all flows33maestro test .maestro/3435# Run a single flow36maestro test .maestro/fill_form.yaml3738# Run flows with a specific tag39maestro test --include-tags passing .maestro/40```4142**The MCP runs a *built* Maestro, not your working tree.** If you change Maestro framework code (anything outside `e2e/`) and want to validate it through the MCP against this app, the MCP will keep using the old build until Maestro is rebuilt **and the MCP is reconnected** (e.g. `/mcp reconnect maestro`). Rebuild, reconnect, then re-run. This is separate from rebuilding the demo app itself (see Build Commands) — a Dart/iOS/Android change to this app needs the app rebuilt and reinstalled on the device before the MCP will see it.4344## Architecture4546### Flutter App (`lib/`)4748`main.dart` is the home screen with buttons navigating to each test screen. Each screen is a standalone Dart file targeting a specific testing scenario:4950| File | Purpose |51|---|---|52| `form_screen.dart` | Login form with email/password validation |53| `input_screen.dart` | Keyboard and text input behaviors |54| `swiping_screen.dart` | Swipe gesture testing |55| `nesting_screen.dart` | Deeply nested widget hierarchies |56| `location_screen.dart` | GPS location via `geolocator`, streams position updates |57| `sensors_screen.dart` | Device sensors (Android only) |58| `webview.dart` | Embedded WebView via `webview_flutter` |59| `defects_screen.dart` | Intentional UI quirks for defect regression |60| `cropped_screenshot_screen.dart` | Screenshot cropping edge cases |61| `notifications_permission_screen.dart` | Permission request flows |62| `permission_check_screen.dart` | Passively displays permission status (location, all-files) via `permission_handler` — never calls `requestPermission()`, so it reflects a pre-granted state deterministically |63| `issue_1619_repro.dart`, `issue_1677_repro.dart` | Bug reproductions |6465The app reads launch arguments via `flutter_launch_arguments` (e.g., `initialCounter`, `delay`) so Maestro flows can configure app state at launch.6667### Maestro Flows (`.maestro/`)6869- **Root flows** (`*.yaml`): Main passing/failing test cases, tagged `passing` or used to assert expected failures.70- **`commands/`**: Reusable Maestro command definitions (e.g., `assertVisible.yaml`, `inputText.yaml`).71- **`android_device_configuration/`** and **`ios_device_configuration/`**: Device setup flows run before tests (disable autocorrect, set timezone, enable sensors, etc.).72- **`web_flows/`**: Flows targeting web/WebView scenarios.73- **`issues/`**: Flows specifically reproducing reported Maestro bugs.74- **`experimental/`**: Unstable/in-progress flows not included in CI.75- **`scripts/`**: JavaScript helpers used by `evalScript` commands.7677`config.yaml` configures which flow directories Maestro includes when running `maestro test .maestro/`.7879**Platform targeting.** Write flows to run on both Android and iOS by default. Add an `android` or `ios` tag only when the behaviour is genuinely platform-specific — a flow with no platform tag runs on every platform. Prefer keeping a single cross-platform flow over splitting into per-platform files: use `${maestro.platform == "android" ? ... : ...}` for platform-specific values, and `runFlow` with `when: platform:` to guard platform-specific steps.8081### App ID8283All flows target `appId: com.example.example`.8485## Testing Permissions8687Non-obvious gotchas when writing permission flows against this app:8889- **iOS: each `permission_handler` permission must be enabled in `ios/Podfile`.** A permission's handler is compiled in only when its macro is set in `GCC_PREPROCESSOR_DEFINITIONS` (e.g. `PERMISSION_LOCATION=1`). Without it, that permission's `.status` **silently returns denied on iOS** regardless of the real authorization. Enabled today: notifications, location. After editing the Podfile, run `pod install` in `ios/` before `flutter build ios` — a Podfile edit alone won't trigger it.90- **Android: runtime permissions must be declared in `AndroidManifest.xml`** or they can't be granted (`pm grant` throws). Declared today: INTERNET, ACCESS_FINE/COARSE_LOCATION, MANAGE_EXTERNAL_STORAGE. (So e.g. POST_NOTIFICATIONS can't be granted here.)91- **Permission values are platform-specific.** Android uses `allow`/`deny`/`unset`; iOS `location` uses `always`/`inuse`/`never`/`unset`. iOS *validates* location values and throws on anything else; Android silently falls back to revoke for unknown/empty values. For cross-platform flows, pick per platform: `location: ${maestro.platform == "android" ? "allow" : "always"}`.92- **`launchApp` with no `permissions:` block defaults to `all: allow`.**93- **Observe passively.** `permission_check_screen.dart` reads status without requesting — use it to assert a pre-granted state on both platforms. Avoid `location_screen.dart` (geolocator) for that: it actively calls `requestPermission()`, popping a dialog (Android does not auto-dismiss it) and resolving position asynchronously.94- **`MANAGE_EXTERNAL_STORAGE` is an appOps permission** on Android (special path), not a standard `pm grant` runtime permission.9596## Adding New Test Screens97981. Create a new `lib/<feature>_screen.dart` with a `StatefulWidget`.992. Add a navigation button in `lib/main.dart`.1003. Write the flow that exercises the **Maestro feature** you are testing, tagged `[passing]`. The flow is the point — the screen exists only to make that Maestro behaviour observable, not to be tested itself. Add a platform tag only if the behaviour is platform-specific (see **Platform targeting** above).1014. For location or sensor tests, ensure relevant device configuration flows exist in the platform-specific subdirectories.102
Also in mobile-dev-inc/Maestro
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| mobile-dev-inc/MaestroAGENTS.md · 15k | AGENTS.md | teststyletesting-strategyapi+1 | 74/100 | 3 days ago |
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| Adit-Jain-srm/NightmareNetCLAUDE.md · 45 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 3 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 3 days ago | |
| microsoft/playwrightCLAUDE.md · 94k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| filamentphp/filamentCLAUDE.md · 32k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 3 days ago | |
| lollipopkit/flutter_server_boxCLAUDE.md · 8.3k | CLAUDE.md | buildteststylearch+2 | 98/100 | 3 days ago | |
| carrot-foundation/middle-earthCLAUDE.md · 0 | CLAUDE.md | setupbuildtestlint-format+6 | 97/100 | 3 days ago | |
| khrnchn/sedekah-jeCLAUDE.md · 89 | CLAUDE.md | testlint-formatstylearch+6 | 97/100 | 3 days ago |
