enh
This commit is contained in:
parent
e560f51fe7
commit
a40725213f
11 changed files with 331 additions and 21 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { MaterialCommunityIcons, Entypo } from '@expo/vector-icons';
|
import { MaterialCommunityIcons, Entypo } from '@expo/vector-icons';
|
||||||
import { View, TouchableOpacity, FlatList, Alert, ActivityIndicator } from 'react-native';
|
import { View, TouchableOpacity, FlatList, Alert, ActivityIndicator } from 'react-native';
|
||||||
import { AppContainer, MyText, tw, MyFlatList , BottomDialog, MyTouchableOpacity, Checkbox } from 'common-ui';
|
import { MyText, tw, MyFlatList , BottomDialog, MyTouchableOpacity, Checkbox } from 'common-ui';
|
||||||
import { trpc } from '@/src/trpc-client';
|
import { trpc } from '@/src/trpc-client';
|
||||||
import { useRouter } from 'expo-router';
|
import { useRouter } from 'expo-router';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
|
||||||
107
change-log.txt
107
change-log.txt
|
|
@ -2280,6 +2280,113 @@ Confirmed from AOSP MediaProvider res/layout/activity_photo_picker.xml:
|
||||||
guard so they can only run while the picker is still open (previously the text
|
guard so they can only run while the picker is still open (previously the text
|
||||||
regex could have tapped "Add Variant" in the app after the picker closed)
|
regex could have tapped "Add Variant" in the app after the picker closed)
|
||||||
|
|
||||||
|
[2026-09-16 00:05:33] Add slot E2E flow (create slot with relative times holding the product) + verbatim product name.
|
||||||
|
|
||||||
|
Product name is now used verbatim from .env (no timestamp suffix) so the slot flow can
|
||||||
|
search for the exact product created by add-product.yaml.
|
||||||
|
|
||||||
|
=== apps/admin-ui/app/(drawer)/dashboard/slots/index.tsx ===
|
||||||
|
- import: removed unused `AppContainer` from the common-ui import
|
||||||
|
(the list already renders <View> + <MyFlatList>, so no nested scroll)
|
||||||
|
|
||||||
|
=== tests/e2e/run.sh ===
|
||||||
|
- removed `PRODUCT_NAME="${PRODUCT_NAME} $(date +%s)"` (and its export) — name used verbatim
|
||||||
|
|
||||||
|
=== tests/e2e/.env.example ===
|
||||||
|
- PRODUCT_NAME comment updated: exact name, must be unique per run
|
||||||
|
|
||||||
|
=== tests/e2e/config.yaml ===
|
||||||
|
- added executionOrder (continueOnFailure: false; flowsOrder: add-product, add-slot-with-product)
|
||||||
|
|
||||||
|
=== tests/e2e/add-slot-with-product.yaml (NEW) ===
|
||||||
|
- login -> add-slot-fab
|
||||||
|
- evalScript computes delivery(+60m) and freeze(+50m) HH/MM
|
||||||
|
- delivery/freeze date via <x>-date-picker -> android:id/button1
|
||||||
|
- delivery/freeze time via <x>-time-picker -> android:id/toggle_mode (optional)
|
||||||
|
-> android:id/input_hour / input_minute (eraseText + inputText) -> android:id/button1
|
||||||
|
- products via slot-products-selector -> slot-products-selector-search -> inputText ${PRODUCT_NAME}
|
||||||
|
-> slot-products-selector-option-.* (index 0,1) -> slot-products-selector-done
|
||||||
|
- create-slot-button -> assert "Slot created successfully!" -> OK
|
||||||
|
|
||||||
|
=== tests/e2e/README.md ===
|
||||||
|
- documented the slot flow, suite ordering, and the verbatim-name caveat
|
||||||
|
|
||||||
|
[2026-09-16 00:08:22] Extract slot time-picking into a subflow + add a standalone empty-slot flow.
|
||||||
|
|
||||||
|
Purpose: validate the native date/time picker interaction in isolation, without
|
||||||
|
creating a product first.
|
||||||
|
|
||||||
|
=== tests/e2e/subflows/set-slot-times.yaml (NEW) ===
|
||||||
|
- computes delivery(+60m)/freeze(+50m) HH/MM via evalScript and drives the native
|
||||||
|
pickers (delivery/freeze date-picker -> android:id/button1; time-picker ->
|
||||||
|
android:id/toggle_mode (optional) -> input_hour / input_minute -> button1)
|
||||||
|
extracted verbatim from add-slot-with-product.yaml
|
||||||
|
|
||||||
|
=== tests/e2e/add-slot-with-product.yaml ===
|
||||||
|
- replaced the inline evalScript + delivery/freeze picker blocks with
|
||||||
|
`runFlow: subflows/set-slot-times.yaml`
|
||||||
|
|
||||||
|
=== tests/e2e/dev/add-empty-slot.yaml (NEW) ===
|
||||||
|
- standalone flow: login -> add-slot-fab -> set-slot-times -> create-slot-button
|
||||||
|
-> assert "Slot created successfully!" (no products)
|
||||||
|
- lives in dev/ so the root `*.yaml` suite glob does not pick it up
|
||||||
|
|
||||||
|
[2026-09-16 00:11:19] Fix slot flows: navigate to the Slots list before the FAB.
|
||||||
|
|
||||||
|
Symptom: `Element not found: Id matching regex: add-slot-fab`. The FAB is on the
|
||||||
|
Slots list screen, but the flows tapped it right after login (which lands on the
|
||||||
|
dashboard).
|
||||||
|
|
||||||
|
=== tests/e2e/add-slot-with-product.yaml ===
|
||||||
|
- added: scrollUntilVisible delivery-slots-menu-item -> tapOn delivery-slots-menu-item
|
||||||
|
-> assertVisible add-slot-fab, before tapping add-slot-fab
|
||||||
|
|
||||||
|
=== tests/e2e/dev/add-empty-slot.yaml ===
|
||||||
|
- same navigation added after login
|
||||||
|
|
||||||
|
[2026-09-16 00:21:09] Make login subflow idempotent; relaunch app between suite flows.
|
||||||
|
|
||||||
|
Symptom: after add-product succeeded (already authenticated, not on the login
|
||||||
|
screen), add-slot-with-product failed at `Assertion is false: id: login-name-input
|
||||||
|
is visible`.
|
||||||
|
|
||||||
|
=== tests/e2e/subflows/login.yaml ===
|
||||||
|
- wrapped the login steps in `runFlow: when: visible id: login-name-input`, so the
|
||||||
|
subflow logs in only if the login screen is showing (reusable standalone or after
|
||||||
|
another already-authenticated flow)
|
||||||
|
- removed the trailing `assertVisible add-product-menu-item` (callers wait for their
|
||||||
|
own first element)
|
||||||
|
|
||||||
|
=== tests/e2e/add-slot-with-product.yaml ===
|
||||||
|
- added `launchApp` before login so the app restarts at its initial route
|
||||||
|
(dashboard when already logged in, login otherwise)
|
||||||
|
|
||||||
|
=== tests/e2e/dev/add-empty-slot.yaml ===
|
||||||
|
- added `launchApp` before login for the same reason
|
||||||
|
|
||||||
|
[2026-09-16 00:22:43] Keep login.yaml as a real flow; make the invocation conditional.
|
||||||
|
|
||||||
|
Rework of the previous entry: login.yaml is a normal (unconditional) login flow
|
||||||
|
again; callers invoke it only when the login screen is showing.
|
||||||
|
|
||||||
|
=== tests/e2e/subflows/login.yaml ===
|
||||||
|
- restored unconditional login steps + trailing `assertVisible add-product-menu-item`
|
||||||
|
(no inner `when`)
|
||||||
|
|
||||||
|
=== tests/e2e/add-product.yaml, add-slot-with-product.yaml, dev/add-empty-slot.yaml ===
|
||||||
|
- replaced `runFlow: <login path>` with a conditional inline wrapper:
|
||||||
|
- runFlow:
|
||||||
|
when:
|
||||||
|
visible:
|
||||||
|
id: login-name-input
|
||||||
|
commands:
|
||||||
|
- runFlow: <login path>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@ APP_ID=in.freshyo.adminui
|
||||||
STAFF_NAME=
|
STAFF_NAME=
|
||||||
STAFF_PASSWORD=
|
STAFF_PASSWORD=
|
||||||
|
|
||||||
# Product under test. run.sh appends a timestamp so re-runs don't collide with
|
# Product under test. Used verbatim: add-product.yaml creates it with this exact
|
||||||
# the backend's unique-name check.
|
# name and add-slot-with-product.yaml searches for it. The backend rejects
|
||||||
|
# duplicate names, so change it (or delete the product) between suite runs.
|
||||||
PRODUCT_NAME="E2E Test Product"
|
PRODUCT_NAME="E2E Test Product"
|
||||||
|
|
||||||
# Id of the store to pick in the Store dropdown (see the Stores screen / DB)
|
# Id of the store to pick in the Store dropdown (see the Stores screen / DB)
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,17 @@ Maestro flows that drive the **admin-ui** Expo app on an Android emulator.
|
||||||
|
|
||||||
```
|
```
|
||||||
tests/e2e/
|
tests/e2e/
|
||||||
config.yaml # workspace config (entry flows = *.yaml at the root)
|
config.yaml # workspace config (entry flows + execution order)
|
||||||
add-product.yaml # first flow: create a product with 2 SKUs (one flash)
|
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/
|
subflows/
|
||||||
login.yaml # reusable login
|
login.yaml # reusable login (callers invoke it conditionally)
|
||||||
pick-image.yaml # OS photo-picker adapter (Android)
|
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`
|
assets/test-product.png # seeded into the emulator gallery via `addMedia`
|
||||||
run.sh # sources .env and runs `maestro test`
|
run.sh # loads .env and runs `maestro test`
|
||||||
.env.example # copy to .env and fill in
|
.env.example # copy to .env and fill in
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -33,11 +37,14 @@ cp tests/e2e/.env.example tests/e2e/.env
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash tests/e2e/run.sh # every entry flow in tests/e2e/
|
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 add-product.yaml
|
||||||
|
bash tests/e2e/run.sh dev/add-empty-slot.yaml # standalone: slot only, no product
|
||||||
```
|
```
|
||||||
|
|
||||||
`run.sh` appends a timestamp to `PRODUCT_NAME` (the backend rejects duplicate names).
|
`PRODUCT_NAME` is used **verbatim** — `add-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
|
## What `add-product.yaml` does
|
||||||
|
|
||||||
|
|
@ -49,14 +56,26 @@ bash tests/e2e/run.sh add-product.yaml
|
||||||
6. Adds Variant 2, fills quantity/prices, toggles **Flash Available**, sets flash price, 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!`.
|
7. Submits and asserts `Product created successfully!`.
|
||||||
|
|
||||||
All in-app interactions use `testID` selectors (`id:`). The only exception is the
|
## What `add-slot-with-product.yaml` does
|
||||||
OS photo picker, which is system UI and is targeted by its platform IDs in
|
|
||||||
`subflows/pick-image.yaml`.
|
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
|
## Notes / gotchas
|
||||||
|
|
||||||
- The image picker flow is the most version-sensitive part; thumbs are targeted by
|
- 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
|
the Android 13/14 Photo Picker id with a DocumentsUI fallback, and the confirm
|
||||||
button by text regex `Add|Done|Select`.
|
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).
|
- On a reused emulator, `addMedia` images accumulate in the gallery (harmless).
|
||||||
- Tests create real data on the connected backend.
|
- Tests create real data on the connected backend.
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,12 @@ tags:
|
||||||
permissions:
|
permissions:
|
||||||
storage: allow
|
storage: allow
|
||||||
|
|
||||||
# --- Login ---
|
# --- Login (only when the login screen is showing) ---
|
||||||
|
- runFlow:
|
||||||
|
when:
|
||||||
|
visible:
|
||||||
|
id: login-name-input
|
||||||
|
commands:
|
||||||
- runFlow: subflows/login.yaml
|
- runFlow: subflows/login.yaml
|
||||||
|
|
||||||
# --- Navigate to Add Product ---
|
# --- Navigate to Add Product ---
|
||||||
|
|
|
||||||
69
tests/e2e/add-slot-with-product.yaml
Normal file
69
tests/e2e/add-slot-with-product.yaml
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
appId: ${APP_ID || "in.freshyo.adminui"}
|
||||||
|
env:
|
||||||
|
APP_ID: ${APP_ID || "in.freshyo.adminui"}
|
||||||
|
STAFF_NAME: ${STAFF_NAME || ""}
|
||||||
|
STAFF_PASSWORD: ${STAFF_PASSWORD || ""}
|
||||||
|
# Must be the exact name created by add-product.yaml.
|
||||||
|
PRODUCT_NAME: ${PRODUCT_NAME || "E2E Test Product"}
|
||||||
|
tags:
|
||||||
|
- slots
|
||||||
|
- smoke
|
||||||
|
---
|
||||||
|
# Restart the app so it returns to its initial route (dashboard when already
|
||||||
|
# logged in from add-product.yaml, login otherwise).
|
||||||
|
- launchApp
|
||||||
|
# Login only when the login screen is showing (already authenticated in-suite).
|
||||||
|
- runFlow:
|
||||||
|
when:
|
||||||
|
visible:
|
||||||
|
id: login-name-input
|
||||||
|
commands:
|
||||||
|
- runFlow: subflows/login.yaml
|
||||||
|
|
||||||
|
# --- Open the Slots list from the dashboard, then the create-slot screen ---
|
||||||
|
- scrollUntilVisible:
|
||||||
|
element:
|
||||||
|
id: delivery-slots-menu-item
|
||||||
|
direction: DOWN
|
||||||
|
- tapOn:
|
||||||
|
id: delivery-slots-menu-item
|
||||||
|
- assertVisible:
|
||||||
|
id: add-slot-fab
|
||||||
|
- tapOn:
|
||||||
|
id: add-slot-fab
|
||||||
|
- assertVisible:
|
||||||
|
id: delivery-date-picker
|
||||||
|
|
||||||
|
# --- Delivery (+60m) and Freeze (+50m) date/times ---
|
||||||
|
- runFlow: subflows/set-slot-times.yaml
|
||||||
|
|
||||||
|
# --- Add the product to the slot (search the exact name, select its SKUs) ---
|
||||||
|
- scrollUntilVisible:
|
||||||
|
element:
|
||||||
|
id: slot-products-selector
|
||||||
|
direction: DOWN
|
||||||
|
- tapOn:
|
||||||
|
id: slot-products-selector
|
||||||
|
- tapOn:
|
||||||
|
id: slot-products-selector-search
|
||||||
|
- inputText: ${PRODUCT_NAME}
|
||||||
|
- hideKeyboard
|
||||||
|
- tapOn:
|
||||||
|
id: 'slot-products-selector-option-.*'
|
||||||
|
index: 0
|
||||||
|
- tapOn:
|
||||||
|
id: 'slot-products-selector-option-.*'
|
||||||
|
index: 1
|
||||||
|
- tapOn:
|
||||||
|
id: slot-products-selector-done
|
||||||
|
|
||||||
|
# --- Submit ---
|
||||||
|
- scrollUntilVisible:
|
||||||
|
element:
|
||||||
|
id: create-slot-button
|
||||||
|
direction: DOWN
|
||||||
|
- tapOn:
|
||||||
|
id: create-slot-button
|
||||||
|
|
||||||
|
- assertVisible: 'Slot created successfully!'
|
||||||
|
- tapOn: 'OK'
|
||||||
|
|
@ -4,3 +4,10 @@
|
||||||
flows:
|
flows:
|
||||||
- '*.yaml'
|
- '*.yaml'
|
||||||
- '!config.yaml'
|
- '!config.yaml'
|
||||||
|
|
||||||
|
# add-product must run first so add-slot-with-product can find the product.
|
||||||
|
executionOrder:
|
||||||
|
continueOnFailure: false
|
||||||
|
flowsOrder:
|
||||||
|
- add-product
|
||||||
|
- add-slot-with-product
|
||||||
|
|
|
||||||
47
tests/e2e/dev/add-empty-slot.yaml
Normal file
47
tests/e2e/dev/add-empty-slot.yaml
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
appId: ${APP_ID || "in.freshyo.adminui"}
|
||||||
|
env:
|
||||||
|
APP_ID: ${APP_ID || "in.freshyo.adminui"}
|
||||||
|
STAFF_NAME: ${STAFF_NAME || ""}
|
||||||
|
STAFF_PASSWORD: ${STAFF_PASSWORD || ""}
|
||||||
|
tags:
|
||||||
|
- dev
|
||||||
|
---
|
||||||
|
# Standalone flow: creates a slot (delivery +60m, freeze +50m) with NO products.
|
||||||
|
# Handy for validating the native date/time pickers in isolation.
|
||||||
|
#
|
||||||
|
# Run with:
|
||||||
|
# bash tests/e2e/run.sh dev/add-empty-slot.yaml
|
||||||
|
- launchApp
|
||||||
|
# Login only when the login screen is showing.
|
||||||
|
- runFlow:
|
||||||
|
when:
|
||||||
|
visible:
|
||||||
|
id: login-name-input
|
||||||
|
commands:
|
||||||
|
- runFlow: ../subflows/login.yaml
|
||||||
|
|
||||||
|
# Open the Slots list from the dashboard, then the create-slot screen.
|
||||||
|
- scrollUntilVisible:
|
||||||
|
element:
|
||||||
|
id: delivery-slots-menu-item
|
||||||
|
direction: DOWN
|
||||||
|
- tapOn:
|
||||||
|
id: delivery-slots-menu-item
|
||||||
|
- assertVisible:
|
||||||
|
id: add-slot-fab
|
||||||
|
- tapOn:
|
||||||
|
id: add-slot-fab
|
||||||
|
- assertVisible:
|
||||||
|
id: delivery-date-picker
|
||||||
|
|
||||||
|
- runFlow: ../subflows/set-slot-times.yaml
|
||||||
|
|
||||||
|
- scrollUntilVisible:
|
||||||
|
element:
|
||||||
|
id: create-slot-button
|
||||||
|
direction: DOWN
|
||||||
|
- tapOn:
|
||||||
|
id: create-slot-button
|
||||||
|
|
||||||
|
- assertVisible: 'Slot created successfully!'
|
||||||
|
- tapOn: 'OK'
|
||||||
|
|
@ -32,8 +32,8 @@ done < ./.env
|
||||||
: "${PRODUCT_NAME:?PRODUCT_NAME is required}"
|
: "${PRODUCT_NAME:?PRODUCT_NAME is required}"
|
||||||
: "${STORE_ID:?STORE_ID is required}"
|
: "${STORE_ID:?STORE_ID is required}"
|
||||||
|
|
||||||
# Unique product name so repeat runs don't trip the backend's duplicate check.
|
# PRODUCT_NAME is used verbatim (the slot flow searches for the exact name).
|
||||||
PRODUCT_NAME="${PRODUCT_NAME} $(date +%s)"
|
# The backend rejects duplicate product names, so change it between suite runs.
|
||||||
export PRODUCT_NAME
|
export PRODUCT_NAME
|
||||||
|
|
||||||
# Default to the whole suite when no path/tags are passed.
|
# Default to the whole suite when no path/tags are passed.
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@ env:
|
||||||
STAFF_NAME: ${STAFF_NAME || ""}
|
STAFF_NAME: ${STAFF_NAME || ""}
|
||||||
STAFF_PASSWORD: ${STAFF_PASSWORD || ""}
|
STAFF_PASSWORD: ${STAFF_PASSWORD || ""}
|
||||||
---
|
---
|
||||||
# Logs into the admin app. Reused by other flows via `runFlow: subflows/login.yaml`.
|
# Logs into the admin app. Callers invoke this conditionally, only when the
|
||||||
- assertVisible:
|
# login screen is showing (see the `when: visible id: login-name-input` wrapper
|
||||||
id: login-name-input
|
# used by the entry flows), so it can also be run standalone from a logged-out
|
||||||
|
# state.
|
||||||
- tapOn:
|
- tapOn:
|
||||||
id: login-name-input
|
id: login-name-input
|
||||||
- inputText: ${STAFF_NAME}
|
- inputText: ${STAFF_NAME}
|
||||||
|
|
@ -15,6 +16,6 @@ env:
|
||||||
- hideKeyboard
|
- hideKeyboard
|
||||||
- tapOn:
|
- tapOn:
|
||||||
id: login-button
|
id: login-button
|
||||||
# Dashboard quick actions are only rendered once the drawer shell is up.
|
# Dashboard quick actions render once the drawer shell is up.
|
||||||
- assertVisible:
|
- assertVisible:
|
||||||
id: add-product-menu-item
|
id: add-product-menu-item
|
||||||
|
|
|
||||||
54
tests/e2e/subflows/set-slot-times.yaml
Normal file
54
tests/e2e/subflows/set-slot-times.yaml
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
appId: ${APP_ID || "in.freshyo.adminui"}
|
||||||
|
---
|
||||||
|
# Sets the slot's delivery (+60 min) and freeze (+50 min) date/times using the
|
||||||
|
# native Android pickers. Assumes the create-slot screen is already open.
|
||||||
|
- evalScript: ${output.delivery = new Date(Date.now() + 60 * 60 * 1000)}
|
||||||
|
- evalScript: ${output.freeze = new Date(Date.now() + 50 * 60 * 1000)}
|
||||||
|
- evalScript: ${output.deliveryHour = ('0' + output.delivery.getHours()).slice(-2)}
|
||||||
|
- evalScript: ${output.deliveryMinute = ('0' + output.delivery.getMinutes()).slice(-2)}
|
||||||
|
- evalScript: ${output.freezeHour = ('0' + output.freeze.getHours()).slice(-2)}
|
||||||
|
- evalScript: ${output.freezeMinute = ('0' + output.freeze.getMinutes()).slice(-2)}
|
||||||
|
|
||||||
|
# --- Delivery: date (today) + time (+60) ---
|
||||||
|
- tapOn:
|
||||||
|
id: delivery-date-picker
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/button1'
|
||||||
|
|
||||||
|
- tapOn:
|
||||||
|
id: delivery-time-picker
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/toggle_mode'
|
||||||
|
optional: true
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/input_hour'
|
||||||
|
- eraseText
|
||||||
|
- inputText: ${output.deliveryHour}
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/input_minute'
|
||||||
|
- eraseText
|
||||||
|
- inputText: ${output.deliveryMinute}
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/button1'
|
||||||
|
|
||||||
|
# --- Freeze: date (today) + time (+50) ---
|
||||||
|
- tapOn:
|
||||||
|
id: freeze-date-picker
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/button1'
|
||||||
|
|
||||||
|
- tapOn:
|
||||||
|
id: freeze-time-picker
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/toggle_mode'
|
||||||
|
optional: true
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/input_hour'
|
||||||
|
- eraseText
|
||||||
|
- inputText: ${output.freezeHour}
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/input_minute'
|
||||||
|
- eraseText
|
||||||
|
- inputText: ${output.freezeMinute}
|
||||||
|
- tapOn:
|
||||||
|
id: 'android:id/button1'
|
||||||
Loading…
Add table
Reference in a new issue