API de casos de ejecución
GET /api/v1/runs/{runUlid}/cases devuelve todos los casos que pertenecen a
una ejecución abierta o cerrada. Se añadieron dos campos como
extensiones aditivas y compatibles con versiones anteriores — las
integraciones existentes que ignoran claves desconocidas no se ven afectadas.
Listar casos de una ejecución
Sección titulada «Listar casos de una ejecución»GET /api/v1/runs/{runUlid}/casesRequiere viewer+ en el proyecto de la ejecución. Devuelve 404 si la
ejecución está fuera de la organización del llamador.
Forma de la respuesta (por elemento)
Sección titulada «Forma de la respuesta (por elemento)»Cada elemento del array cases incluye los campos habituales más:
| Campo | Tipo | Descripción |
|---|---|---|
caseLifecycleStatus | object | null | El estado del ciclo de vida actual (en tiempo real, no del snapshot) del caso fuente. null cuando el campo de estado no está configurado o el caso fuente fue eliminado. |
customFieldValues[].optionSystemKey | string | null | La clave de sistema propia de la opción (p. ej. status_active, status_draft). null para opciones personalizadas definidas por el usuario y para tipos de campo no selectores. |
Objeto caseLifecycleStatus
Sección titulada «Objeto caseLifecycleStatus»Cuando no es null, el objeto tiene la misma forma que un CustomFieldValueEntry:
| Campo | Tipo | Descripción |
|---|---|---|
optionUlid | string | ULID de la opción de ciclo de vida seleccionada |
optionName | string | Nombre de la opción |
optionColor | string | null | Color hexadecimal, si existe |
optionIcon | string | null | Identificador de icono, si existe |
optionSystemKey | string | null | Clave de sistema: status_active, status_draft, status_deprecated, o null para opciones personalizadas |
En tiempo real vs. snapshot
Sección titulada «En tiempo real vs. snapshot»El contenido del caso de prueba (título, pasos, descripción) se
congela en un snapshot cuando el caso se añade a la ejecución — los cambios
en el caso original no afectan ninguna ejecución existente. caseLifecycleStatus
es deliberadamente no un snapshot: se resuelve en tiempo real mediante un
join al caso fuente, por lo que siempre refleja el estado actual del caso en el
repositorio. Si necesitas el estado del snapshot, usa el campo priority
(que sí forma parte del snapshot).
Ejemplo
Sección titulada «Ejemplo»curl -sS \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/runs/01J...RUN/cases"{ "cases": [ { "runCaseUlid": "01J...RC", "caseUlid": "01J...CASE", "caseNumber": 7, "titleSnapshot": "Flujo de pago", "status": "untested", "caseLifecycleStatus": { "optionUlid": "01J...OPT", "optionName": "Borrador", "optionColor": "#F59E0B", "optionIcon": "circle-dashed", "optionSystemKey": "status_draft" }, "customFieldValues": [ { "fieldUlid": "01J...FLD", "fieldName": "Prioridad", "optionUlid": "01J...PRI", "optionName": "Alta", "optionColor": "#EF4444", "optionIcon": null, "optionSystemKey": null } ] } ]}Cuando el caso fuente no tiene estado de ciclo de vida configurado, o el caso fue eliminado:
{ "caseLifecycleStatus": null}Cuando una entrada de customFieldValues pertenece a una opción de sistema (campo de estado del ciclo de vida):
{ "optionSystemKey": "status_active"}Cuando pertenece a una opción personalizada (definida por el usuario):
{ "optionSystemKey": null}Reconciliar la selección de casos de una ejecución
Sección titulada «Reconciliar la selección de casos de una ejecución»PATCH /api/v1/runs/{runUlid}/casesReconcilia la selección de casos de una ejecución a la selección completa
deseada que se envíe, en una sola transacción atómica. A diferencia de
POST /runs/{runUlid}/cases (solo agrega — añade los ULIDs de caso dados y
nunca quita nada), este endpoint trata la ausencia del conjunto deseado como
una eliminación. Ambos endpoints siguen disponibles y no cambian entre sí.
Requiere member+ (el mismo permiso de ejecución que correr los tests);
viewer recibe 403. Permitido en una ejecución abierta o cerrada sin
abortar (completada, o cerrada automáticamente al tener resultado todos sus
casos); rechaza solo una ejecución abortada con 409, sin mutar nada.
Cuerpo de la solicitud
Sección titulada «Cuerpo de la solicitud»{ "caseUlids": ["01J...A", "01J...B", "01J...D"], "caseAssignees": [{ "caseUlid": "01J...D", "assigneeUlid": "01J...USER" }]}| Campo | Tipo | Descripción |
|---|---|---|
caseUlids | string[] | La selección completa deseada (ULIDs de caso fuente). Un array vacío es válido — elimina todos los casos de la ejecución. |
caseAssignees | array (opcional) | Asignado por caso para la selección deseada. Un ULID de caso ausente de este array significa que ese caso queda (o pasa a quedar) sin asignar — no existe un valor explícito de “limpiar”. |
Dada la selección actual y la solicitud anterior, el servidor calcula la diferencia y la aplica, de forma atómica:
- Agrega cada caso de
caseUlidsque aún no está en la ejecución — congelando su título y pasos como un snapshot nuevo,status: "untested", con el asignado provisto (si lo hay) aplicado en la misma operación. - Elimina cada caso actual ausente de
caseUlids— en cascada con sus snapshots de pasos y adjuntos de resultado, igual que el endpoint de un solo casoDELETE /runs/{runUlid}/cases/{runCaseUlid}. - Conserva cada caso presente en ambos, sin cambios (
titleSnapshot,status,assigneeUlid,elapsedMs). - Reasigna cualquier caso conservado cuyo asignado provisto difiera del actual.
La respuesta es el resumen reconciliado de la ejecución (RunResponse), la
misma forma que devuelve cualquier otra mutación de ejecución — no
incluye el array de casos de la ejecución; llama a
GET /runs/{runUlid}/cases para obtener el listado actualizado.
Validación del asignado
Sección titulada «Validación del asignado»Cada assigneeUlid provisto debe resolver a un miembro de la organización de
la ejecución. Un ULID de asignado ajeno a la organización o desconocido
devuelve 404 not_found — igual que el comportamiento existente de la
creación (POST /projects/{projectId}/runs) y del patch por caso
(PATCH /runs/{runUlid}/cases/{runCaseUlid}) para el mismo campo, no un
422 validation_failed. En ese caso no se agrega, elimina ni reasigna ningún
caso.
Eventos de auditoría
Sección titulada «Eventos de auditoría»Emite exactamente un evento por cada caso que realmente cambió:
run.case_added por cada caso agregado, run.case_removed por cada caso
eliminado, run.case_assigned por cada caso cuyo asignado cambió (incluyendo
una limpieza, to: null) — ver API de eventos de auditoría
para las formas compartidas de metadata. Un caso sin cambios tanto en
membresía como en asignado no emite nada. El asignado incorporado de un caso
recién agregado se registra en run.case_added y no emite además un
run.case_assigned.
Ejemplo
Sección titulada «Ejemplo»curl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"caseUlids": ["01J...A", "01J...D"]}' \ "https://probara.net/api/v1/runs/01J...RUN/cases"Relacionado
Sección titulada «Relacionado»- Referencia API — paginación, errores, autenticación
- Referencia interactiva v1 — esquemas completos
- API de búsqueda de casos — búsqueda entre suites con
customFieldValues