freshyo/tests/e2e
2026-09-16 00:36:02 +05:30
..
assets add product test 2026-09-15 23:59:59 +05:30
dev enh 2026-09-16 00:36:02 +05:30
subflows enh 2026-09-16 00:36:02 +05:30
.env.example enh 2026-09-16 00:36:02 +05:30
add-product.yaml enh 2026-09-16 00:36:02 +05:30
add-slot-with-product.yaml enh 2026-09-16 00:36:02 +05:30
config.yaml enh 2026-09-16 00:36:02 +05:30
README.md enh 2026-09-16 00:36:02 +05:30
run.sh enh 2026-09-16 00:36:02 +05:30

Admin E2E tests (Maestro)

Maestro flows that drive the admin-ui Expo app on an Android emulator.

Layout

tests/e2e/
  config.yaml            # workspace config (entry flows + execution order)
  add-product.yaml       # create a product with 2 SKUs (one flash)
  add-slot-with-product.yaml  # create a slot (delivery +60m, freeze +50m) holding that product
  subflows/
    login.yaml           # reusable login (callers invoke it conditionally)
    pick-image.yaml      # OS photo-picker adapter (Android)
    set-slot-times.yaml  # delivery +60m / freeze +50m via native pickers
  dev/
    add-empty-slot.yaml  # standalone: create a slot with no products (validate pickers)
  assets/test-product.png  # seeded into the emulator gallery via `addMedia`
  run.sh                 # loads .env and runs `maestro test`
  .env.example           # copy to .env and fill in

Prerequisites

  • Maestro CLI installed (curl -Ls "https://get.maestro.mobile.dev" | bash).
  • A booted Android emulator (maestro start-device --platform android, or Android Studio).
  • The admin-ui dev build installed on the emulator (bun run --filter admin-ui android, appId in.freshyo.adminui).
  • The build must be able to reach the backend (login + image upload hit the API/R2).

Setup

cp tests/e2e/.env.example tests/e2e/.env
# edit tests/e2e/.env — at minimum STAFF_NAME, STAFF_PASSWORD, STORE_ID

Run

bash tests/e2e/run.sh                 # every entry flow (ordered: add-product, then add-slot-with-product)
bash tests/e2e/run.sh add-product.yaml
bash tests/e2e/run.sh dev/add-empty-slot.yaml   # standalone: slot only, no product

PRODUCT_NAME is used verbatimadd-product.yaml creates it with that exact name and add-slot-with-product.yaml searches for it. The backend rejects duplicate names, so change PRODUCT_NAME (or delete the product) between suite runs.

What add-product.yaml does

  1. addMedia seeds assets/test-product.png into the emulator gallery.
  2. launchApp with clearState: true (forces login) and gallery permission.
  3. Logs in (subflow) and taps the add-product-menu-item quick action.
  4. Fills the product name and selects Store + Product Type.
  5. Variant 1: quantity, price, MRP, attaches an image.
  6. Adds Variant 2, fills quantity/prices, toggles Flash Available, sets flash price, attaches an image.
  7. Submits and asserts Product created successfully!.

What add-slot-with-product.yaml does

  1. evalScript computes delivery = now + 60 min and freeze = now + 50 min.
  2. Logs in and taps the add-slot-fab.
  3. Sets the delivery/freeze date (today) and time via the native Android pickers (android:id/button1, toggle_mode, input_hour, input_minute).
  4. Opens slot-products-selector, searches the exact PRODUCT_NAME, selects the two SKU options and taps Done.
  5. Submits and asserts Slot created successfully!.

All in-app interactions use testID selectors (id:). The exceptions are system UI — the OS photo picker (subflows/pick-image.yaml) and the native date/time pickers.

Notes / gotchas

  • The image picker flow is the most version-sensitive part; thumbs are targeted by the Android 13/14 Photo Picker id with a DocumentsUI fallback, and the confirm button by its button_add id.
  • Native time-picker ids (android:id/toggle_mode, input_hour, input_minute, button1) depend on the OS version. The date dialog defaults to today, so a run within ~60 min of midnight would put delivery on the next day.
  • On a reused emulator, addMedia images accumulate in the gallery (harmless).
  • Tests create real data on the connected backend.