From b8addc87f804789368612bf8e1be31a2bf28efe1 Mon Sep 17 00:00:00 2001 From: cirakg Date: Sun, 25 Oct 2026 23:51:52 +0100 Subject: test(ui): second UI scenario, and the fixes it found A second UI-test build (uitest-extra.jungle) covers the legacy PIN and the forced new PIN, Change and Reset PIN, a queued Require PIN, UPC-A, Code 39, the code error screen, the encoding progress, auto-lock on a barcode, the light theme and the glance without a code; the main flow adds the Steam and Library details and the menu's text screens. Fixed from what it found: Entry IDs tripped the watchdog with 110 entries; auto-lock didn't close a locked barcode; a queued Require PIN showed "Confirm in menu"; locked barcodes lacked the padlock; the PIN keypad's bottom row, the Reset PIN question, text-screen bottoms, the glance title and the light-theme warning colour. Goldens approved on all seven watches; only the Forerunner 70 was re-verified after the version bump. Co-Authored-By: Claude Opus 5.5 --- source/app/AppInfo.mc | 2 +- source/app/Fixtures.mc | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) (limited to 'source/app') diff --git a/source/app/AppInfo.mc b/source/app/AppInfo.mc index 163486c..1e6fe3c 100644 --- a/source/app/AppInfo.mc +++ b/source/app/AppInfo.mc @@ -12,5 +12,5 @@ import Toybox.Lang; module AppInfo { // Semantic version of the app: MAJOR.MINOR.PATCH. - const VERSION = "0.8.0"; + const VERSION = "0.9.0"; } diff --git a/source/app/Fixtures.mc b/source/app/Fixtures.mc index 01b15a8..08a51a1 100644 --- a/source/app/Fixtures.mc +++ b/source/app/Fixtures.mc @@ -12,6 +12,11 @@ // result, with the 4-digit PIN marker (KeyManager.PIN_LENGTH_KEY). // Unlocking it with the app's own code also cross-checks the wrap format // against the Python implementation (test/storage/PinTest.mc). +// +// The extra UI-test scenario (TestMode.SCENARIO_EXTRA, uitest-extra.jungle) +// loads loadExtra() instead: FIXTURE_LEGACY_WRAP, the same master key under +// the 6-digit PIN FIXTURE_LEGACY_PIN without the marker (a PIN from before +// the 4-digit rule), and the entries and forms its flow needs. import Toybox.Application; import Toybox.Lang; @@ -22,6 +27,8 @@ module Fixtures { const FIXTURE_PIN = "1234"; const FIXTURE_WRAP = "101112131415161718191a1b1c1d1e1f000007d001202122232425262728292a2b2c2d2e2f133549536635b7a7ae3add45a59c42953d4c666538390a99305164dba9c99961e7148e1c561b6cfc70cfde7f9e3e59179464ce65bf91dd08807ff8a52027d77c90c2b692ca22fe4cbd3fb20ffb440137"; // lint: allow-literal (fake fixture) const FIXTURE_MASTER_KEY = "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"; // lint: allow-literal (fake fixture) + const FIXTURE_LEGACY_PIN = "123456"; + const FIXTURE_LEGACY_WRAP = "101112131415161718191a1b1c1d1e1f000007d001202122232425262728292a2b2c2d2e2f857b961d4854e06740f602627bfb952efaac5383e800768221bf3a7b292ee881e2ce2f76b9dd744b2ac32322473df351929bc6dfcbfc2941527ae8b90614a8a6a6bd0f72d33161bafd16b1039caa670c"; // lint: allow-literal (fake fixture) // Erase all app storage (UI-test build only). function resetStore() as Void { @@ -32,6 +39,18 @@ module Fixtures { // so one entry can be locked; otherwise locked demo entries go to the // pending queue until a PIN exists. function load(vault as Vault) as Void { + var extra = TestMode.ON && TestMode.SCENARIO == TestMode.SCENARIO_EXTRA; + if (TestMode.ON) { + // The extra scenario's screens use the light theme, the main + // one's the dark theme. Properties outlive a launch in the + // simulator, so both set it. + Application.Properties.setValue("optTheme", extra ? Options.THEME_LIGHT : Options.THEME_DARK); + AppState.options.load(); + } + if (extra) { + loadExtra(vault); + return; + } if (TestMode.ON && !vault.hasPin()) { Application.Storage.setValue(KeyManager.WRAP_KEY, Bytes.fromHex(FIXTURE_WRAP)); Application.Storage.setValue(KeyManager.PIN_LENGTH_KEY, KeyManager.PIN_DIGITS); @@ -75,6 +94,43 @@ module Fixtures { } } + // The extra UI-test scenario (README 17.4; tools/ui_flow.py + // run_extra_flow): the legacy PIN, a locked TOTP, the symbologies the + // main fixture lacks (UPC-A, Code 39), an EAN-13 whose check digit is + // wrong (the code error screen) and a QR large enough that its encoding + // progress shows for a while. The Manage form asks for "Require PIN" on + // the UPC-A card while the watch is locked, so it waits for the next + // PIN; the glance option is off, so the glance shows the entry count. + // Its screens use the light theme (set in load()). + function loadExtra(vault as Vault) as Void { + Application.Storage.setValue(KeyManager.WRAP_KEY, Bytes.fromHex(FIXTURE_LEGACY_WRAP)); + vault.session.unlock(Bytes.fromHex(FIXTURE_MASTER_KEY)); + var rfcKey = "12345678901234567890"; // lint: allow-literal (RFC 4226 test key) + vault.add(otp("GitHub", "alice@example.com", "Work", Entry.OTP_TOTP, Hashes.SHA1, 6, 30, rfcKey, false)); + vault.add(otp("Bank", "carol", "Finance", Entry.OTP_TOTP, Hashes.SHA512, 6, 30, + "1234567890123456789012345678901234567890123456789012345678901234", true)); // lint: allow-literal (RFC 6238 test key) + vault.add(code("Shop card", Codes.UPCA, "036000291452")); // fake; a valid UPC-A check digit + vault.add(code("Badge", Codes.CODE39, "FAKE-39")); + vault.add(code("Broken card", Codes.EAN13, "5901234123458")); // the check digit should be 7 + // Fake text of 199 characters: a version 10 QR in byte mode, which + // still fits the smallest screen at 2 px per module. + var text = "Fake event ticket 0042 for the UI test."; + while (text.length() < 160) { + text += " Row 12, seat 34, gate b, valid all day."; + } + vault.add(code("Big QR", Codes.QR, text)); + vault.lock(); + Application.Properties.setValue("optGlanceCode", false); + vault.glanceCode = false; + Application.Properties.setValue("impApply", false); + Application.Properties.setValue("otpAdd", false); + Application.Properties.setValue("codeAdd", false); + var ids = vault.ids(); + Application.Properties.setValue("mgId", ids[2]); // Shop card + Application.Properties.setValue("mgAction", ManageAction.LOCK); + Application.Properties.setValue("mgApply", true); + } + // UI-test build: the glance option, and the other forms, filled in as // the phone would (README 16, M7 end-to-end): Add OTP (a TOTP whose code the screenshot shows), // Add code (a Code 128 card whose screenshot must decode) and Manage -- cgit v1.2.3