aboutsummaryrefslogtreecommitdiff
path: root/tools/ui_flow.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ui_flow.py')
-rw-r--r--tools/ui_flow.py72
1 files changed, 67 insertions, 5 deletions
diff --git a/tools/ui_flow.py b/tools/ui_flow.py
index e54b530..edfc9a4 100644
--- a/tools/ui_flow.py
+++ b/tools/ui_flow.py
@@ -19,8 +19,13 @@ drawing each screen, so every step waits for the screen it expects instead
of sleeping. Menus are native Menu2 views that print nothing; for those the
script waits a fixed time.
-The flow covers: the results of an Aegis import sent through the settings
-form (the fixture sets the form, as the phone would), the list, a TOTP entry, a HOTP entry and its next code, the
+The flow covers: the results of an Aegis import and of the Add OTP, Add
+code and Manage entry forms, all sent through the settings (the fixture
+sets the forms, as the phone would), the two entries those forms added (a
+TOTP whose code the golden image shows, and a Code 128 card whose
+screenshot must decode), the Manage form's change to the locked Bank entry
+waiting for the PIN and confirmed from the menu (watches with buttons), the
+list, a TOTP entry, a HOTP entry and its next code, the
PIN screen, a wrong PIN, a correct PIN opening a locked entry, auto-lock
closing it, the menu, the About screen (watches with buttons; touch-only
menus have no focus to move), the lockout after 5 wrong PINs, and an EAN-13
@@ -49,6 +54,7 @@ import zxingcpp
EXIT_OK, EXIT_DIFFERENT, EXIT_FLOW = 0, 1, 2
SCREEN_TIMEOUT_S = 20.0
AUTO_LOCK_TIMEOUT_S = 25.0 # the UI-test build locks after 10 s without input
+AUTO_LOCK_IDLE_S = 13.0 # idle time after which that lock has surely happened
IMPORT_TIMEOUT_S = 90.0 # the 100-entry fixture import runs on a timer after start-up
IMPORT_MEMORY_BUDGET = 0.70 # README 18: peak memory at most 70 % of the watch-app memory
MENU_SETTLE_S = 1.5 # Menu2 has no "shown" line
@@ -66,6 +72,9 @@ MEMBER_QR = ( # source/app/Fixtures.mc: a version 6 QR
PARCEL_DM = "PARCEL-FAKE-0042-7731" # source/app/Fixtures.mc: Data Matrix
TICKET_PDF417 = "Boarding pass FAKE 0042 seat 12A" # source/app/Fixtures.mc: PDF417
RAIL_AZTEC = "RAIL-FAKE-0042 Zone 1-3" # source/app/Fixtures.mc: Aztec
+LOCKER_CODE128 = "FAKE-0042" # source/app/Fixtures.mc: the Add code form's Code 128 card
+# The Add OTP form's TOTP ("Hello!" demo key) at TestMode.NOW is 309848, next
+# 489290 (RFC 6238 computed in Python); the golden image otp_form shows them.
QR_TIMEOUT_S = 30.0 # the QR is encoded in timer steps the first time
@@ -350,6 +359,30 @@ def flow_import(f: Flow) -> None:
f.expect("list")
+def flow_forms(f: Flow) -> None:
+ """The entries the Add code and Add OTP forms added end the list: the
+ list wraps, so UP from the first row reaches them."""
+ f.prev() # the Code 128 card (added last)
+ f.act()
+ f.open_focused_row()
+ f.expect("code")
+ f.shot("code_form", expect_code=LOCKER_CODE128)
+ f.act()
+ f.back()
+ f.expect("list")
+ f.prev() # the TOTP from Add OTP
+ f.act()
+ f.open_focused_row()
+ f.expect("otp")
+ f.shot("otp_form")
+ f.act()
+ f.back()
+ f.expect("list")
+ f.next()
+ f.next() # back to the first row (GitHub)
+ time.sleep(SETTLE_S)
+
+
def flow_entries(f: Flow) -> None:
"""The list, a TOTP entry, a HOTP entry and its next code."""
f.shot("list")
@@ -403,9 +436,10 @@ def flow_menu(f: Flow) -> None:
f.shot("menu")
f.act()
if f.sim.has("down"):
- # Locked with a PIN: Change PIN, Reset PIN, Settings results, Entry
- # IDs, Clock status, About.
- for _ in range(5):
+ # Locked with a PIN and a phone change waiting: Phone changes,
+ # Change PIN, Reset PIN, Settings results, Entry IDs, Clock status,
+ # About.
+ for _ in range(6):
f.next()
time.sleep(MENU_SETTLE_S)
f.act()
@@ -419,6 +453,32 @@ def flow_menu(f: Flow) -> None:
f.expect("list")
+def flow_queue(f: Flow) -> None:
+ """The Manage form's edit of the locked Bank entry waits for the PIN:
+ menu, Phone changes, Confirm all, PIN, results. Touch-only
+ menus have no focus to select with, so those watches skip it."""
+ if not f.sim.has("down"):
+ return
+ f.menu()
+ time.sleep(MENU_SETTLE_S)
+ f.select() # Phone changes (the first item while one waits)
+ time.sleep(MENU_SETTLE_S)
+ f.shot("queue")
+ f.act()
+ f.select() # Confirm all
+ f.expect("pin")
+ f.opened_pin_screen()
+ f.act()
+ f.enter_pin(FIXTURE_PIN)
+ f.expect("results")
+ f.shot("queue_results")
+ f.act()
+ f.back()
+ f.expect("list")
+ # The PIN unlocked the session; the lockout flow needs it locked again.
+ time.sleep(AUTO_LOCK_IDLE_S)
+
+
def flow_lockout(f: Flow) -> None:
"""Five wrong PINs start the 30 s wait."""
f.act()
@@ -471,9 +531,11 @@ def flow_code(f: Flow) -> None:
def run_flow(f: Flow) -> None:
"""The scripted session; see the module docstring."""
flow_import(f)
+ flow_forms(f)
flow_entries(f)
flow_locked_entry(f)
flow_menu(f)
+ flow_queue(f)
flow_lockout(f)
flow_code(f)