Skip to content
Ryno

Run a flow

Chain requests into a scenario, answer as you go, and read the report it leaves behind.

One link answers one question. Signing off a release does not: someone has to walk a dozen links in order, decide after each one whether the app did the right thing, and leave behind something a developer can act on the next morning. That is what a flow is for, and this page follows one from an empty file to a report you can reopen a week later.

Switch to flows

Flows are the second of the three modes in the rail down the left of the window. Pick it there, or press 2. Your project stays open and your device stays selected on the way in; only the panel changes.

New flow in the sidebar header asks for a name and writes one file under .ryno/flows, next to your collections and versioned with them. The sidebar then lists every flow with how its last run went, or not run yet for one nobody has launched.

Under the title sits a description. Write what the scenario is meant to verify: it is stored in the flow file, so it is the first thing a colleague reads when they inherit the flow six months from now.

Add the steps

Three buttons, three ways in:

  • Add request… picks one request out of your collections.
  • Add collection… pulls in a whole folder at once, in its own order.
  • Custom step writes a link straight into the flow, with no request behind it. Useful for the one-off nobody wants to keep.

The order of the list is the run order — nothing else ranks steps. Drag a card to move it, or use Move up and Move down in the step’s menu, which also holds Delete step. Those two exist so that reordering never requires a pointer.

A step points at a request, it never copies it

This is the rule the rest of the page rests on. A step added from your collections holds the path of that request, not a copy of it.

Two things follow, and both are the reason flows are worth keeping:

  • A request you fix is fixed everywhere. Correct a typo in the link once and every flow that uses it launches the corrected one. Nothing goes stale behind your back, which is what would otherwise turn a healthy flow into a fake regression.
  • A flow never writes back. Nothing you do inside the flow reaches the request file under collections. You can retune a whole scenario without touching what anyone else runs.

Rename the request and the step follows it, because a step with no label of its own shows the request’s name.

Delete the request and the flow still runs. The step is recorded as skipped, with the reason, and the recap still accounts for it — a run that quietly dropped half a scenario would read as a clean pass. The step’s menu then offers Relink…, to point it at another request, and Convert to inline, to keep the link it last knew as its own.

Override a value for this flow only

Expand a step and you get every value it can substitute, with the source’s value beside it. Type over one and only this flow sees it; the panel says so above the table. Reset to source drops the whole layer at once, and dropping the last value returns the step to exactly the state it had before you overrode anything.

Run options behave the same way, with the same controls as the request editor’s Options tab, because they are the same options. A step inherits every option from its source and stores only the ones this flow decides, so each row can say whether it is following the request or the flow — and one gesture puts it back to inherited.

That is what lets one request serve two scenarios: the same link, with a different identifier in the path here and Force-stop app first on there, without a second copy of anything.

Decide when screenshots are taken

An image per step is what turns a report into something a developer can read without you in the room. Where you decide it is the part worth knowing: the choice belongs to the flow, not to each step, and it sits in the brief next to the description.

Setting What it captures
Per request Whatever each step’s own screenshot option asks for. This is the default.
Never Nothing at all, whatever the steps ask for.
Every step One image per step the run launches, passed and failed alike.
On failure only Only the steps you answer as failed.
On success only Only the steps you answer as passed.

Two things about this surprise people, and both cost a session when they bite.

A screenshot on a verdict is taken when you answer, not when the step launches. Under On failure only and On success only the image is grabbed at the moment you press the answer, so what it holds is the screen you were looking at while judging — not whatever the app had drifted to a second after the link went out. Per request is the exception, and the older behaviour: it captures once the launch settles.

The setting is shared, the images are not. Your choice is written into the flow file, so it travels to your team through the project like everything else in .ryno. The images do not: they land in .ryno/screenshots, which Ryno excludes from the repository with a screenshots/ rule the moment it sets a project up. So a colleague who pulls your flow inherits the policy and none of the pictures, which is what you want — one run, on one device, on one afternoon.

One device cannot be captured at all: a cabled iPhone, whose tooling has no screenshot verb. Pick a policy that promises an image on that fleet and the app says so under the picker rather than letting you find out from an empty report.

Start the run

Run flow sits at the top of the flow, in the same green as the run button in the top bar, and it wants two things: a device selected and at least one step. A step whose request has gone missing is not one of them — it is skipped by the run, never a reason to hold the whole scenario back.

The runner then takes the entire window. That is the feature, not a flourish: during a run your eyes are on the phone, and the screen has to answer which step, which link, which device in one glance from across a desk. Everything else in the app is out of reach until you are done, so nothing can be clicked by accident with a phone in your other hand.

Answer each step with one key

Each step launches, and then the runner asks you one question. Answer it with Y if the app did the right thing, N if it did not, and S to move past a step you cannot judge right now. The same three choices are on screen as buttons, sized to be hit without looking.

No modifier, on purpose. During a run one hand is holding a device, so an answer has to cost one key. Two consequences come with that, and the second one is the one to remember:

  • These three keys only mean anything while a run is up. Outside the runner they belong to whatever has focus, exactly like any other letter.
  • They go quiet while you are typing into a field. Without that rule the form on the next screen would be unusable, since the words you write about a failure are full of the letters those keys are bound to.

So the short version, if you only keep one line: press the key when the question is on screen, use the buttons when the cursor is in a text box.

Say what went wrong

Answering that a step did not work unfolds a short form with two questions — what happened, and what you expected instead. The gap between the two answers is the bug description, and it is what somebody who was not there will read.

Neither field is required. A tester who saw the failure and cannot phrase it must still be able to move on: a run recorded as failed and undescribed is worth more than a run stalled, and far more than a Yes pressed to get past a form. Back returns you to the question if you answered by mistake.

When the launch itself fails

Sometimes nothing reaches the app at all — the device went away, the simulator shut down, the tool refused. The runner treats that as its own outcome and says so in as many words: it is a technical error, not a failed check, and the step was never verified. Reading it as a product bug is how a tooling problem turns into a bug report nobody can reproduce.

You get the exit code, the exact command that was sent, and the tool’s own output. Retry step runs the same step again once you have plugged the cable back in; Continue run carries on to the next one. Neither ends the run for you, and the failure is already recorded either way.

A cabled iPhone is the fleet where this matters most, for the reason a single link already showed you: Ryno hands the link to the app you named and gets a clean answer back whether or not the app understood it. Inside a flow that has a plain consequence — the launch confirms nothing, so your own answer is the entire verdict, and no screenshot can be taken to back it up. Everything the report holds for that step came from you.

Read the recap

The run ends on a summary: the three totals, then every step with its verdict, in flow order and skipped ones included.

Each line carries what a reader needs and nothing else — the reason for a skip, the words you typed about a failure, and one sentence saying whether a screenshot was taken and, when it was not, why. Those reasons are not interchangeable, so they are spelled out separately: the flow’s policy excluded this step, the step’s own option was off, the device cannot be captured, the capture failed, or the step never launched at all.

Back to editor closes the runner. The report is already saved by then.

Find the report again

Reports mode, on 3, lists every run of the project grouped by flow — one foldable header per flow, newest first, each holding its own attempts. That grouping is the question a history gets asked: not what ran on Tuesday, but how has this flow behaved across its retries.

A report is self-contained. It stores the flow’s name, the device and the family it belongs to, the links that were launched and the step labels as they were at run time, so renaming the flow, reordering it or deleting it outright never changes what an old report says. That is the whole point of keeping one.

Two actions sit in its header. Copy prompt for AI puts the failures on the clipboard already written up as something you can paste into an agent, which is usually faster than describing them again. Delete run removes that one record.

One limit worth knowing before you lean on it: this history is personal to your machine and stays out of the project, and it is bounded. Ryno keeps around 50 MB of run history per project — tens of thousands of runs — and once past that the oldest ones drop off on their own. It is a trail, not an archive: a report you need to keep is one you should copy out.