A test plan is a durable, named selection of test cases that you curate once and reuse across releases, sprints, or any repeated test cycle. Typical examples are “Smoke”, “Release Regression”, or “Critical Path” — selections you run repeatedly without rebuilding them each time.
Test plans live at /projects/:projectId/plans in the TESTS section of the project sidebar. Each plan accumulates its own history of generated runs over time, independent of the test repository.
Reaching the screen
Open a project, then click Plans in the TESTS section of the project sidebar. The URL is /projects/:projectId/plans.
The test plans list
The list shows every live test plan in the project as a table with the following columns:
| Column | Description |
|---|---|
| # | Auto-assigned plan number, unique within the project |
| Name | Display name of the plan |
| Cases | Current count of selected test cases |
| Created by | The user who created the plan |
| Created | Creation date |
The list is paginated. Search is not available in v1 — use the plan number or scroll to find a plan.
Creating a plan
- Click New plan (visible to members and above; viewers see a read-only list).
- Enter a Name for the plan — for example,
SmokeorRelease Regression. - Optionally add a Description.
- Click Create plan.
Name rules: plan names must be unique among live plans within the project. If the name is already in use, an inline “This name is already in use” error appears on the name field and the dialog stays open.
Editing a plan
Click the Edit plan action on a plan row to open the edit dialog. You can also open the same dialog from the plan detail view by clicking the Edit plan button in the detail header. Change the name or description and click Save changes.
The same uniqueness rule applies on edit: renaming a plan to a name already used by another live plan shows an inline error and keeps the dialog open.
Deleting a plan
Click the Delete plan action on a plan row. A confirmation dialog names the plan and notes that previously generated runs are unaffected. Click Delete to confirm, or Cancel to return without changes.
Deletion is permanent and cannot be undone from the UI. Runs generated from the plan before deletion remain intact.
Plan detail view — tabbed layout
Click a plan’s name to open its detail view at /projects/:projectId/plans/:planUlid. The detail view consists of:
- A header with the plan name, description, and action buttons.
- A tabbed main area with three tabs: Selection, Configuration matrix, and Progress.
- A summary rail on the right that shows the progress donut, outcome counts, status, milestone, and plan metadata.
The active tab is persisted in the URL (?tab=selection, ?tab=matrix, or ?tab=progress), so you can deep-link directly to a specific tab and the view survives a browser refresh.
Selection tab
The Selection tab shows the plan’s currently selected cases grouped into collapsible suite bands. Cases with no suite appear in an ungrouped band. Each row shows the case ID, title, and assignee.
Click a suite band header to collapse or expand that group.
If the plan has no cases yet, the Selection tab shows an empty-selection state with an Edit selection affordance to get started.
Configuration matrix tab
The Configuration matrix tab shows the dimension value checkboxes and the combination grid. See the Configuration matrix section below for details.
Progress tab
The Progress tab shows the per-configuration breakdown table with outcome counts for each combination that has generated runs.
Editing the case selection
To edit the selection:
- Click Edit selection in the header (visible to members and above).
- The case picker opens pre-checked with the plan’s current selection, with each case’s saved assignee already shown. This is the same picker used when starting a run from the repository.
- Add or remove cases as needed. For each case you can also set or change the Assigned field in the picker.
- Click Confirm to replace the plan’s selection with the full set you have checked, including all assignees.
The new selection — including all per-case assignees — takes effect immediately in the detail view. Any runs previously generated from the plan are unaffected — a run snapshots the case list and assignees at the moment it is generated.
Per-case assignees in the selection
Each row in the Selection tab shows an Assignee column. Members see an interactive Assignee dropdown (combobox) on every row; viewers see the assignee name or ”—” as read-only text.
Changing an assignee inline
To change a case’s assignee without opening the case picker:
- Open the Selection tab on the plan detail.
- Click the Assignee combobox on the row you want to update.
- Select a team member from the dropdown, or select Unassigned to clear the current assignee.
- The change is saved immediately — no confirmation step is required.
Only one row can be updating at a time. While the save is in progress, the combobox for that row is disabled to prevent double-submission. The row reflects the server’s returned value once the update completes.
Important: snapshot semantics
Changing a case’s assignee inline updates only the plan’s stored assignee for that case. It does not back-propagate to any runs that were already generated from the plan. Existing run cases keep the assignee they had at the moment the run was generated.
This is intentional — a run is a snapshot. If you need an existing run’s assignee to reflect a change, use the run’s own assignee controls.
Assigning during Edit selection
You can also set or change assignees in bulk when editing the case selection:
- Open Edit selection in the header.
- Set the Assigned field on the desired cases inside the picker.
- Click Confirm. All assignees are saved with the full selection in a single operation.
Assignees are optional — any number of cases can be left unassigned.
Generating a run from a plan
A plan can accumulate several runs over time, but each action creates exactly one run — a plan never fans out into multiple runs from a single click. A run created from a plan snapshots the plan’s current case selection and per-case assignees, so editing the selection or assignees later does not change runs already created.
To create a run from the plan detail view:
- Open the plan detail.
- Click New run. The button is disabled when the selection is empty — add cases first.
- The New test run modal opens with the plan already selected. Adjust the name, environment, milestone, assignees, and configurations as needed.
- Submit. One run is created and the app navigates to its execution view.
How assignees are seeded into the generated run
When you generate a run from a plan, the plan’s stored per-case assignees are automatically seeded onto the matching run cases. You do not need to reassign people on every run.
The full assignee precedence (first match wins for each run case):
- Per-case override — an explicit assignee you set in the “New test run” modal for that specific case
- Plan’s stored assignee — the assignee saved on that case in the plan
- Default assignee — the “Default assignee” field set in the modal (applies to all cases without a higher-priority source)
- Unassigned — if none of the above apply, the run case is left unassigned
Stale assignees
If a team member who was assigned to a plan case later leaves the organization, generating a run from that plan still succeeds. The run case for that case is simply created unassigned (—) — the stale assignee is silently dropped rather than causing an error.
Generating a run from the new-run modal
You can also start a run from a plan directly from the New test run modal, without opening the plan detail:
- Click New run from the runs list.
- Select the From test plan tab.
- Choose a plan from the dropdown. The modal pre-fills the per-case assignees from the plan’s stored selection.
- Optionally set a Default assignee for cases without a plan-level assignee, or adjust individual case assignees.
- Click Create run. The app creates the run and navigates to the execution view.
The From repository tab continues to work as before — it lets you build a manual case selection for a one-off run.
How plans relate to runs
- A plan is reusable: you can generate any number of runs from it at any time.
- Each run is a snapshot: it captures the selected cases at generation time. Future edits to the plan do not affect past runs.
- Deleting a plan does not delete its runs. The runs remain in the project run history; the link from each run back to the plan is simply cleared.
Plan status
Every test plan has a status that you set and change manually. The three statuses are:
| Status | Meaning |
|---|---|
| Draft | The plan is being prepared — cases and configurations are being curated |
| Active | The plan is in use and generating runs |
| Completed | The cycle is done; the plan is archived in place |
How status works
- A new plan starts as Draft unless you explicitly choose a different status at creation.
- Transitions are free: you can move from any status to any other at any time. There are no terminal states — a Completed plan can be reopened to Active or reverted to Draft.
- Status is purely manual in v1. The plan is never auto-advanced to Completed when its runs close; that decision always belongs to you.
- A same-value PATCH (setting the status to what it already is) is silently accepted — no error, no event.
- An invalid status value returns
422 validation_failed.
Changing the status
Open the plan detail. Members see a Status selector in the summary rail on the right. Select the desired status from the dropdown; the change is saved immediately. Viewers see the current status as a read-only chip in the rail.
Progress
The summary rail on the right of the plan detail shows a progress donut (percent executed + executed/total count) and a results legend (Passed, Failed, Blocked, Skipped, Untested) computed from the same outcome counters as the Progress tab. These numbers are a live rollup computed at read time.
The Progress tab shows the per-configuration breakdown table. See Progress tab above.
Overall outcome counts
The top of the Progress section shows totals across all the plan’s runs:
| Metric | Meaning |
|---|---|
| Total runs | Number of runs generated from this plan (open or closed) |
| Closed runs | Number of those runs that have been closed |
| Passed | Sum of passed test results across all runs |
| Failed | Sum of failed test results |
| Blocked | Sum of blocked test results |
| Skipped | Sum of skipped test results |
| Untested | Sum of untested (pending) test results |
The outcome counts reuse the same per-status counters maintained on each run. No re-scanning of individual results happens at read time.
A plan with no runs shows zeroed counts and an empty breakdown.
Per-configuration breakdown
When the plan has generated runs using the configuration matrix, the By configuration section groups those runs by their combination and shows the outcome counts per group. Each row in the breakdown corresponds to one configuration combination (for example, Chrome / Windows), and carries its own run totals and outcome counts.
Runs that were generated without any configuration tags — either because the plan had no configuration selection at the time, or because they were created manually — appear in a single Unconfigured bucket. The sum of all breakdown row counts equals the overall counts shown above.
Milestone link
A test plan can optionally be linked to a milestone in the same project. This association is purely for release tracking and context — it does not affect run generation or test execution.
Linking a plan to a milestone
Open the plan detail. Members see a Milestone selector in the summary rail on the right. Select a milestone from the dropdown to link the plan; select No milestone to clear the link. The change is saved immediately.
The available milestones are the live milestones in the plan’s project. A milestone from another project cannot be selected.
Viewers see the linked milestone name (or ”—”) as read-only text in the rail.
When a milestone is deleted
If a linked milestone is deleted, the plan’s milestone link is automatically cleared. The plan itself is preserved.
Independence from run milestones
The plan’s milestone link is independent of the milestone set on the runs created from it. Creating a run from a plan-with-a-milestone does not automatically stamp that milestone onto the new run. Each run’s milestone is set separately in the New test run modal.
Permissions
| Action | Viewer | Member |
|---|---|---|
| View the plans list | Yes | Yes |
| View a plan detail | Yes | Yes |
| View the case selection | Yes | Yes |
| View case assignees | Yes | Yes |
| View status, progress, and milestone | Yes | Yes |
| Create a plan | No | Yes |
| Edit a plan | No | Yes |
| Delete a plan | No | Yes |
| Edit the case selection | No | Yes |
| Assign cases in Edit selection | No | Yes |
| Change inline case assignee in Selection tab | No | Yes |
| Change the plan status | No | Yes |
| Set or clear the milestone link | No | Yes |
| Create a run | No | Yes |
Configuration matrix
The configuration matrix declares which configuration combinations this plan intends to cover. It is a coverage checklist, not a generator: it never creates runs on its own. When you select values across multiple groups — for example, Chrome and Firefox from a Browser group, plus Windows and macOS from an OS group — the plan computes a combination grid, and you create a run for each combination when you are ready to test it.
If no configuration values are selected the plan still works: runs created from it simply carry no configuration.
See Configurations for how to set up configuration groups and values in your project.
Selecting values per group
The Configuration matrix tab in the plan detail view lists every configuration group defined in the project. For each group, use the checkboxes to select which values you want this plan to cover.
- Checking a value adds it to the plan’s configuration selection for that group.
- Unchecking a value removes it. The combination grid updates immediately.
- Groups where no value is selected do not participate in the cartesian product.
The combination grid
Once at least one value is selected, a Combinations grid appears below the value selectors. Each row in the grid represents one candidate combination — the cross-product of all selected values across all participating groups.
| Column | Description |
|---|---|
| Combination | The set of values for this combination (one per participating group) |
| Run | A link to the most recent run covering this combination, plus a read-only ×N count when more than one covers it. Pending when none does yet, — when excluded |
| Include / Exclude | Toggle whether this combination is part of the plan’s intended coverage |
The ×N count is informational only — it is not a link or a button, and clicking it does nothing. For a per-combination breakdown of results, use the Progress tab.
Every combination starts as included. The grid shows only combinations that result from your current value selection; it updates live as you add or remove values.
Excluding specific combinations
To declare that a combination will not be tested, click Exclude on that row. The row is marked as excluded, its Run column shows —, and it offers no create action. Click Include on the same row to restore it.
You can exclude as many combinations as you like. The coverage count below the grid reflects only the included combinations.
The coverage count
Below the combination grid the plan shows the size of its intended coverage:
- N combinations to cover — the included combinations.
- No configuration selected — runs from this plan carry no configuration — shown when no values are checked.
- No combinations to cover — include at least one — shown when every combination is excluded.
Creating a run for a combination
Each pending row carries a New run action. Clicking it opens the New test run modal with the plan and that combination already filled in, so the run you create is tagged with exactly that configuration. A row that already has a run keeps its New run action too — re-testing a combination after a fix is a normal flow, and the row then shows the newest run plus the ×N count.
Creating a run never happens implicitly: the matrix declares intent, and you decide when each combination actually gets executed.
Each run snapshots the plan’s current case selection. Future edits to the plan — changing values, excluding combinations, or updating the case selection — do not affect runs that already exist.