# Test repository

> Suites, cases, steps, detail panel, and trash.

The repository is the day-to-day surface for managing tests inside a project.

## Suite tree

- Suites can be nested.
- **+ New suite** opens a single dialog with a required **Parent suite** picker. The default is **Project root**; you can choose any suite in the tree before saving. A suite's action menu opens the same dialog with that suite preselected as the parent.
- **Edit suite** (suite actions menu or the path bar edit icon) lets you change the name, description, and **parent suite**. A suite's description can hold formatting and images and shows at the top of the suite. The picker starts at the current parent (or **Project root** for a root suite). You cannot pick the suite being edited or any of its descendants; the API still rejects cycles if the tree changed while the dialog was open.
- Expand/collapse branches in the sidebar.
- Create suites from the suite actions menu.

### Collapsing navigation rails (desktop)

On desktop, each navigation column has its own collapse control. States are saved in your browser and restored on reload.

- **Project side rail** (project name, Tests links, Settings) collapses to an icon-only **mini-rail** (~3.5rem). Hover or keyboard-focus an icon to see its label in a tooltip.
- **Suite tree** (this column) has no per-suite icons, so it collapses to a thin strip with an **expand** control instead of a mini-rail. The column stays mounted so the layout does not jump.
- Collapsing one bar does not affect the others—you can hide the project rail while keeping the suite tree open, or the reverse.

To collapse the project, workspace, or user rail, point at it and click the round chevron button on its right edge; the button stays visible while the rail is collapsed, so click it again to restore the full column. From the keyboard, press `[` to collapse or expand the rail, or Tab to the button — it is the rail's first stop. The suite tree collapses with the chevron in its header and reopens with its expand control.

### Narrow-screen navigation

On a narrow (phone-width) screen the repository presents one pane at a time instead of the
desktop's suite tree, case list, and detail panel side by side: the suite list, then a suite's
case list, then a case's detail — each reached by tapping the item above it. A visible **Back**
button (named after the suite you came from, not a bare arrow) returns to the previous pane, and it
works the same way even when you open a case directly from a shared link or bookmark. On a tablet
screen, the suite tree and case list stay side by side, with the case detail opening as a panel
over them.

## Test cases

- Create cases from the repository (quick add or full editor).
- Open a case to view the **detail panel** with tabs for properties and **steps**. Its **Parameters** section lists the case's parameters; select **Edit** there to change them in place, as you would the steps.

### Shareable URLs (display IDs)

The browser uses **human-readable display IDs** instead of internal ULIDs in repository links:

- **Suite in the path:** `/projects/{projectCode}/suites/{projectCode}-S{suiteNumber}` (for example `/projects/ACME/suites/ACME-S2`).
- **Case in the query string:** `?case={projectCode}-{caseNumber}` (for example `?case=ACME-14`).

The link to an open case is `/projects/{projectCode}?case={projectCode}-{caseNumber}` (for example `/projects/ACME?case=ACME-14`) — the same form for every case, whether or not it belongs to a suite. Copy it, paste it or reload it and the repository comes back with that case's detail panel open, highlighting and scrolling to the suite the case belongs to (or **Cases without suite**).

Opening a case never changes the path you are on. While you browse a suite at `/projects/ACME/suites/ACME-S2`, opening a case only adds `?case=`, so the suite stays in view and remains shareable on its own. Any active search and filters in the URL survive the same way.

Older links that carry the suite in the path — `/projects/ACME/suites/ACME-S2?case=ACME-14`, or `/projects/ACME/unassigned?case=ACME-14` for a case without a suite — still open the right case. They are simply no longer the form the app produces.

Invalid or unknown display IDs fail gracefully: unknown suites show a not-found page; unknown `?case=` values leave the detail panel closed without error toasts.

- Edit title, suite, and steps in the editor; classification (priority, severity, status, type, layer, behavior, is flaky, plus any organization custom fields) is rendered dynamically based on the project's enabled fields and persisted through the dedicated custom-field-values endpoint.

### Editor sections

The full editor groups inputs into up to five sections, in this order:

1. **Identification and classification** — title, description, suite, milestone, and the system enum/checkbox fields (priority, severity, status, type, layer, behavior, is flaky) in product order.
2. **Custom fields** — organization-defined custom fields for this project. The section is omitted when the project has no visible custom fields.
3. **Jira issues** and **GitHub issues** — the issues linked to the case, when editing an existing case. Each appears only while its integration is active: Jira when your plan includes integrations and the project maps a Jira project, GitHub when your plan includes integrations and a GitHub account is connected. Links you add or remove here apply immediately, without **Save**.
4. **Pre and post** — preconditions and postconditions. Each can hold formatting and images: paste or drop an image into it, or type **/** and choose **Image**. The section collapses when both are out of scope. When only one is visible, the section title adapts (for example **Preconditions**).
5. **Execution sequence** — the case's manual steps (always shown).

The **Parameters** section holds the case's parameters, and **Review combinations** lists the combinations they produce. A `${name}` you write in a title or a step must match one of them, and the editor names any placeholder that no parameter or configuration group matches. See [Parameterized test cases](https://docs.probara.net/en/guides/parameterized-test-cases/).

Submit performs a slim `POST /api/v1/projects/:projectUlid/test-cases` (or `PATCH /api/v1/test-cases/:caseUlid` in edit mode), followed by the steps `PUT` if any step changed, and finally a `PUT /api/v1/test-cases/:caseUlid/custom-field-values` for the dynamic classification block. If one stage fails the others stay applied and the editor surfaces a partial-success error so the user can retry just the failed step.

### When someone else saved the case first

If someone else saves a case while you are editing it, your save is refused instead of overwriting their changes, and you are told the case was changed by someone else. In the full editor your edits stay on screen until you click **Reload**, which replaces them with the latest version, so copy anything you want to keep first. In the detail panel, **Reload** shows the latest version and closes an open step edit.

### Detail panel General tab

The **General** tab shows description, preconditions, postconditions, steps, and attachments. Preconditions and postconditions hold formatting and images: click one to edit it, and it saves when you leave it (**Esc** discards the edit). Preconditions and postconditions sections render **only** when that system field is visible for the case's project—the same project-scoped definition list that drives the editor. A field hidden per project scope shows no heading, no empty placeholder, and no stored value in read-only views (collapsed detail panel and expanded dialog). Values are not deleted on the server; linking the field to the project again restores display.

### Case attachments

The **Attachments** section ends the **General** tab. It lists every image in the case's texts, labeled with the field that holds it (**Description**, a custom field's name, or a step such as **Step 2**), then the files uploaded to the case. An image used in two fields shows once, with both labels. Click any attachment to open it in the attachment viewer.

To keep a file with the case outside its texts, such as a specification or a log, click **Upload**. Owners, admins, and members can upload any file type except executables (`.exe`, `.msi`, `.sh`, `.bat`, and similar), up to 32 MB per file and 20 files per case; the images in the texts do not count toward the 20. To delete files, click **Edit** next to the section count, use each file's remove button, and click **Done**. A deletion applies at once. An image has no remove button: delete it from its text, and it leaves the list once the text is saved. Viewers see the section but cannot upload or delete.

Uploaded files count toward your organization's storage. They are not part of the case's versions: restoring a version leaves them as they are, and with mandatory [review](https://docs.probara.net/en/guides/test-case-review/) you upload and delete them directly, without a review request. Duplicating a case does not copy them, and archiving it keeps them.

### Detail panel Properties tab

The **Properties** tab renders the **Classification** block dynamically. The first row is **Suite**: a full-width hierarchy selector. **Project root** means the case is not in any suite (it appears under **Cases without suite** in the sidebar). Changing suite here sends a slim case `PATCH`, records workspace activity, and reverts the selector if the request fails.

Below that come system fields (priority, severity, status, type, layer, behavior, is flaky), then custom fields sorted by title in a two-column grid. A paragraph field holds formatting and images: click it to edit, and it saves when you leave it (**Esc** discards the edit). Inline custom-field edits send the full `PUT /custom-field-values` and merge the server response; failures revert only the affected field.

**Traceability** keeps the milestone row only—the read-only Suite row was removed (suite now lives under Classification). The panel's expanded dialog mirrors the same layout.

### Version history

Every save of a case creates a new version of it: edits in the detail panel or the full editor, an import that replaces the case, edits to a shared step the case uses, and edits to a shared parameter the case uses. The **History** tab of the detail panel lists the versions newest first, with who created each one and when; a version created by a shared step edit or an import is labeled as such, and a version created by merging a [review request](https://docs.probara.net/en/guides/test-case-review/) shows **Merged from review**. Click a version to see what changed from the version before it; switch to **Full version** to see the case as it was then, with its title, description, classification, fields, and steps. The first version shows in full. An option deleted since then shows as **Deleted option**.

The version marked **Current** is the case as it is now. A case not saved since it was created has no earlier versions yet.

An image you remove from a text of the case stays with the earlier versions that show it, and keeps counting toward your organization's storage until your plan's history retention removes the last of those versions, or until you permanently delete the case (see [Attachments](https://docs.probara.net/en/guides/attachments/)).

Viewing, comparing, and restoring versions is available on the Pro and Enterprise plans. On other plans the **History** tab explains this and links to the plans. Every save still creates a version on every plan, so the case's whole history is there as soon as your plan includes it, and **Activity** keeps showing who changed what.

To compare any two versions, click **Compare** above the list, tick two versions, and click **Compare** (the older one is compared with the newer one). To compare a version with the case as it is now, open it and click **Compare with current**. A comparison shows only what differs, grouped into details, custom fields, and steps. Changes to a step's keyword and to the case's step format appear there too, and changes to its parameters and excluded combinations appear in a **Parameters** section. Each change shows the field's previous value, an arrow, and its new value; in text, the removed words are marked on the left and the added words on the right. A review request shows its proposed changes the same way.

To go back to an earlier version, open it and click **Restore this version**, then **Restore**. Restoring saves a new version with that version's content; no version is deleted, so you can restore the newer one again later. Owners, admins, and members can restore; the current version has nothing to restore. A few things cannot come back as they were:

- A shared step that still exists comes back as a link to it, so it shows the shared step's current content. A shared step deleted since comes back as regular steps with the text and images the version had.
- A suite deleted since is skipped and the case stays in its current suite; a milestone deleted since leaves the case without a milestone.
- A custom field or option deleted since is skipped. A field the version had no value for is cleared, unless it is required: then it keeps its current value.
- A shared parameter deleted since comes back as regular parameters with the values the version had, and the restore says so.

After a restore, the **History** tab lists anything that was skipped, and the update shows **Restored from version N** in **Activity**. If someone else saved the case after you opened it, the restore is refused and you are asked to reload the case.

### Detail panel on a narrow (phone-width) screen

On a narrow (phone-width) screen the detail panel opens full-screen instead of as a side drawer — no resize handle, and any custom width you set on a wider screen is not applied. Closing returns you to the case list, exactly like the resize handle's absence: there is nothing to resize on a screen this width. Opened from a repository deep link, the panel's own header carries the labelled back control instead of a separate bar. The header's expand-to-full-view control is not shown either — the panel is already full-bleed, so there is nothing left to expand into.

### Status icon

Each case row shows a small icon at the far right when the case's **Status**
is not Active. The icon and its color match the status option configured for
that case (for example, a dashed circle for Draft or a warning indicator for
Deprecated). When the Status is Active or not set, the slot is empty and
nothing is shown — only non-Active statuses need visual attention.

- The icon appears for any status option whose system key is not `status_active`,
  including custom status options that have an icon assigned.
- Custom status options **without** an icon assigned do not show anything even
  when they are not Active.
- Hovering the icon shows a tooltip with the option name.

## Steps

A case writes its steps in one of two formats, chosen with the **Step format** switch in the editor. **Classic** steps have action text, optional **data**, and an expected result. **Gherkin** steps have a keyword and text, with an optional Doc String or Data Table. A new case takes the project's default format unless you choose another. See [Gherkin test cases](https://docs.probara.net/en/guides/gherkin-test-cases/) for the Gherkin rules and the Raw view. Save changes with **Save** when editing steps in the detail panel.

To reuse the same steps in many cases, click **Insert shared step** to add a [shared step](https://docs.probara.net/en/guides/shared-steps/): its steps appear among the case's steps, numbered like them (only the case editor marks them **Shared step**), and always show the shared step's current steps. The picker lists only shared steps of the case's format. Editing it once changes every case that uses it.

### Step images

A classic step's action, data, and expected result can hold images inside their text. While editing steps, paste an image into one of those fields, drop it there, or type **/** and choose **Image**: it goes where you put it. You can add PNG, JPEG, and WebP images of up to 10 MB each, up to 20 at a time. To remove an image, delete it from the text. Gherkin steps take no images. Every image in a step also shows in the case's [Attachments](#case-attachments) section.

You can add images while creating a case too. If you save while an image is still uploading, the save waits for it.

Step images count toward your organization's storage. If a save would take the organization past its quota, the whole save is refused with an out-of-storage message: no step or field changes are saved and your edits stay in the editor. Removing an image, or a step that holds images, does not free that space while an earlier version of the case still shows the image — see [what counts toward storage](https://docs.probara.net/en/guides/attachments/).

## Keyboard navigation in tab strips

Tab strips throughout the application (detail panels, run views, plan views, and other tabbed surfaces) follow the standard WAI-ARIA Tabs keyboard pattern.

### Moving between tabs

| Key          | Action                                                           |
| ------------ | ---------------------------------------------------------------- |
| `ArrowRight` | Move to the next tab (wraps from the last tab to the first).     |
| `ArrowLeft`  | Move to the previous tab (wraps from the first tab to the last). |
| `Home`       | Jump to the first tab.                                           |
| `End`        | Jump to the last tab.                                            |

Selection follows focus automatically — pressing an arrow key both moves focus and activates the tab.

### Tab order

Only the currently active tab is in the page tab order. Pressing `Tab` skips over the inactive tabs and moves focus to the next interactive element after the tab strip. To reach a different tab, first focus the active tab with `Tab`, then use `ArrowRight` or `ArrowLeft` to navigate.

## Bulk selection

Hover any case row or suite band to reveal a checkbox. Selecting at least one case shows a **bulk-action bar** below the filter bar with the selection count, **Edit** and **Duplicate** (visible but not yet active), **Run**, **Delete**, and **Clear selection**.

- **Suite checkboxes are tri-state.** A suite band shows checked when every case in its recursive subtree (including collapsed sub-suites) is selected, indeterminate when only some are, and unchecked otherwise. Toggling a suite band selects or deselects its entire subtree in one action.
- **The "Cases without suite" band** offers its own checkbox for orphan cases; it is never treated as a deletable suite.
- **Selection survives filtering.** Selecting cases, then narrowing the list with search or filters, keeps every selected case counted in the bulk bar even while it is hidden from view. Clearing the filter shows it selected again.
- **Empty suites show no checkbox** — there is nothing to select.

### Bulk delete

Activating **Delete** opens a confirmation summarizing how many suites will be deleted and how many cases will be archived, then:

1. Loose selected cases (not covered by a fully-selected suite) are archived first.
2. The topmost fully-selected suites are deleted — this reuses the existing suite-delete behavior, which archives every case in that suite's subtree. A suite whose parent is also fully selected is not deleted separately; only the topmost one is.

If a step fails partway through, the process stops immediately, the error is shown, and your selection is **not** cleared — the repository refreshes so you can see what changed and retry. On full success, the selection clears and the listing refreshes. If the case you had open in the detail panel was part of the deleted selection, the panel closes.

### Bulk run

Selecting cases and activating **Run** takes you to the project's **Runs** screen with the new-run modal already open and those cases preselected — you can still add or remove cases before creating the run. See the **Test runs** guide's "Creating a run from a repository selection" section for details.

## Trash

Archived cases move to **Trash**. You can restore or permanently remove them depending on your role.

On a narrow (phone-width) screen the trash table becomes a card list: each archived case presents as its
own card, showing the same display id, suite, and archived-at values, with its own selection checkbox
and **Unarchive** action still available. At tablet width and above the list is the table described
above.
