This commit is contained in:
shafi54 2026-09-15 18:35:54 +05:30
parent b5274e0c2b
commit 31085bdf32
5 changed files with 147 additions and 64 deletions

View file

@ -442,6 +442,7 @@ const ProductForm = forwardRef<ProductFormRef, ProductFormProps>(({
<View style={tw`flex-1`}>
<MyTextInput
topLabel="Our Price"
testID={`variant-${vIndex}-price`}
placeholder="Selling price"
keyboardType="numeric"
value={variant.price?.toString() ?? ''}
@ -452,6 +453,7 @@ const ProductForm = forwardRef<ProductFormRef, ProductFormProps>(({
<View style={tw`flex-row items-center mb-3`}>
<Checkbox
testID={`variant-${vIndex}-flash`}
checked={variant.isFlashAvailable}
onPress={() => {
setFieldValue(`variants.${vIndex}.isFlashAvailable`, !variant.isFlashAvailable)
@ -485,6 +487,7 @@ const ProductForm = forwardRef<ProductFormRef, ProductFormProps>(({
{mode === 'edit' && (
<View style={tw`flex-row items-center mb-3`}>
<Checkbox
testID={`variant-${vIndex}-suspend`}
checked={variant.isSuspended}
onPress={() => setFieldValue(`variants.${vIndex}.isSuspended`, !variant.isSuspended)}
style={tw`mr-3`}

View file

@ -2030,3 +2030,27 @@ placeholder text:
+ id: "slot-products-selector"
e2e/flows/admin-product-full.yaml — same change for the attach leg.
[2026-09-14 22:55:00] Fix: the second variant's Our Price had no stable selector.
Symptom: saving the product edit failed validation with "price is required" —
variant 2's Our Price never received the typed value. The flow tapped the
"Selling price" PLACEHOLDER, which only exists while the field is empty; that tap
works for variant 1 (filled during create) but does not focus the lower card's
input, so inputText went nowhere and the new variant stayed priceless.
apps/admin-ui/src/components/ProductForm.tsx — give each variant's price field a
per-index testID:
<MyTextInput
topLabel="Our Price"
+ testID={`variant-${vIndex}-price`}
placeholder="Selling price"
e2e/flows/admin-product-full.yaml — target it by id (0-indexed: the new variant is
index 1) instead of by placeholder:
- - tapOn: "Selling price"
+- tapOn:
+- id: "variant-1-price"
- inputText: "999"

17
e2e/.env Normal file
View file

@ -0,0 +1,17 @@
# Copy this file to e2e/.env (gitignored). `run.sh` / `bun run e2e` loads it
# automatically, so you don't need -e flags on the command line.
#
# Login uses the username + password path ("other ways to login"), because the
# OTP flow needs a real SMS/OTP that can't be automated.
TEST_IDENTIFIER=9676651496
TEST_PASSWORD=meatfarmer@123
# Optional: the address vars already have non-secret defaults in config.yaml.
# Set them here only if you want to override those.
# ADDRESS_NAME=
# ADDRESS_PHONE=
# ADDRESS_LINE1=
ADMIN_NAME=shafi
ADMIN_PASSWORD=shafI123

View file

@ -22,37 +22,40 @@ 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.
# Slot update disabled for now — only product create + update.
- runFlow: admin-product.yaml
- runFlow: admin-attach-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"
# DISABLED while iterating on the admin side — re-enable to verify in the user
# app (it is a long leg: app switch + CDN refresh + search).
# - 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:
@ -97,8 +100,23 @@ appId: in.freshyo.adminui
centerElement: true
timeout: 30000
- tapOn: ".*Add Variant"
# Reveal the new card — it is added below the fold, and extendedWaitUntil never
# scrolls. Only retry the button if the card is still absent AFTER scrolling (a
# bare notVisible would be true while the card is merely off-screen and would
# double-tap, adding a third variant).
- scrollUntilVisible:
element:
text: "Variant 2"
direction: DOWN
centerElement: true
timeout: 30000
- runFlow:
when:
notVisible: "Variant 2"
commands:
- waitForAnimationToEnd:
timeout: 5000
timeout: 3000
- tapOn: ".*Add Variant"
- scrollUntilVisible:
element:
text: "Variant 2"
@ -117,7 +135,19 @@ appId: in.freshyo.adminui
# nothing, which is why this field stayed empty before.
- waitForAnimationToEnd:
timeout: 5000
- tapOn: "Selling price"
# Scroll to the price field — the second variant (index 1, shown as "Variant 2")
# sits below the first, so this reveals it. Tapping an off-screen field does
# nothing, hence the scroll first.
- scrollUntilVisible:
element:
id: "variant-1-price"
direction: DOWN
centerElement: true
timeout: 30000
- waitForAnimationToEnd:
timeout: 5000
- tapOn:
id: "variant-1-price"
- inputText: "999"
- hideKeyboard
- scrollUntilVisible:
@ -134,14 +164,16 @@ appId: in.freshyo.adminui
- inputText: "2 kg"
- hideKeyboard
# Flash: turn it on, fill the flash price, then turn it back off.
# Flash: turn it on, fill the flash price, then turn it back off. Tap the actual
# checkbox (id), not the label text — the label is a plain Text that ignores taps.
- scrollUntilVisible:
element:
text: "Flash Available"
id: "variant-0-flash"
direction: DOWN
centerElement: true
timeout: 30000
- tapOn: "Flash Available"
- tapOn:
id: "variant-0-flash"
- waitForAnimationToEnd:
timeout: 3000
- runFlow:
@ -151,12 +183,14 @@ appId: in.freshyo.adminui
- tapOn: "Enter flash price"
- inputText: "399"
- hideKeyboard
- tapOn: "Flash Available"
- tapOn:
id: "variant-0-flash"
- waitForAnimationToEnd:
timeout: 3000
# Suspend the SKU (the whole product effectively goes unavailable to users).
- tapOn: "Suspend SKU"
- tapOn:
id: "variant-0-suspend"
# Replace the image: the add tile sits just below the checkboxes, and this is the
# only path (expo-image-picker -> Android Photo Picker).
@ -213,31 +247,33 @@ appId: in.freshyo.adminui
- 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"
# DISABLED while iterating on the admin side — re-enable to assert the effects
# (suspended -> Out of Stock / UNAVAILABLE, new unit, no 1 hr row).
# - 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"

View file

@ -14,6 +14,7 @@ interface CheckboxProps {
checkedColor?: string; // deprecated, use checkColor
fillColor?: string; // new prop for box/circle fill
checkColor?: string; // new prop for check/tick color
testID?: string;
}
const Checkbox: React.FC<CheckboxProps> = ({
@ -25,6 +26,7 @@ const Checkbox: React.FC<CheckboxProps> = ({
checkedColor, // deprecated
fillColor,
checkColor,
testID,
}) => {
const { colors } = useTheme().theme;
const fill = fillColor || colors.brand500;
@ -39,6 +41,7 @@ const Checkbox: React.FC<CheckboxProps> = ({
style={style}
activeOpacity={0.7}
disabled={disabled}
testID={testID}
accessibilityRole="checkbox"
accessibilityState={{ checked, disabled }}
>