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.
100 lines
8.0 KiB
Plaintext
100 lines
8.0 KiB
Plaintext
/* ── the faces no walk had seen ─────────────────────────────────────
|
|
Round thirty-one gave six screens an honest failure and its own
|
|
verifier was straight about what it had shipped unobserved: Home's
|
|
`catalogDown`, the lyrics `failed` note, Gaps' `gapErr`, Playlist's
|
|
`loadErr`, the catalog record's and the artist page's stubs, and
|
|
`failed · <sentence>` on a transfer row. It could drive none of them
|
|
because neither `loadHome` nor `loadLyrics` was reachable from the
|
|
`__ss` handle — both are gated on `started` / `key` and answer a
|
|
second ask with nothing at all, so no amount of tapping re-runs
|
|
them. The handle carries the two stores and their two loaders now,
|
|
and this block is what they were added for.
|
|
|
|
It sits HERE, before the first run, and not at the end of the list:
|
|
the block below reloads the page twice, and the mock's follows live
|
|
in a module-level `let` that a reload empties — after `fresh-off`
|
|
nobody is followed, and Home's `catalogDown` (which needs a follow)
|
|
and the Gaps shelf (which IS the follows) are both structurally
|
|
unreachable. Here the block inherits what the weather left behind:
|
|
signed in, on Home, Daft Punk followed, a track on the mini bar.
|
|
|
|
Every assertion is on settled state — an armed failure stays armed,
|
|
an error stub stays up, the toast stays until it is dismissed — and
|
|
the two forced loads return their promise, which `cdp.evaluate`
|
|
awaits, so the fetch is over before the step's wait even begins.
|
|
Every failure is disarmed by the step that proves the face heals,
|
|
and `faces-clear` is the proof that nothing was left armed. */
|
|
{ do: `(function () { __ssMock.clear(); __ss.player.error = ''; __ss.lib.error = ''; __ss.player.retry = null; return __settle(); })()`, wait: 800 },
|
|
/* Home with every follow's catalog page refused. `home.svelte.js` has
|
|
always set `slot.error` there; until round thirty-one nothing read
|
|
it, and until this step nothing had ever seen the line that does. */
|
|
{ do: `(function () { __ssMock.fail('catalog_artist', 'io: failed to lookup address information: no address associated with hostname'); return __ss.loadHome(true); })()`, name: "faces-home-down", wait: 1200 },
|
|
/* the same armed failure, on the other screen that asks the same
|
|
command: Gaps. Home stays poisoned through these three steps on
|
|
purpose — it is asserted above, and the second tap below is what
|
|
clears the weather for both. */
|
|
{ do: `document.querySelectorAll('.nav button')[2].click()`, wait: 800 },
|
|
{ do: `__click('.segtabs button', 'Gaps')`, wait: 700 },
|
|
{ do: `__click('.gapline', null)`, name: "faces-gap-down", wait: 1400 },
|
|
/* a failed lookup leaves `gapRows[key]` undefined, so the second tap
|
|
genuinely asks again rather than merely opening a rail */
|
|
{ do: `__ssMock.fail('catalog_artist', '')`, wait: 300 },
|
|
{ do: `__click('.gapline', null)`, name: "faces-gap-again", wait: 1600 },
|
|
/* a catalog record. The walk has already made 302127 `ready` and
|
|
`lookupAlbum` returns early on anything but an error, so the entry is
|
|
forgotten first — the smallest honest way to say "ask again". */
|
|
{ do: `(function () { delete __ss.catalog.albums[302127]; return __ssMock.fail('catalog_album', 'io: connection reset by peer'); })()`, wait: 300 },
|
|
{ do: `__ss.push('catalogAlbum', { id: 302127, artist: 'Daft Punk', title: 'Discovery' })`, name: "faces-album-down", wait: 1500 },
|
|
{ do: `__ssMock.fail('catalog_album', '')`, wait: 300 },
|
|
{ do: `__click('.imp-foot .btn', 'Try again')`, name: "faces-album-again", wait: 1600 },
|
|
{ do: `__ss.back()`, wait: 700 },
|
|
/* the artist page has TWO of these and they say different things: a
|
|
lookup that FAILED is "didn't answer", one that came back empty is
|
|
"had nothing to add". `bestArtistFor` is what has to fail for the
|
|
first — failing `catalog_artist` alone never reaches the page at all
|
|
and leaves the status at none, which is the other copy. */
|
|
{ do: `__ssMock.fail('catalog_search', 'io: failed to lookup address information: no address associated with hostname')`, wait: 250 },
|
|
{ do: `__ss.push('artist', { name: 'Hollow Signal' })`, name: "faces-artist-down", wait: 1600 },
|
|
{ do: `(function () { __ssMock.fail('catalog_search', ''); __ss.back(); return true; })()`, wait: 700 },
|
|
{ do: `__ss.push('artist', { name: 'Hollow Signal' })`, name: "faces-artist-none", wait: 1600 },
|
|
{ do: `__ss.back()`, wait: 700 },
|
|
/* a playlist that will not read. Id 1 survives the whole walk — it is
|
|
the one renamed to "Late night drive II"; the one deleted was New
|
|
Playlist. Try again clears `loadErr` and bumps `again`, which is
|
|
what re-arms the effect. */
|
|
{ do: `__ssMock.fail('playlist_items', 'unable to open database file')`, wait: 250 },
|
|
{ do: `__ss.push('playlist', { id: 1 })`, name: "faces-playlist-down", wait: 1400 },
|
|
{ do: `__ssMock.fail('playlist_items', '')`, wait: 300 },
|
|
{ do: `__click('.imp-foot .btn', 'Try again')`, name: "faces-playlist-again", wait: 1400 },
|
|
{ do: `__ss.back()`, wait: 700 },
|
|
/* the lyrics face. Sheet.svelte asks with the UN-forced `loadLyrics()`,
|
|
which returns at once while `lyr.key` is already this track's — so
|
|
the face alone can never ask again, which is exactly why round
|
|
thirty-one could not drive this one. The loader, forced. */
|
|
{ do: `(function () { __ss.openSheet(); return true; })()`, wait: 900 },
|
|
{ do: `document.querySelectorAll('.fbtn')[1].click()`, wait: 900 },
|
|
{ do: `(function () { __ssMock.fail('lyrics_get', 'io: failed to lookup address information: no address associated with hostname'); return __ss.loadLyrics(true); })()`, name: "faces-lyrics-down", wait: 1200 },
|
|
{ do: `(function () { __ssMock.fail('lyrics_get', ''); return true; })()`, wait: 250 },
|
|
{ do: `__ss.loadLyrics(true)`, name: "faces-lyrics-again", wait: 1200 },
|
|
{ do: `(function () { document.querySelectorAll('.fbtn')[0].click(); __ss.closeSheet(); return true; })()`, wait: 700 },
|
|
/* a transfer that was refused, written straight into the store the way
|
|
the shade steps above do — nothing is fetched, and `failed` is in
|
|
DONE, so `xfernote.shape()` sees nothing in flight and posts no
|
|
notice. The id is far above the backend's own counter, and `list()`
|
|
sorts id-descending, so this row is the first one on the screen. */
|
|
{ do: `(function () { __ss.transfers.items[990011] = { id: 990011, username: 'walk_peer', path: 'Walk\\\\walk-c.flac', name: 'walk-c.flac', state: 'failed', queue_place: null, local_path: null, error: 'transfer rejected: File not shared.', received: 0, total: 0 }; __ss.push('transfers', {}); return true; })()`, name: "faces-xfer-failed", wait: 1300 },
|
|
{ do: `(function () { delete __ss.transfers.items[990011]; __ss.back(); return true; })()`, wait: 800 },
|
|
/* the one toast action round thirty-one armed that no step had ever
|
|
pressed. `lib.error` is written by `loadLibrary` alone —
|
|
`watchLibrary`'s own reload swallows its failure — so You → Rescan
|
|
library is the only door in the app that reaches it twice. */
|
|
{ do: `document.querySelectorAll('.nav button')[4].click()`, wait: 800 },
|
|
{ do: `__ssMock.fail('library_albums', 'unable to open database file')`, wait: 250 },
|
|
{ do: `__click('.screen .row', 'Rescan library')`, name: "faces-library-toast", wait: 1500 },
|
|
{ do: `__ssMock.fail('library_albums', '')`, wait: 300 },
|
|
{ do: `__click('.toast:not(.notice) .na', 'Try again')`, name: "faces-library-again", wait: 1400 },
|
|
/* and all of it put away, so the first run below starts exactly where
|
|
it would have started without this block at all */
|
|
{ do: `(function () { __ssMock.clear(); __ss.player.error = ''; __ss.lib.error = ''; __ss.player.retry = null; __settle(); return __ss.loadHome(true); })()`, wait: 900 },
|
|
{ name: "faces-clear", wait: 1200 },
|