Happy path
Staff sets up the iPad.
Sign into the native app with staff credentials. Open Settings → Kiosk Mode. Set kiosk passcode (6-digit, separate from staff password). Tap "Enter Kiosk Mode" → app guides staff to enable iOS Guided Access (iOS native). Once Guided Access locks the app, attendee-facing UI activates.
Attendee approaches.
Big "Welcome — please scan your QR or enter your email" screen. Camera viewfinder + email input + numeric keypad alternative. No menu, no other tabs. Volume + sleep buttons disabled (Guided Access).
Attendee scans/enters → confirmation.
"Welcome, [name]! You're checked in." Auto-dismisses after 5s, returns to welcome screen for the next attendee. Optional: print badge (depends on EF-067 substrate).
Staff exits kiosk.
Tap-corner-3-times reveals exit prompt. Enter kiosk passcode → exit Guided Access (iOS native triple-press home/power). Returns to staff-mode UI.
Failure modes
Kiosk passcode too short or weak
Trigger: staff enters "1234" or "111111".
Server-side validation: 6 digits, no all-same, no sequential (123456 / 654321). Common-passcode blacklist enforced. Harness: stub weak passcodes, save returns 422, list of rejected patterns.
Attendee tries to navigate away
Trigger: attendee taps URL bar, swipes from edge, presses home button.
Guided Access blocks all navigation. App stays on welcome screen. Harness: physical-device test — gesture attempts don't escape the app.
iPad rotation lock
Trigger: kiosk is mounted in landscape; rotation should be locked.
App enforces orientation lock based on staff's setup choice (portrait or landscape). Rotating the device doesn't reflow. Harness: orientation lock honored.
Email-not-found generic message
Trigger: attendee types an email not on the roster.
"We can't find that email — please see staff." Anti-probing — no leak about what the email's status is (could be unregistered, revoked, cross-event). Same UI for all rejection reasons. Harness: stub email-not-found, generic message visible.
Attendee privacy — no name display before identity confirmed
Trigger: half-typed email autocomplete from prior attendee remains visible.
Each interaction starts with a clean slate — no autocomplete, no autofill, no prior-input visible. iOS Guided Access doesn't leak across sessions. Harness: quick succession of two attendees, second sees no remnant of first.
Camera permission revoked while in kiosk mode
Trigger: parent control or admin restriction toggles camera off mid-event.
App detects, falls back to email-only entry, surfaces a banner "Camera unavailable — please use email entry below." Doesn't crash. Staff can exit kiosk to fix. Harness: revoke camera while kiosked, banner visible, email entry still works.
Network drops during kiosk
Trigger: kiosk-mode iPad goes offline.
Inherits native-app-shell offline contract. Local roster + queue continue working. Confirmation message stays the same — attendee unaware. Sync banner not displayed (kiosk UI is attendee-facing; staff sees it on exit). Harness: offline + check-in attendee, queues locally + confirms.
Already-checked-in attendee at kiosk
Trigger: attendee scans their QR but already checked in earlier.
"You're already checked in. Have a great event!" — friendly tone, no "error" framing. Auto-dismisses. Audit log row: kiosk_already_checked_in for monitoring (lots of these may indicate confused attendees). Harness: stub already-checked-in, friendly message, audit row.
Kiosk exit attempts without passcode
Trigger: someone (attendee, child, security) taps the corner 3 times to attempt exit.
Exit prompt appears. Wrong passcode 3x → 60s lockout. Lockout extends (60s, 300s, 600s) on repeated failure. Harness: 3 wrong attempts, 60s lockout banner.
iPad battery low during event
Trigger: iPad battery drops below 20%.
Subtle staff-only banner appears in the welcome screen footer (visible enough for staff during a sweep, not big enough to alarm attendees). Below 10%, larger warning. Harness: stub battery 15%, subtle banner; stub 5%, larger warning.
App crash recovery
Trigger: app crashes (rare, but possible due to memory pressure).
iOS Guided Access remains active across app relaunch (standard iOS behavior). On relaunch, app detects kiosk-mode flag set and resumes welcome screen automatically without staff intervention. Harness: simulate crash, app relaunches into welcome screen.
Stable test attributes
kiosk-setup-passcode-input | Settings → Kiosk Mode | 6-digit passcode entry |
kiosk-setup-orientation-lock | Settings → Kiosk Mode | Portrait/landscape choice |
kiosk-enter-cta | Settings → Kiosk Mode | Triggers Guided Access prompt |
kiosk-welcome-screen | Attendee surface | Big "Please scan or enter email" |
kiosk-camera | Welcome | Always-on camera viewfinder |
kiosk-email-input | Welcome | Numeric keypad alternative |
kiosk-confirmation | Post-check-in | "Welcome, [name]" |
kiosk-already-checked-in-message | If pre-checked | Friendly tone |
kiosk-email-not-found-message | If not on roster | "Please see staff" (anti-probing) |
kiosk-camera-fallback-banner | If camera revoked | "Use email entry below" |
kiosk-exit-prompt | 3-tap corner | Passcode entry |
kiosk-exit-lockout-banner | After 3 wrong tries | 60s+ lockout |
kiosk-battery-low-banner | Below 20% battery | Subtle staff-visible |
kiosk-battery-critical-banner | Below 10% battery | Larger warning |
Agent test plan
Probe list
- weak-passcode-rejected: stub "1234"/"111111", save 422
- (manual) navigate-away-blocked: physical iPad, gesture/swipe, blocked
- (manual) orientation-locked: physical iPad rotation, no reflow
- email-not-found-generic: stub not-on-roster, generic message visible
- (manual) no-autofill-leak: physical 2-attendee succession, second clean
- camera-revoked-fallback-works: stub revoke, banner + email-entry works
- offline-confirms-locally: device offline, queues + confirms
- already-checked-in-friendly: stub pre-checked, friendly message + audit row
- exit-passcode-required: 3-tap corner, prompt visible, wrong passcode locks out
- (manual) battery-banners-thresholds: physical 15% subtle, 5% larger
- (manual) crash-recovery-resumes-kiosk: simulate crash, relaunches into welcome
- audit-log-kiosk-events: per-check-in audit row tagged kiosk-mode