When a case enters a journey through a deep link that skips earlier screens, what must it arrange first?
answer
- A deep link skips work, not requirements
- Arrange what the earlier screens would have done
- Build the link from seeded data
- Not-running entry differs from already-open entry
- Assert the back path from a deep entry
basics
~20 sEverything the skipped screens would have produced: a signed-in user established programmatically, a target record seeded for this run, any first-run or consent flags those screens write, and a link built from that seeded record.
solid answer
~50 sA deep link is an entry point, not a shortcut: it drops someone onto a screen deep in a journey while doing none of the work the earlier screens did. The case has to do that work explicitly - establish the signed-in user session by a programmatic path, seed the record the destination renders, and set any onboarding or consent flags an earlier step would have written. Build the link from the seeded record's generated identifier, because a fixed identifier rots as data changes and turns the case into a false alarm. Exercise both entries: with the app not running at all, and with it already open on another screen, since those are different code paths. Then assert the destination is genuinely usable - the right record, a working primary action, and a sensible back path.
code
pseudocode · 14 linescase "shared item opens straight to its detail screen, app not running":
user = seed_user(); establish_signed_in_session(user)
set_first_run_flags(onboarding_done = true, terms_accepted = true)
item = seed_item(owner = user, title = "winter jacket")
link = build_link(path = "/item/" + item.id) # identifier generated this run
ensure_app_not_running()
open_link(link)
wait_until(screen_settled)
assert rendered_title() == item.title
assert primary_action_enabled() == true
assert back_action() lands_on "item list"go deeper
Know that a deep link opens a screen directly without running the screens before it, so anything those screens would have created must already exist. Recall that the case itself has to arrange that setup.
Explain the arrangement in detail: a signed-in user established programmatically, a record seeded for this run whose generated identifier goes into the link, and first-run flags set. Explain why an entry with the app not running differs from one with it already open.
Show judgement about the destination's contract - what backing out does, what happens when nobody is signed in, what happens when the target no longer exists - and about keeping such cases from rotting as the data around them changes.
Own how far deep-link entry may bypass the product's own setup, and what that implies for both the app's design and the suite's shape. Decide when the shortcut is a legitimate seam and when it is quietly leaving the skipped screens uncovered.
## A deep link skips work, not requirements A deep link opens a screen from the middle of a journey. Nothing that the earlier screens would have done has been done: no sign-in, no selection of the record now on display, no acceptance of terms, no first-run setup, no warmed cache. The destination still needs all of it to be true, so the case has to make it true by other means. That inversion is the whole subject. In an ordinary case, the arrangement is a few steps and the assertion is the interesting part. In a deep-linked case, the **arrangement is most of the case**, and getting it wrong produces failures that look like product defects and are not. ## What the journey normally does, and what the case must do instead | What the skipped screens would have done | What the deep-linked case must do instead | | --- | --- | | Signed the person in through the sign-in screens | Establish the signed-in user session by a programmatic path before the link is opened | | Created or selected the record the destination renders | Seed that record for this run and put its generated identifier into the link | | Written first-run, onboarding or consent flags | Set those flags directly, or accept that the destination will be interrupted by them | | Warmed an in-memory cache the destination reads | Assume nothing is warm and assert the destination fetches what it needs | | Built a back path out of the screens actually visited | Define what backing out should do from a deep entry, and assert that | The identifier in the link deserves particular attention. Writing a fixed identifier into the case is the single most common way these cases rot: the record is deleted, renamed or reset, and the case starts failing for a reason unrelated to the behaviour under test. Teams then learn to ignore the failure, which costs more than the case ever gave. Generate the record in the arrangement, read its identifier back, and build the link from it. ## Cold entry and warm entry are different code paths Opening the link with the app not running at all is not the same as opening it while the app is already on another screen. The first builds everything from nothing. The second has to interrupt whatever is on screen, decide what happens to unsaved work there, place the destination sensibly in the back path, and reuse a signed-in session that already exists. Products routinely get one right and the other wrong, so a case that only ever exercises one entry reports coverage it does not have. Both belong in the suite, and each should say in its name which entry it uses. ## What the destination must prove Landing on the screen is not the assertion. The case should establish: 1. **The right thing is shown** - the seeded record, matched by a value the arrangement chose, not by the screen merely being non-empty. 2. **The screen is genuinely usable** - the primary action works from this entry, not only when the screen is reached the long way. 3. **The back path is sensible** - backing out lands somewhere coherent rather than dropping the person out of the app mid-task. 4. **Nothing was assumed warm** - data the earlier screens would have loaded is fetched here, and its absence is handled rather than rendered as blanks. ## Links that arrive in the wrong conditions The interesting branches are the ones where the link's assumptions do not hold, and they are cheap to add once the arrangement exists: - **Nobody is signed in.** The product should route to sign-in and then continue to the linked destination. The defect worth catching is the intent being dropped after authentication, and it is invisible to a case that stops asserting once the sign-in screen appears. - **The target no longer exists.** A deleted or expired record should produce a clear explanation and a route onwards, not an empty screen or a silent bounce to the default one. - **The link is opened twice.** The second entry should not stack a duplicate destination behind the first. A last caution about using deep links inside other cases. They are a legitimate way to skip setup and they make suites much faster, but every case that enters that way is a case that no longer covers the screens it skipped. That is a reasonable trade when something else covers them, and a silent hole when nothing does - so the decision belongs in the suite's design, recorded, rather than made case-by-case by whoever was in a hurry.
- What should the case assert when the deep link is opened while nobody is signed in?That the product routes to sign-in and then continues on to the linked destination, rather than dropping the person at the default screen. Assert the destination's content after sign-in completes, not merely that a sign-in screen appeared. Losing the original intent after authentication is the common defect here, and it is completely invisible to a case that stops at the sign-in screen.
- Why exercise the link with the app already open as well as with it not running?They are different entries. One builds everything from nothing; the other has to interrupt what is on screen, decide what happens to unsaved work there, place the destination sensibly in the back path, and reuse a session that already exists. Products routinely get one right and the other wrong, so a case covering only one reports coverage the suite does not actually have.
- What goes wrong when the record identifier in the link is fixed in the case?It rots. The record is deleted, renamed or reset between runs, and the case fails for a reason unrelated to the behaviour under test, which trains everyone to ignore it. Seeding the record in the arrangement and reading its identifier back keeps every failure meaningful, and it removes a shared dependency other cases can silently break.
Handing someone the middle chapter of a book: they can read it, but only if everything the earlier chapters established is already true.
saying these in an interview costs you the question
- Writes a fixed record identifier into the link
- Assumes the deep link signs the person in
- Only exercises the entry with the app already open
- Stops asserting once the sign-in screen appears
- Never checks where the back action leads
- Treats a deep link purely as a faster way to set up