enh
This commit is contained in:
parent
b5274e0c2b
commit
31085bdf32
5 changed files with 147 additions and 64 deletions
|
|
@ -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`}
|
||||
|
|
|
|||
|
|
@ -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
17
e2e/.env
Normal 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
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 }}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue