A disconnected screen still renders records loaded earlier - how does a case tell stale-but-allowed from simply wrong?
answer
- Decide the expectation before you disconnect
- Record the values the device already holds
- Compare against that record, not the server
- Stale shown as current is a defect
- Missing promised content is wrong, not stale
basics
~20 sCapture the values the device holds before disconnecting; that snapshot is the oracle. Stale-but-allowed means the screen matches it and says it is not current. Wrong means values never held, missing promised content, or stale data shown as live.
solid answer
~40 sMake the case own the baseline. Sign in with the link up, let synchronisation settle, and record the exact values the device now holds - that recording is the oracle. Then disconnect, change the same records on the far side through a service interface, and open the screen again. A pass is the screen showing the recorded values, not the newer ones, together with whatever freshness cue the design promises: a last-updated timestamp, a banner, a distinct treatment. A fail is anything the device never held, an empty screen where retention was promised, or the same rendering used for live data. Never assert against the current far-side values - the two are meant to differ, and comparing them turns every correct stale read into a red result.
code
pseudocode · 20 linescase "disconnected screen serves the last synced values":
seed_orders([{id: "o-1", status: "PACKING"},
{id: "o-2", status: "PACKING"}])
sign_in()
await(until: sync_idle, deadline: 30s)
snapshot = ui.read_rows("orders")
assert snapshot.size == 2
link.disable()
service.patch_order("o-1", status: "SHIPPED") # far side moves on
ui.navigate_away()
ui.open("orders")
assert ui.read_rows("orders") == snapshot # stale, by design
assert ui.freshness_label() == "updated " + snapshot.captured_at
assert ui.offline_notice_shown() == true
link.enable()
await(until: ui.row("o-1").status == "SHIPPED", deadline: 60s)
assert ui.offline_notice_shown() == falsego deeper
Be ready to explain that a screen with no connection is expected to show what the device already had, and that the case needs a recorded copy of those values before the link is taken away.
Explain why the captured snapshot is the comparison target and the current far-side values are the wrong one, and how the freshness cue turns an ambiguous rendering into a checkable expectation.
Show judgement about which reads the product genuinely promises with no connection, how you keep the baseline stable between runs, and how you stop the case passing because both sides happened to be empty.
Own the promise itself: which reads may be served from the device with no connection, how old is too old to serve, and how the interface must say so - the cases can only assert a promise someone has made.
A screen that renders with no connection is doing one of two very different things: serving data the device legitimately holds, or inventing something. Telling those apart is the entire job of the case, and it cannot be done by comparing the screen with the far side - because on a disconnected client, the screen and the far side are *supposed* to disagree. Compare them and every correct stale read turns red, the team stops believing the case, and it gets deleted or slackened until it catches nothing. ## The oracle is the captured snapshot Before the link is taken away, drive the device into a known state: sign in, let synchronisation settle, and record the exact values the device now holds. That recording is the oracle for everything that follows. Depending on the product it may be the rows read off the screen, a projection the case can query, or the payload the device was last served. What matters is that it is captured while the link was up and kept inside the case. Only then disconnect, and only after disconnecting change the same records on the far side through a service interface. You have now manufactured, on purpose, the situation the retained-read behaviour exists to handle: the device is behind and has no way of knowing it. ## Five renderings, five verdicts | What the disconnected screen shows | Verdict | Why | | --- | --- | --- | | The captured snapshot, marked as not current | Pass | Exactly the retained-read promise | | The captured snapshot, rendered as if live | Fail | The user is told something false | | Values only the far side could know | Fail | Impossible; investigate the harness first | | Nothing, where retention was promised | Fail | The promise was not kept | | A defined empty state, where nothing was promised | Pass | Honest about what it does not hold | Rows four and five are the same rendering with opposite verdicts, which is why the expectation has to be settled before the case is written. Blank is a defect only against a promise; with no promise on record the case has no ground to stand on. Getting that promise written down is often the most valuable half-hour of the work, and it is a conversation, not a test-design decision you can make alone. ## The freshness cue is part of the pass, not decoration Stale data presented as current is worse than no data, because the user acts on it. So the assertion is not only *what* is rendered but *how it is labelled*: a timestamp of the last successful update, a banner, a distinct treatment with an accessible label - whatever the design chose. Two failure shapes are worth naming explicitly: - **The cue never appears.** The user believes a figure that is hours old. Nothing crashes, no error is logged, and only an assertion on the cue catches it. - **The cue never clears.** Once the link returns and fresh data arrives, a lingering warning teaches users to distrust data that is now correct. Assert the return path as well as the outage. ## Writing it so it stays green for the right reason 1. **Seed the records through a service interface** with values the case chose, so the snapshot contains recognisable strings rather than whatever the shared account happened to hold. 2. **Assert the snapshot is non-empty** before disconnecting. A case where both sides are empty passes for no reason at all, and this is the single most common way this case rots. 3. **Force a real read, not a redraw.** Navigate away and back, or reopen the application, so the screen genuinely resolves data with no connection rather than showing what was already in memory. 4. **Assert the exact fields you seeded**, not a row count. A count matches while every value is wrong. 5. **Restore the link and assert convergence** - the newer values appear and the cue clears - so the case covers the recovery as well as the outage. ## What this case does not own How much is retained, in what order it is discarded when space runs short, and when the device decides its copy is too old to serve are design questions with their own home. This case does not choose a retention policy; it takes the stated one and asks three things of the product: are the reads the design promised actually served with no connection, are they labelled honestly while they are old, and do they give way to fresh data once the link returns. Those three hold their value even if the storage layer underneath is replaced entirely, which is what makes them worth automating on a handheld where the outage is a normal condition rather than an incident.
- The screen is blank when the device has no connection. Is that a defect?Only the stated expectation decides. If the product promises previously loaded records stay readable with no connection, a blank screen breaks that promise and the case should fail. If the data was never meant to be retained, the correct expectation is a clear empty state that explains why, and the case asserts that instead. Settle it in writing before automating it.
- Why not simply compare the disconnected screen against the current far-side response?Because the two are supposed to differ. The device shows what it last received; the far side has moved on. Comparing them turns a correct stale read into a red result and trains the team to ignore the case. The stable oracle is the snapshot captured while the link was up, plus the freshness cue the design promises.
A printed timetable in your pocket is useful and honest as long as it carries its print date; the same paper with no date, presented as today's, is misinformation.
saying these in an interview costs you the question
- Compares the disconnected screen against current far-side data
- Treats any old value on screen as a defect
- Checks the values but ignores the freshness cue
- Captures no baseline before taking the link away
- Accepts a blank screen without checking the promise
- Passes while the captured snapshot was empty