Recording Results

Recording a result is the core action of test execution. On the v2 Cases tab you can record with one-tap inline buttons, a side detail panel, a full-screen focus runner, or a per-case runner route when you need steps, notes, and evidence. Bulk actions and a fail→issue prompt round out the workflow. Every result is timestamped, attributed to the tester, and preserved in history.

Think of it as filing an inspection report

Each test case is an inspection item. Choose the recording mode that fits the moment — sweep a smoke pass with inline buttons, work through steps in the panel or per-case runner, or keyboard-drive a long regression in focus mode. Assignment is set from the row or bulk bar; defects are captured through the fail→issue prompt. Recording is deliberately fast and status-first — no spinner — so a tester can sweep a whole run in seconds.

Inline recording (default)

  1. Open a run from the TEST RUNS tab.
  2. Switch to the Cases tab.
  3. Tap a status button on the case row to record that outcome.

The row shows a compact quick strip of the first three run-result statuses (in admin order), each with its configured icon. Additional statuses live behind a ··· overflow menu that lists every status with its icon, label, and keyboard hint. When the active result is an overflow status, that status takes over the overflow slot so the current value stays visible. Click the active status again to clear the case back to Untested.

The row updates immediately — result pill, progress bar, and overview cards all refresh from the optimistic cache. The change syncs to the server in the background; watch the workspace header Sync pill for status.

Panel mode

In list view, open the Display control and set Result entry to Panel. Click a case row (or press Enter when it is active) to open a side detail panel beside the list.

The panel shows the case’s steps, a rich-text result note, any result fields the case’s template defines, the result buttons, and the case’s result history. Type a note, pick a status, and the note is saved with that result. Expand the panel to focus mode or the per-case runner for a full-screen view of the same case.

Result buttons in panel and focus mode

Panel mode and focus mode share one result control, sized so it never outgrows its space no matter how many statuses your administrator configures.

  • Panel mode shows the first four statuses (in admin order) as one-click buttons, two per row.
  • Focus mode shows the first three as tiles on a single row.
  • Each button carries its admin icon, its colour, and its 19 keyboard number.
  • Every remaining status lives behind a More statuses button that opens a searchable list — type to filter, Enter picks the first match. When a result is recorded, the list also offers Clear result, which stays reachable while you are searching.
  • The current value is always visible: if the recorded status is one of the overflow statuses, it is pinned as an extra button and the overflow trigger relabels to All statuses.
  • Clicking the recorded status again clears the case back to Untested.

Keyboard numbers count positionally through the full admin-ordered list, so 1n are exactly the visible buttons and a pinned overflow status keeps its own number. Statuses above nine have no number badge.

Focus mode

Click Focus in the Cases toolbar (or press F on an active row in list view) to open a full-screen, keyboard-first runner. Everything else — app chrome, the case list, the toolbar, other cases — goes away behind a dimmed backdrop.

A top bar carries the run id and title, a progress bar, an executed / total count, and an exit control. The case card sits in the centre between previous/next arrows, with a right rail showing the current result, assignee, case properties (priority, folder, template, environment, executions), and per-case history. A keyboard legend runs along the bottom, so the shortcuts below never have to be remembered.

The card itself scrolls — folder crumb, case id, priority, current result, case attachments, steps, result fields, and a note box — but the status buttons and Pass & next are pinned to the bottom of the card and never scroll away. On a long case you can always record without hunting for the controls. On a narrow window the rail steps aside and history folds back into the card.

Key Action
1n Record the matching status (admin order, up to nine); press the same key again to clear it back to Untested. Records only — it does not move you on.
P Pass & next — record your first success status and advance. See Recording never moves you on.
J / K or arrow keys Next / previous case, in run order
Space Jump to the next untested case (records nothing)
Esc Exit focus mode — or, if you are typing in the note or a field, leave the field first

Shortcuts stand down while you are typing, so a note containing the letter p never records a pass.

Per-case runner (steps + evidence)

Open a single case in its own route (/test-runs/…/cases/…) for structured, step-by-step execution. A breadcrumb shows TR-…, the folder, and the case with its n / N position; chevrons or J/K move to the previous or next case, and Pass & next (P) is the one control that both records and moves on — see Recording never moves you on.

  • Per-step results — each step carries a Set… status picker (with a Clear item); a Mark all steps control sets or clears every step at once. A running N of M passed count is shown.
  • Suggested result — once every step is marked, the runner suggests the overall result and offers a one-click Record button for it.
  • Record result composer — a rich-text comment area (select text to format; paste images inline), an evidence strip for attaching screenshots and files, any result fields the case’s template defines, a Set result… popover listing every admin status (with 1n keyboard hints), and — once every step is marked — a tinted Record {suggested} button for the step-derived status. Recording is held while an image or evidence file is still uploading.
  • Right rail — a labelled Set result control (the admin result statuses in a popup, plus Clear result), the assignee picker, read-only case properties (Priority, Folder, Environment, Estimate, Executions), every other custom field the case carries, and the two relation blocks: Covers and Defects in this run. The rail opens at 336px and is resizable — drag the divider on its left edge, or tab to it and use / in 16px steps — between 264px and 560px. The width is remembered in your browser and shared with the case editor’s properties rail: the two rails show the same properties at the same scale, so sizing one sizes the other.
  • Case attachments — the files the test case itself carries, shown read-only so a tester can open the reference material without leaving the run.

Recording never moves you on

Recording a result and moving to the next case are two separate intentions, and TestOrchestrator keeps them separate. Nothing advances unless you asked it to.

Pass & next is the only control that says “next” out loud, and it is the only one that does it — the button in the runner header, its twin in focus mode, and the P shortcut. Everything else records and leaves you exactly where you are: the Set result… popover, the suggested-status button, the 1n number keys, the inline status buttons, and the rail’s result picker.

  • Pass & next records your first success status, not a status called “Passed”. It uses whichever status your administrator ordered first among those flagged as a success. A workspace whose catalogue starts with Passed w/ exceptions gets that one, because that is what the admin put first. If no success status is configured, the button is not shown at all.
  • On the last case it renames itself. The button reads plain Pass rather than Pass & next, its tooltip names the status it will record and says this is the end of the run, and recording shows Recorded — last case in this run. A control that promises to move on and then does not reads as broken, so it stops promising.
  • Pass does not un-pass. Pressing Pass & next on an already-passed case re-records the pass; it has no toggle-off behaviour. Clearing a result is a deliberate, separate action — the status tiles and number keys clear when you re-press the active one, and the popovers carry an explicit Clear result item.

The rail’s result picker is the correction path. Setting a result from the rail does not advance, and — importantly — it records through the composer, so the note you have typed and the evidence you have attached are saved with it rather than left behind looking unsaved. The one exception is Clear result, which deletes the result those values would hang off and therefore carries nothing.

Success and failure are properties your administrator sets, not names we look for. Everything that asks “did this pass?” — pass rates, the run-health card, the fail→issue prompt, requirement coverage, the release gate — reads the Considered success / Considered failure flags on the status, never its name or position. So a custom status called Passed w/ exceptions counts as green, and a blocking status your team named Env down counts as blocked. See Status Properties.

Covers and Defects are separate blocks

The runner rail splits linked tracker issues into two blocks, because they answer different questions.

  • Covers — labelled from the test case. These are the requirements this case exists to verify. They are read-only inside a run: coverage is authored on the repository test case, not on an execution, so the rows carry no actions. When the case covers nothing the block reads No requirement linked on this case.
  • Defects in this run — what broke while running. This block keeps the Link action for attaching an existing issue, and reads Nothing linked yet. when empty.

The two are memberships, not a split of one list: an issue linked to the case both as a requirement and as a defect legitimately appears in both blocks. See Relations for how a link gets its meaning, and how to change it.

Case attachments in the runner

Files attached to the test case — a spec PDF, a reference screenshot, sample data — are inherited into the run and shown on the runner, the side panel, and focus mode. Click one to open it in a preview (images, PDFs, and text render inline; anything else offers to open in a new tab).

They are read-only here. There is no attach, remove, or reorder control in a run, because the files belong to the repository case exactly like its Description does — edit them on the case itself. A case with no attachments shows nothing at all rather than an empty state, so the runner stays quiet for the majority of cases that carry none.

Case attachments are not evidence. Evidence is what you attach to a result while executing, through the composer’s evidence strip. Case attachments are reference material that arrived with the case. They are frozen separately at close — see Sign-off snapshots.

Long-form case fields read as prose

Custom fields your administrator defined with the TEXT type are long-form prose, so the runner gives each one its own block in the main content column — in reading order alongside Description, Preconditions, and Steps — rather than squeezing it into a rail row or a table cell. The block shows the field label with a pencil glyph and renders the value’s formatting and inline images. A case that has no value for the field keeps its block and shows a No <field> on this case. empty state, so a missing answer is visible rather than silent.

These blocks are read-only inside a run: the value belongs to the repository test case, exactly like Description and Priority. Because TEXT fields are unbounded prose, they are not offered as display-property chips, table columns, or side-rail rows on the Cases tab — those surfaces list your property fields (dropdown, multi-select, checkbox, date, number, link, and single-line string). A field the workspace calls “Description” or “Preconditions” only merges into the built-in block of that name when its system name matches exactly; a differently-named field with a similar label keeps its own block.

Result fields

A status says what happened. Result fields — called Test Run Fields in Admin → Fields — capture the surrounding facts an auditor needs: the build under test, the device it ran on, how long it took, whether a regression check was done. They are a separate family from test case fields: a case field describes the case, a result field describes one execution of that case.

The form follows the case’s template

Result fields are attached to templates, so which form you see depends on the template of the case in front of you. Two cases in the same run can show different result fields, or one can show a form and the next none at all. Fields appear in the order your administrator defined them, and the form card names the template it came from on hover, so “why did this change?” is answerable without leaving the case.

Values are recorded per execution, not per case. The form resets when you move to another case and again after each recorded result, so ten results on one case carry ten independent sets of values, each staying attached to the result it was entered with. It starts empty every time — unless your administrator switched on Carry forward for a field.

Fields that carry forward

Some facts barely change between executions: the build number, the device, the environment build tag. Re-typing them on every result is busywork, so an administrator can mark a result field Carry forward. When they have, the field opens seeded with the value from the previous result recorded against that same case in that same run.

The seeding is narrow on purpose:

  • It reads the case’s own execution history in this run — never another case, never an earlier run, and never whatever you last typed somewhere else.
  • It reads the most recent execution only. If the tester before you left that field blank, you start blank too — a blank is information, and the form will not go digging further back to find something to put there.
  • It applies again after you record, because the next execution on that case is still the same case in the same run.
  • A case being executed for the first time in a run has nothing to seed from and starts empty as usual.

A carried value is a default, not data. It is filled in for you and you can overwrite it before recording; nothing is written until you record, exactly as before.

Carry forward is off unless someone turns it on. It is a per-field switch in Admin → Fields → TEST CASES, on a Test Run Field’s editor under Behaviour. A workspace that never touches it sees the form start empty every time, as this page has always described.

TEXT result fields never carry forward. The toggle is disabled for them and the runner refuses to seed one under any circumstances. A TEXT field is where you write what actually happened this time; arriving to find last execution’s findings already in the box is how a stale observation gets signed off as a fresh one. Every other type — STRING, INTEGER, FLOAT, DATE, LINK, DROPDOWN, MULTI_SELECT, CHECKBOX — can carry forward.

One-tap and bulk paths carry no values at all, so they neither seed nor save a carried value. Carry forward only ever applies where the form is actually on screen.

Entering values

The result form appears wherever a result is composed rather than tapped — the side panel, focus mode, and the per-case runner — sitting just above the result controls. It is shown only to testers with the Execute tests permission, and never on a closed run.

Every type an administrator can give a result field is supported except STEPS, which is not offered for results at all:

  • DROPDOWN — a single-select picker; each option carries the icon and colour set in admin config.
  • MULTI_SELECT — pick any number of options.
  • CHECKBOX — an on/off toggle.
  • TEXT — a rich-text box that spans the full width of the form, for prose you write per execution (unlike a TEXT case field, which is read-only in a run). This is the only result-field type that takes images: paste or drop a screenshot straight into it and it uploads with the result, exactly like the note. Every other type is a plain value.
  • STRING, INTEGER, FLOAT, DATE, LINK — single-line inputs, each with the matching keyboard and picker: whole numbers, decimals, a date picker, and a URL field. STRING is the single-line one; TEXT is the multi-line rich-text one.

How a result field is dressed

Beyond its type, each result field can carry presentation settings your administrator authored in Admin → Fields. They are all optional; a field with none set looks exactly as its type dictates.

Setting What you see
Icon An icon and colour beside the field name, replacing the generic glyph its type would otherwise get. Without one you still get that type glyph — a calendar for DATE, a chain for LINK, and so on.
Unit A short suffix after the value, inside the input — min, ms, MB. It is read out with the field, so a screen reader hears the unit too. Single-line types only (STRING, INTEGER, FLOAT, DATE, LINK); it does not appear in the result history.
Placeholder Hint text while the box is empty. An authored placeholder replaces the built-in nudge (0 for numbers, https://… for a link, the default prompt on a TEXT box). Dropdowns always read Select…; multi-selects and checkboxes take none.
Help text A tooltip on the field’s label — hover the label to read it. It is not printed under the input, so it will be a sentence rather than a paragraph.

Icons come from your configuration, never guessed. The product does not infer a glyph from a field’s name, so renaming a field never changes or loses its icon. The same is true of dropdown option icons: an option shows the icon and colour an administrator gave it, a plain colour dot if only a colour was set, and plain text if neither.

See Presentation in the Fields admin docs for how these are authored.

Required result fields

Your administrator can mark a result field required for a project. A required field carries a dot beside its label (announced as “required” to screen readers) but stays neutral until you actually try to record — nothing is flagged red on first sight.

If you try to record with a required field still empty, nothing is written. A red banner names the missing field and the template it belongs to, and the composer keeps everything you had already entered — the note, the attached evidence, and the values you did fill in. Fill the field in and record again. A blocked attempt is not a failed save; no result, and no partial result, reaches the server.

The check sits on the write itself, so every path to a result on a surface that has the form honours it: the Set result popover, the suggested-status button, Pass & next, the 1n keyboard shortcuts, and the rail’s result picker. Clearing a result is exempt on every path — clearing deletes the result the values would hang off, so there is nothing to require and nothing to send.

One-tap recording on a case that needs a form

Some ways of recording carry no form at all: the inline status buttons on a row, the board and table cells, the bulk bar. They send a status and nothing else. If the case’s template requires a result field, there is no honest way for those paths to satisfy it.

So rather than fire a request that is certain to be rejected, a one-tap attempt on such a case writes nothing and takes you to the form: the case opens in the runner (or focus mode) with the required field flagged, ready to fill in. One tap, one bounce, no error.

The banner you land on names the status you tapped, so your click is spoken back to you rather than quietly dropped: Passed wasn’t recorded — Build is required on the Regression template. Fill it in and try again.” With more than one field missing it reads Build and Device are required… Fill them in and try again.” The status travels in the page address, so the bounced-into state can be shared or navigated back to.

Once you record something yourself the status name drops out of the banner — you can see your own pick on the surface in front of you, so repeating it would just be noise. From then on it reads the plain form: Build is required on the Regression template. Nothing was recorded — fill it in and try again.”

Clearing a result is never bounced. Clearing removes the result the values would hang off, so there is nothing to require. And where the per-case runner is not reachable, the bounce opens focus mode instead — either way you land on a form, whatever view you started from.

A required checkbox behaves differently depending on how you record. This is the one genuinely surprising rule, and it follows from what each path can send.

  • In the result form a checkbox is never missing. Unchecked is a real answer, not a blank, so a required checkbox is already satisfied the moment the form opens and it will never block you.
  • On a one-tap or bulk path no field values are sent at all, so a required checkbox genuinely is missing — and those cases are gated like any other.

Because “required” on a checkbox can therefore only ever cost you a detour, administrators are blocked from setting it (the rule is enforced on both the admin screen and the server). To make a tester consciously answer, use a Yes/No dropdown and mark that required instead — a dropdown has a real unset state, so it gates consistently everywhere. See Project Overrides.

You may still meet a required checkbox on a field configured before that rule existed; those are read as not required by the result form, which is why the two paths can differ.

While evidence is uploading, the write waits

A result and its evidence must land together, so recording is held until every image and attached file has finished uploading — whether it is in the note, in a TEXT result field, or on the evidence strip. The record controls dim and a line beneath them says why:

  • Waiting for the evidence upload to finish before recording. — an upload is still in flight. It clears on its own.
  • Retry or remove the failed image before recording. — an upload failed. This one needs you: retry it or take it out, then record.

The message is announced to screen readers, and it is the same message wherever you record from — the composer button, the suggested-status button, the rail’s result picker, and Pass & next all point at it rather than each inventing their own. Clearing a result is never held: it carries nothing, so there is nothing to wait for.

Evidence is uploaded straight away, but saved only when you record

A file uploads the moment you drop, paste, or pick it — there is no separate upload step — but it is not saved until you record a result. Until then it is held in a draft belonging to the case you are on, and the composer says so rather than letting a settled chip look filed:

  • Each chip on the evidence strip is dashed and carries a draft badge.
  • An image pasted into the note or into a TEXT result field gets the same dashed outline and badge, since it has no chip to carry one.
  • A line beneath the strip reads “N files uploaded but not saved — they’re attached when you record a result.”

Because the draft belongs to that one case, leaving the case throws it away — so you are asked first. Moving to another case or leaving the composer while a draft is holding files raises a confirm headed Discard N uploaded file(s)?, reading “They were uploaded but never attached to a result. Leaving this case deletes them for good.”

  • Cancel puts you back in the composer with the note, the evidence, and the draft untouched. Record, and all of it is saved with the result.
  • Discard deletes the uploaded files, then goes where you were heading.

The prompt sits on every gesture that would abandon a composer holding uploads: prev/next and exit in the per-case runner; the case walk and close in focus mode; and, in panel mode, the close control, Esc, the J/K case walk, Enter, and clicking a different case row. Cancelling always puts you back exactly where you were — the same case still in the panel, its draft intact, and the row selection unmoved. Closing the browser tab raises the browser’s own leave-the-page prompt instead, because no dialog of ours can intercept that. A composer holding no uploads never prompts at all.

There is no draft result. The prompt has exactly two exits — go back and record, or discard. A placeholder “draft” status would put an un-signed-off row into the run’s history and its sign-off, so the way to keep evidence is to record a result.

Uploads left in a draft for 48 hours are deleted. A crashed tab or a closed laptop can leave a draft nobody ever discards, so the server sweeps uploads that were never recorded against: 48 hours after a file was uploaded, it is permanently removed. Files attached to a recorded result are never touched by the sweep.

Recorded values in history

Values recorded with a result appear beneath it in the case’s result history as compact chips — the field label in a faint tone, then the recorded value. A chip always carries a value; a field label never stands on its own. If an admin left an option’s display label blank, or the option has since been retired, the chip falls back to the stored value rather than showing the field name and nothing else. Long values are shortened to fit — hover the chip to see the full text.

How each field type reads:

Field type In the history
Number (integer or decimal) The value followed by the field’s admin-configured unit, for example Duration 42 min. Only number fields show a unit — a unit set on any other type is ignored.
Dropdown The selected option’s label, carrying its admin-configured icon or colour dot.
Multi-select One chip for the field, with the chosen options comma-separated — not a chip each.
Checkbox Ticked reads Yes. Unticked shows no chip — see the note below.
Date Exactly as recorded; it is not reformatted.
Link and single-line text The value as plain text. A link is shown, not made clickable, here.
Long-form text Never a chip — it renders as a prose block instead.

An unticked checkbox is recorded, but not shown as a chip. Only Yes is worth a chip — a row of No chips is noise on a history you are scanning for what happened. The false value is still stored with the result and still appears in the frozen sign-off snapshot record; it simply does not take up space in the chip strip.

A field left empty shows no chip, and a result recorded with no field values at all shows no chip strip. Chips appear the instant you record — they are written optimistically alongside the result, so they do not wait on the server and do not need a refresh. Because every set of values is bound to its own result, the history reads as a timeline of what was true at each execution, not just the latest one.

Bulk results

  1. On the Cases tab, select multiple case rows with the checkboxes.
  2. A floating bulk bar appears at the bottom of the viewport showing N cases with an inline clear control (or press Esc to clear the selection).
  3. Choose Assign to stamp one tester across the selection (or Unassign), or Set result to apply one status to every selected case (Clear result resets them to Untested).
  4. Use Remove from run to take the selected cases out of this run. Their recorded result history is preserved, so re-adding a case restores its past executions.

The bar shows an applies instantly · syncs hint — each bulk action writes once to the cache and queues one mutation, the same optimistic pattern as single-row recording. When the bar sits near the bottom of the screen, its menus open upward so every option stays visible.

Cases with a required result field are split out — and you decide before anything is written. A bulk action stamps one status across many cases and carries no field values; one form filled once cannot honestly describe several separate executions. So if your selection includes cases whose template requires a result field, a dialog appears first, headed Record <status> on <N> cases, telling you exactly how many need a value and naming the fields their template asks for. You choose:

  • Record the other m — stamp the cases that can take it, and leave the rest untouched.
  • Review the n — go and record those cases individually, where the result form is available.
  • Cancel — write nothing.

If every selected case needs a value, the dialog says so and offers no bulk option. Nothing is written until you choose, so there is no after-the-fact list of failures to reconcile.

Assigning cases

Change the assignee directly on any case row with the assignee picker, or select several rows and use Assign in the bulk bar — its menu lists your project’s members and ends with Unassign, which hands the cases back to the pool. Both paths write optimistically. Assigning requires the Execute tests permission. See Assigning Testers.

Fail→issue prompt

When you record a Failed or Blocked result and the case has no linked tracker issue, a non-blocking prompt appears offering to Raise issue or Link issue. You can dismiss it and continue — the result is already saved.

When you would rather not be prompted

Sweeping a run with many failures should not mean dismissing a prompt per case. Dismiss the fail→issue prompt twice in a row and TestOrchestrator takes the hint: per-case prompting stops, and one quiet run-level chip stands in for all of them — N failures with no linked issue, pinned at the bottom of the Cases tab.

  • Triage opens the Issues-tab composer with every unlinked failed or blocked case already selected, so one issue can cover the lot.
  • The chip has no auto-dismiss timer — it is already the quiet mode. It stays until you act on it or close it, and disappears on its own once nothing is left unlinked.
  • Engaging at any point (raising, linking, or triaging) resets the streak, so the per-case prompt comes back for the next failure.
  • The streak is per run and starts fresh each time you open a different run.

Close guard still applies. Closing a run with failed cases that have no linked defects triggers the server close guard. Link issues before closing for full traceability.

Result statuses

Each inline button records one status — the overall outcome of executing that case. Statuses are admin-configured and open-ended: the first three (in admin order, with their configured icons) appear as one-click glyph buttons; the rest sit in the ··· overflow menu. Only statuses with the Available for Run Results scope are shown (the Untested status is excluded; clicking a case’s active status again clears it back to Untested). See Scope Availability for how run-result statuses are configured.

Recording is status-first and optimistic. Inline buttons are the fastest path — no “Add Result” modal and no spinner. Panel mode and focus mode use the result buttons; the per-case runner uses the composer described above. Assignment is set with the row’s assignee picker or the bulk bar; defects are captured through the fail→issue prompt below.

Linking a defect

Defects are linked through the fail→issue prompt. When you mark a case Failed or Blocked and it has no linked tracker issue, the prompt offers:

  • Raise issue — create a new issue in a configured tracker and link it to the result. Writable trackers (for example Linear) create instantly from the composer; others open the tracker’s new-issue page so you can link the fresh key back.
  • Link issue — attach an existing issue by key or URL.

Issue sources (Jira, Linear, GitHub, Azure DevOps, and others) are set up under Integration Sources; linking requires the Manage external references permission. Linked defects also appear in the per-case runner’s Defects in this run rail block and on the run’s Issues tab, giving end-to-end traceability from a failed result to its defect.

Linking from a result means “defect”. Because you are standing on an execution, the relation is preselected as a defect-style one — linking here is a statement about what broke, not about what the case is for. Requirement coverage is authored on the test case instead. You can always pick a different relation, and change it later. See Relations.

Closed runs are read-only

Once a run is closed, nothing in it can be recorded. Case rows drop their inline status strip, assignee picker, and selection checkbox; the toolbar’s Focus action disappears; and the panel and focus runner show the recorded result as a static row (Read-only) rather than an entry control. The per-case runner keeps its recorded per-step marks visible but replaces the Record-result composer with a banner explaining the state, and the rail’s assignee row says Run is closed — reopen to reassign.

Everything already recorded stays fully readable — including the per-step marks on every history entry, not just the latest one — and the run’s frozen sign-off is available from the Overview tab. To record again, reopen the run.

Result history

Every result recorded for a case is preserved permanently. The most recent result determines the case’s current status on the Cases tab. Previous results are never overwritten — they provide a complete audit trail visible in the panel, focus mode, and per-case runner history and on the Activity tab. Rich-text notes render in history; older plain-text notes display unchanged.

Each history entry is one execution, and it shows everything that execution carried: the status, who recorded it, the note, thumbnails of the evidence attached to that result, its per-step marks, and the result-field values recorded with it — short values as chips beneath the note, TEXT fields as their own labelled prose. Click a thumbnail to open the file full size. If a file has since been deleted, its tile falls back to a labelled placeholder carrying the file name, so the record still says what was attached.

An image you paste into the note appears in the note, not twice — it is not also listed as a separate thumbnail. Evidence you have just uploaded shows on the new history entry immediately, without a page refresh.

Per-step marks in history

An execution recorded with per-step results carries those marks into its history entry, between the note and the field chips, so which step failed? is answerable from the history rather than only from the runner. Collapsed it is a single line — 3/5 steps marked · 2 passed · 1 failed, each tally in its status’s colour, in admin order. Expand it and every step of the case is listed: its number, its wording, and what it was marked, with the status’s icon and colour.

  • Steps nobody marked are listed too, reading a faint Not marked. A gap in the marking is half the answer, so it is shown rather than skipped.
  • Every entry keeps its own marks. They belong to the execution they were recorded with, so an older result still shows what was marked at the time, not what the runner holds now.
  • A status renamed or retired since the execution is still counted and still named, but as plain text with no icon — nothing will put a glyph on an outcome it can no longer resolve.
  • An entry that carried no marks — recorded from panel mode, which does not mark steps, or a cleared result — shows nothing here at all.

The marks read the same on a closed run, where the runner’s own step controls are read-only and every execution older than the latest one was previously unreadable.