Skip to main content

Conditions & if / else

A condition guards work: one step, or a whole group with else and else if arms. So a session can take one of several paths instead of being split into separate files you choose between by hand.

Two shapes, one vocabulary:

GuardsReach it from
Run only ifa single stepright-click a step
if / else blocka contiguous rangeright-click a selection

Guard one step​

Right-click a step and choose Wrap in an if / else…, or set a guard on the step itself. Trq asks you to tap the element the condition is about, then opens the dialog.

A guarded step that doesn't run is marked skipped, not failed, and the row says which condition skipped it.

Guard a group​

  1. Select the steps — click one, or Shift-click a range.
  2. Right-click and choose Wrap N steps in an if / else…
  3. Tap the element on the device, then build the condition.

Three rows appear: an if marker, your steps indented beneath it, and an end. Steps between them run only when the condition holds; anything after end always runs.

Right-click the if marker for the rest:

Menu itemWhat it does
Edit condition…Change what this arm asks
Add else if…Another condition, tried in order, before any else
Add elseA final arm, for when nothing above matched
Remove the if / else (keep steps)Delete the markers; the steps stay, unguarded

Arms are tried top to bottom and at most one runs. Once one matches, the rest are skipped without being evaluated at all.

Once an else exists both Add else options switch off — an arm after the catch-all could never be reached. The menu says so rather than just greying out.

note

Reach these from any marker in the block. "Add an else" is an action on the condition, so right-clicking its end does what right-clicking its if does.

What a condition can ask​

The dialog has one structural choice — On the screen or On a variable — and then asks only what that kind needs.

On the screen​

Pick an element, then choose a check:

CheckMeans
is visibleOn screen — not scrolled away or covered
existsIn the accessibility tree, seen or not
is enabledNot greyed out
is checkedA checkbox or radio
is selectedA tab or chip — not the same as checked
can scrollThe element scrolls its own content
text isExact match
text containsCase-insensitive

is visible and exists are different questions, and the gap between them matters more than it sounds. An element can sit in the tree, enabled, matching your selector, and still be scrolled out of its container or hidden behind a bottom sheet. exists is true then; is visible is not.

is selected is not is checked. A selected tab is not a ticked box, and Android reports them through different accessors.

An element condition waits up to 2 seconds for its answer, because a screen may still be painting. Expiry is the answer — unlike a step's find timeout, where expiry is a failure.

On a variable​

Compare a captured {{var.NAME}} against a value: equals, contains, matches, is less than, is set, and so on. Captures from earlier steps are offered as chips, because a typo in a variable name evaluates to "never captured" forever.

This is the same vocabulary and the same comparison the API Tests tab uses, so equals is numeric-tolerant here too — "10" equals "10.0".

A variable condition does no waiting. The capture already happened, so a variable can't become true by waiting; it resolves in about zero milliseconds.

Either side can be a {{var.x}}, an {{env.X}}, a {{calc(...)}} or a plain literal. Selector values are templated too, so "run only if the row for {{var.accountName}} is visible" works.

Inverting​

Invert — run when this is NOT true flips the verdict. The dialog previews the sentence that will land on the row, which is the quickest way to catch a condition that reads as the opposite of what you meant.

Inversion applies to the verdict, after the wait. "Run only if the error is not visible" waits for the error to appear and runs only if it never does — not merely if it hasn't appeared yet.

What a run looks like​

Steps in an arm that didn't run are marked skipped, with the condition that skipped them. Nothing is sent to the device for them.

Markers aren't steps. They carry no timing, no screenshot, and never appear in a report as passing or failing — a session with nine steps and two blocks still reports nine. Their rows show the role (if, else if, else, end) and the condition, in grey, with the guarded steps indented one level.

While you're recording​

A condition doesn't run while you record — recording captures what you do, and you are the condition. Guards and arms are evaluated on Play, in Debug (step through a branch exactly as it runs), and from the CLI.

Nesting​

Blocks nest, and a block inside a skipped arm is never evaluated — its condition would be asking the screen about something the skipped steps never did.

An example​

Skip a first-run tour only when it's actually showing:

1 launch com.example.app
if Skip tour is visible
2 tap Skip tour
end
3 tap Accounts
if {{var.plan}} equals pro
4 assert Portfolio is visible
else if Upgrade banner is visible
5 tap Dismiss
else
6 assert Accounts is visible
end
7 tap Settings

Steps 1, 3 and 7 always run. Step 2 runs only on a first launch. Exactly one of the three arms runs between 3 and 7.

Half-authored blocks​

An if with no condition takes its else arm rather than guessing, so a marker you haven't finished never silently runs its steps. A stray end is ignored rather than failing the session — a session caught mid-edit still plays, and refusing over one orphaned marker would be the worse failure.

Deleting any marker removes its partners too. Leaving them behind would make the list unreadable — but the steps between them are untouched, because removing a condition should un-guard your work, not destroy it.

See also​