freshyo/e2e/flows/admin-product-full.yaml
2026-09-14 23:34:10 +05:30

243 lines
6.8 KiB
YAML

# Full product lifecycle, driven across BOTH apps in one run.
#
# Maestro's launchApp accepts an appId, so a single flow can alternate between
# the admin app and the user app and verify each change immediately.
#
# Coverage:
# - create a product + attach it to the slot (admin)
# - it is searchable and orderable (user)
# - suspend the SKU (admin) -> user: Unavailable
# - change its units (quantity attribute) (admin) -> user: new unit
# - flash: enable, then disable (admin) -> user: no 1 hr row
# - add a second variant (multiple SKUs) (admin) -> user: variant count
# - replace the image (admin)
# - save and re-verify (user)
#
# Env (see e2e/run.sh): ADMIN_NAME, ADMIN_PASSWORD, PRODUCT_NAME, PRODUCT_PRICE,
# TEST_IDENTIFIER, TEST_PASSWORD, SLOT_DELIVERY_LABEL
#
# NOTE: the image step drives the Android system Photo Picker, which only lists
# photos already on the device — e2e/run.sh pushes a fixture image first.
appId: in.freshyo.adminui
---
# --- 1. Admin: create the product and attach it to the slot ------------------
# Reuses the standalone flows so the selectors live in one place.
- runFlow: admin-product.yaml
- runFlow: admin-attach-product.yaml
# --- 2. User: the new product is searchable ---------------------------------
- launchApp:
appId: in.freshyo.app
clearState: false
- tapOn:
text: "^Home$"
optional: true
- extendedWaitUntil:
visible:
id: "add-to-cart-icon"
timeout: 90000
# The catalog is a versioned CDN file, so refresh to pick up the new product.
- swipe:
start: "50%,30%"
end: "50%,80%"
- waitForAnimationToEnd:
timeout: 10000
- tapOn: "Search fresh meat..."
- extendedWaitUntil:
visible: "All Products"
timeout: 30000
- inputText: ${PRODUCT_NAME}
- hideKeyboard
- extendedWaitUntil:
visible: "${PRODUCT_NAME}.*"
timeout: 120000
# The card carries the unit notation and the price from the admin form.
- assertVisible: "Quantity: 0.5 kg"
# --- 3. Admin: suspend the SKU, change its units, add a variant -------------
- launchApp:
appId: in.freshyo.adminui
clearState: false
- extendedWaitUntil:
visible: "Dashboard"
timeout: 90000
- tapOn: "Products"
- extendedWaitUntil:
visible: "Search products..."
timeout: 40000
- tapOn: "Search products..."
- inputText: ${PRODUCT_NAME}
- hideKeyboard
- waitForAnimationToEnd:
timeout: 5000
- tapOn: "Edit"
- extendedWaitUntil:
visible: "Enter product name"
timeout: 40000
# Units: the quantity attribute value (auto-added, name is locked to "quantity").
# Scroll to it first — centering the checkbox labels below would push it off-screen.
- scrollUntilVisible:
element:
text: "0.5 kg"
direction: DOWN
centerElement: true
timeout: 30000
- tapOn: "0.5 kg"
- eraseText
- inputText: "1 kg"
- hideKeyboard
# Multi-SKU: a second variant with its own price and unit. The leading "+" is an
# icon rather than part of the label, so match on the label alone.
- scrollUntilVisible:
element:
text: ".*Add Variant"
direction: DOWN
centerElement: true
timeout: 30000
- tapOn: ".*Add Variant"
- waitForAnimationToEnd:
timeout: 5000
- scrollUntilVisible:
element:
text: "Variant 2"
direction: DOWN
centerElement: true
timeout: 30000
- waitForAnimationToEnd:
timeout: 5000
- scrollUntilVisible:
element:
text: "Selling price"
direction: DOWN
centerElement: true
timeout: 30000
# Settle before tapping: a tap that lands while the list is still scrolling hits
# nothing, which is why this field stayed empty before.
- waitForAnimationToEnd:
timeout: 5000
- tapOn: "Selling price"
- inputText: "999"
- hideKeyboard
- scrollUntilVisible:
element:
text: "e.g. 0.5 kg"
direction: DOWN
centerElement: true
timeout: 30000
# Variant 1's price/value are already filled, so only variant 2's empty fields
# render these placeholders — exactly one match each, hence no index.
- waitForAnimationToEnd:
timeout: 5000
- tapOn: "e.g. 0.5 kg"
- inputText: "2 kg"
- hideKeyboard
# Flash: turn it on, fill the flash price, then turn it back off.
- scrollUntilVisible:
element:
text: "Flash Available"
direction: DOWN
centerElement: true
timeout: 30000
- tapOn: "Flash Available"
- waitForAnimationToEnd:
timeout: 3000
- runFlow:
when:
visible: "Enter flash price"
commands:
- tapOn: "Enter flash price"
- inputText: "399"
- hideKeyboard
- tapOn: "Flash Available"
- waitForAnimationToEnd:
timeout: 3000
# Suspend the SKU (the whole product effectively goes unavailable to users).
- tapOn: "Suspend SKU"
# Replace the image: the add tile sits just below the checkboxes, and this is the
# only path (expo-image-picker -> Android Photo Picker).
- tapOn:
point: "21%,61%"
- waitForAnimationToEnd:
timeout: 8000
- runFlow:
when:
visible: "This app can only access the photos you select"
commands:
- tapOn:
point: "16%,32%"
- waitForAnimationToEnd:
timeout: 3000
# The confirm button is labelled "Add (1)" once a photo is selected, so it
# can't be matched by a bare "Add".
- runFlow:
when:
visible: "Add.*"
commands:
- tapOn: "Add.*"
- runFlow:
when:
visible: "Done"
commands:
- tapOn: "Done"
# Save everything.
- scrollUntilVisible:
element:
text: "Save Changes"
direction: DOWN
centerElement: true
timeout: 30000
- waitForAnimationToEnd:
timeout: 5000
- tapOn: "Save Changes"
# Retry while the button is still up: a tap that lands mid-settle is swallowed,
# and the label only goes away once the mutation is actually in flight.
- repeat:
times: 5
commands:
- runFlow:
when:
visible: "Save Changes"
commands:
- waitForAnimationToEnd:
timeout: 3000
- tapOn: "Save Changes"
- extendedWaitUntil:
visible: "Product updated successfully!"
timeout: 60000
- tapOn: "OK"
# --- 4. User: the changes are visible ---------------------------------------
- launchApp:
appId: in.freshyo.app
clearState: false
- tapOn:
text: "^Home$"
optional: true
- extendedWaitUntil:
visible:
id: "add-to-cart-icon"
timeout: 90000
- swipe:
start: "50%,30%"
end: "50%,80%"
- waitForAnimationToEnd:
timeout: 10000
- tapOn: "Search fresh meat..."
- extendedWaitUntil:
visible: "All Products"
timeout: 30000
- inputText: ${PRODUCT_NAME}
- hideKeyboard
# Suspended SKU -> the card is marked out of stock and cannot be added.
- extendedWaitUntil:
visible: "${PRODUCT_NAME}.*"
timeout: 120000
- assertVisible: "Out of Stock"
- assertVisible: "UNAVAILABLE"