Ir al contenido

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.

GET /api/v1/runs/{runUlid}/cases

Requiere viewer+ en el proyecto de la ejecución. Devuelve 404 si la ejecución está fuera de la organización del llamador.

Cada elemento del array cases incluye los campos habituales más:

CampoTipoDescripción
caseLifecycleStatusobject | nullEl 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[].optionSystemKeystring | nullLa 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.

Cuando no es null, el objeto tiene la misma forma que un CustomFieldValueEntry:

CampoTipoDescripción
optionUlidstringULID de la opción de ciclo de vida seleccionada
optionNamestringNombre de la opción
optionColorstring | nullColor hexadecimal, si existe
optionIconstring | nullIdentificador de icono, si existe
optionSystemKeystring | nullClave de sistema: status_active, status_draft, status_deprecated, o null para opciones personalizadas

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).

Ventana de terminal
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}/cases

Reconcilia 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.

{
"caseUlids": ["01J...A", "01J...B", "01J...D"],
"caseAssignees": [{ "caseUlid": "01J...D", "assigneeUlid": "01J...USER" }]
}
CampoTipoDescripción
caseUlidsstring[]La selección completa deseada (ULIDs de caso fuente). Un array vacío es válido — elimina todos los casos de la ejecución.
caseAssigneesarray (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 caseUlids que 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 caso DELETE /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.

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.

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.

Ventana de terminal
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"