Everything written this session that has not been through the device: rounds 43 to 48 (each patch adversarially verified, 43's transient-notice expectation fixed), a partial round 49, the pipeline scripts, the Android Auto design and the icon comparison mock. Also the two harness changes that were never A/B'd — adaptive waits, which may only shorten a declared wait and never lengthen it, and a ship that runs the mock walk and the deploy at the same time. The A/B and its 255-step baseline are in handoff/tools; main stays at what the phone has actually walked.
57 lines
4.8 KiB
Plaintext
57 lines
4.8 KiB
Plaintext
/* ── the weather ────────────────────────────────────────────────────
|
|
Everything above this line is the happy path; nothing in thirty
|
|
rounds of walk had ever made a command reject or taken the client
|
|
offline, so none of these lines had ever been drawn. The mock's own
|
|
doors (__ssMock.fail / answer / offline / clear) are the weather, and
|
|
every assertion below is on SETTLED state — an armed failure stays
|
|
armed, a sign-in card stays up, the folder-gone row stays — because
|
|
the probe lands after the screenshot, well past the step's own wait.
|
|
The one timed assertion is the room list, and its timeout is shortened
|
|
to 1.2 s against the 3.1 s of waits between arming it and reading it.
|
|
The last step puts the weather away and
|
|
leaves the app exactly as it found it — anything appended after this
|
|
block inherits a signed-in app on Home.
|
|
|
|
The first step settles FIRST, and it has to: the landscape block above
|
|
leaves the library tab three screens deep (record → artist), so one tap
|
|
on the Library tab lands on the artist page and `.segtabs button` would
|
|
be its discography tabs, not Albums/Artists/Tracks. It also wipes any
|
|
error the happy path left standing, so `!i.toast` below means this
|
|
block's toast and no other. */
|
|
{ do: `(function () { __ss.player.error = ''; __ss.lib.error = ''; __ss.player.retry = null; return __settle(); })()`, wait: 800 },
|
|
{ do: `__ssMock.fail('library_track_index', 'unable to open database file')`, wait: 300 },
|
|
{ do: `document.querySelectorAll('.nav button')[2].click()`, wait: 700 },
|
|
{ do: `document.querySelectorAll('.segtabs button')[2].click()`, name: "weather-tracks", wait: 1300 },
|
|
{ do: `__ssMock.fail('library_track_index', '')`, wait: 200 },
|
|
{ do: `__click('.imp-foot .btn', 'Try again')`, name: "weather-tracks-ok", wait: 1300 },
|
|
/* signed out, in a lift: the card is back and nothing says why in Rust */
|
|
{ do: `__ssMock.offline(true)`, wait: 600 },
|
|
{ do: `document.querySelectorAll('.nav button')[3].click()`, name: "weather-signedout", wait: 1100 },
|
|
/* the single most visible raw-Rust site on the phone, twice over */
|
|
{ do: `__ssMock.fail('connect_and_login', 'login failed: INVALIDPASS')`, wait: 200 },
|
|
{ do: `(function () { var p = document.querySelectorAll('.signin .field')[1]; p.value = 'hunter2'; p.dispatchEvent(new Event('input', { bubbles: true })); return true; })()`, wait: 400 },
|
|
{ do: `__click('.signin .btn-fill', 'Sign in')`, name: "weather-badpass", wait: 1200 },
|
|
{ do: `__ssMock.fail('connect_and_login', 'could not reach server: io: failed to lookup address information: no address associated with hostname')`, wait: 200 },
|
|
{ do: `__click('.signin .btn-fill', 'Sign in')`, name: "weather-noserver", wait: 1200 },
|
|
/* Search signed out with a query typed showed NOTHING where the network
|
|
section lives — no row, no reason. Now it says so and offers the door */
|
|
{ do: `document.querySelectorAll('.nav button')[1].click()`, wait: 700 },
|
|
{ do: `(function () { var i = document.querySelector('.sfield input'); i.value = 'daft punk'; i.dispatchEvent(new Event('input', { bubbles: true })); return true; })()`, name: "weather-search-out", wait: 1800 },
|
|
/* the room list is fire-and-forget over the wire (the client sends it and
|
|
nothing answers if the server will not), so the wait is ours: an armed
|
|
answer that resolves and emits nothing is exactly that server. Community
|
|
is left on Buddies by the walk above, so the Rooms tab is asked for by
|
|
name — the note lives under that one. */
|
|
{ do: `__ssMock.fail('connect_and_login', ''); __ssMock.offline(false)`, wait: 1200 },
|
|
{ do: `(function () { __ss.slsk.roomsWaitMs = 1200; __ss.slsk.rooms = []; __ssMock.answer('slsk_room_list', null); __ss.refreshRooms(); return true; })()`, wait: 200 },
|
|
{ do: `document.querySelectorAll('.nav button')[3].click()`, wait: 900 },
|
|
{ do: `__click('.segtabs button', 'Rooms')`, name: "weather-rooms-late", wait: 2200 },
|
|
/* one tap on Rescan library used to empty the whole index and say Ok */
|
|
{ do: `__ssMock.fail('rescan_library', 'library-folder-missing: /storage/1A2B-3C4D/Music')`, wait: 200 },
|
|
{ do: `document.querySelectorAll('.nav button')[4].click()`, wait: 800 },
|
|
{ do: `__click('.screen .row', 'Rescan library')`, name: "weather-rescan", wait: 1500 },
|
|
/* and the weather clears */
|
|
{ do: `(function () { __ss.slsk.roomsWaitMs = 12000; __ssMock.clear(); __ss.refreshRooms(); __ss.player.error = ''; __ss.lib.error = ''; __ss.player.retry = null; return true; })()`, wait: 900 },
|
|
{ do: `__settle()`, wait: 900 },
|
|
{ do: `document.querySelectorAll('.nav button')[0].click()`, name: "weather-clear", wait: 1000 },
|