API de planes de prueba
Los planes de prueba son colecciones de casos de prueba seleccionados dentro de un proyecto. Cada plan contiene una selección ordenada de casos activos; desde esa selección puedes generar una ejecución de prueba que toma una instantánea de los casos en el momento de la generación. Cada plan tiene un ULID asignado por el servidor, un número de plan asignado de forma monotónica dentro del proyecto y una descripción opcional.
/api/v1/projects/{projectId}/plans{projectId} es el código del proyecto (por ejemplo, ACME).
Cuerpo de la solicitud
Sección titulada «Cuerpo de la solicitud»| Campo | Requerido | Notas |
|---|---|---|
name | sí | Cadena no vacía, máximo 200 caracteres. Debe ser único entre los planes activos del proyecto |
description | no | Descripción en texto libre, máximo 2000 caracteres |
status | no | Estado inicial: draft, active o completed. Por defecto es draft si se omite |
Los campos ulid o planNumber provistos por el cliente son rechazados. Un nombre duplicado entre planes activos del proyecto devuelve 409 conflict. Campos faltantes o inválidos devuelven 422 validation_failed.
Respuesta
Sección titulada «Respuesta»201 con el objeto del plan creado. Ver Campos de respuesta.
Ejemplo
Sección titulada «Ejemplo»curl -sS -X POST \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Sprint 24","description":"Lanzamiento de funcionalidad"}' \ "https://probara.net/api/v1/projects/ACME/plans"/api/v1/projects/{projectId}/plansDevuelve los planes activos (no eliminados) del proyecto, ordenados por número de plan ascendente. Paginación por página.
Parámetros de consulta
Sección titulada «Parámetros de consulta»| Parámetro | Notas |
|---|---|
page | Número de página (base 1, valor predeterminado 1) |
pageSize | Elementos por página (predeterminado 20, máximo 200) |
Respuesta
Sección titulada «Respuesta»200 con { items, page, pageSize, total }. Cada elemento sigue la estructura de respuesta.
Ejemplo
Sección titulada «Ejemplo»curl -sS \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/projects/ACME/plans?page=1&pageSize=20"Obtener
Sección titulada «Obtener»/api/v1/plans/{planUlid}Devuelve un plan activo perteneciente a la organización activa, incluyendo el conteo actual de casos.
Devuelve 404 not_found cuando el plan está fuera de la organización activa o ha sido eliminado.
Ejemplo
Sección titulada «Ejemplo»curl -sS \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000"Actualizar
Sección titulada «Actualizar»/api/v1/plans/{planUlid}Actualiza uno o más campos de un plan activo. Se debe proporcionar al menos un campo. Un nombre duplicado devuelve 409 conflict.
Cuerpo de la solicitud
Sección titulada «Cuerpo de la solicitud»| Campo | Requerido | Notas |
|---|---|---|
name | no | Nuevo nombre (máximo 200 caracteres). Debe ser único entre planes activos del proyecto |
description | no | Descripción actualizada (máximo 2000 caracteres). Enviar null para borrarla |
status | no | Nuevo estado del ciclo de vida: draft, active o completed. Cualquier transición entre estados distintos es válida. Enviar el estado actual del plan es un no-op (aceptado, sin evento). Un valor de estado inválido devuelve 422 validation_failed |
milestoneId | no | ULID de un hito activo del mismo proyecto para vincular, o null para borrar el vínculo existente. Un ULID que no corresponde a un hito activo del proyecto del plan devuelve 404 not_found y deja el plan sin cambios. Un hito de otro proyecto u organización también es 404 not_found |
Un cuerpo vacío (sin campos) devuelve 422 validation_failed.
Respuesta
Sección titulada «Respuesta»200 con el objeto del plan actualizado. Ver Campos de respuesta.
Reglas de transición de estado
Sección titulada «Reglas de transición de estado»- Todas las transiciones entre
draft,activeycompletedson válidas en cualquier dirección. - No hay estados terminales: un plan
completedpuede volver aactiveodraft. - Un PATCH con el mismo valor de estado (el campo
statuscoincide con el estado actual del plan) se acepta como no-op — no se registra ningún cambio de estado y el plan devuelve200sin modificaciones. - Un valor de estado inválido (que no sea uno de los tres valores válidos) devuelve
422 validation_failed. - El estado es estrictamente manual: la API nunca avanza el estado de un plan automáticamente según el estado de sus ejecuciones.
Ejemplos
Sección titulada «Ejemplos»# Cambiar el estado a activocurl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"status":"active"}' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000"# Vincular un hitocurl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"milestoneId":"01HZMILESTONE0000000000000"}' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000"# Borrar el vínculo de hitocurl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"milestoneId":null}' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000"# Combinado: renombrar y marcar como completadocurl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Sprint 25 Final","status":"completed"}' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000"Eliminar
Sección titulada «Eliminar»/api/v1/plans/{planUlid}Elimina el plan de forma lógica. El plan deja de aparecer en la lista y su nombre queda disponible para reutilizarse. Las ejecuciones generadas a partir del plan no se ven afectadas.
Devuelve 204 en caso de éxito, 404 not_found si no se encuentra.
Ejemplo
Sección titulada «Ejemplo»curl -sS -X DELETE \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000"Reemplazar la selección de casos
Sección titulada «Reemplazar la selección de casos»/api/v1/plans/{planUlid}/casesSemántica de reemplazo total: la selección completa se reemplaza por la lista ordenada de ULIDs de casos proporcionada. Omitir un caso de la lista lo elimina; enviarlo en una posición diferente lo mueve. Envía un array caseUlids vacío para vaciar la selección.
Opcionalmente puedes asignar un miembro del equipo a cada caso en la misma llamada enviando caseAssignees. Las entradas cuyo caseUlid no aparezca en caseUlids se ignoran silenciosamente. La resolución de todos los responsables ocurre antes de que se reemplace la selección: un assigneeUlid inválido deja la selección actual sin cambios.
Cuerpo de la solicitud
Sección titulada «Cuerpo de la solicitud»| Campo | Requerido | Notas |
|---|---|---|
caseUlids | sí | Array ordenado de ULIDs de casos activos. Los ULIDs duplicados son rechazados (422). Los casos deben pertenecer al proyecto del plan |
caseAssignees | no | Array de pares { caseUlid, assigneeUlid }. Cada assigneeUlid debe ser miembro de la organización activa — un assigneeUlid de otra organización devuelve 404 not_found y deja la selección sin cambios. Las entradas cuyo caseUlid no aparezca en caseUlids se ignoran. Omitir este campo (o no incluir una entrada para un caso en particular) almacena ese caso sin responsable |
Devuelve 404 not_found si algún ULID no corresponde a un caso activo del proyecto o si algún assigneeUlid no es miembro de la organización. Devuelve 422 validation_failed por ULIDs duplicados.
Respuesta
Sección titulada «Respuesta»200 con { items } — la nueva selección en orden de posición. Ver Campos de elemento de selección.
Ejemplo — solo selección de casos
Sección titulada «Ejemplo — solo selección de casos»curl -sS -X PUT \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"caseUlids":["01HZCASEA","01HZCASEB","01HZCASEC"]}' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000/cases"Ejemplo — selección con responsables por caso
Sección titulada «Ejemplo — selección con responsables por caso»curl -sS -X PUT \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "caseUlids": ["01HZCASEA","01HZCASEB","01HZCASEC"], "caseAssignees": [ { "caseUlid": "01HZCASEA", "assigneeUlid": "01HZMEMBER000000000000000001" }, { "caseUlid": "01HZCASEB", "assigneeUlid": "01HZMEMBER000000000000000002" } ] }' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000/cases"01HZCASEC no tiene entrada en caseAssignees y se almacena sin responsable.
Actualizar el responsable de un caso del plan
Sección titulada «Actualizar el responsable de un caso del plan»/api/v1/plans/{planUlid}/cases/{planCaseUlid}Actualiza el responsable de un único caso del plan sin modificar el resto de la selección. Este endpoint es la actualización en línea por caso — no reemplaza la lista de casos del plan.
Semántica de instantánea: actualizar el responsable de un caso del plan no se propaga a ninguna ejecución ya generada desde el plan. Los casos de ejecución existentes conservan el responsable que tenían en el momento en que se generó la ejecución.
Parámetros de ruta
Sección titulada «Parámetros de ruta»| Parámetro | Descripción |
|---|---|
planUlid | ULID del plan |
planCaseUlid | ULID de la fila del caso en el plan (el campo ulid de un elemento de selección, no el ULID del caso de prueba) |
Cuerpo de la solicitud
Sección titulada «Cuerpo de la solicitud»| Campo | Requerido | Notas |
|---|---|---|
assigneeUlid | sí | ULID de un miembro activo de la organización, o null para quitar el responsable |
El cuerpo debe contener exactamente una clave. Las claves desconocidas devuelven 422 validation_failed.
Respuesta
Sección titulada «Respuesta»200 con el objeto del caso del plan actualizado (misma estructura que un elemento de selección). Ver Campos de elemento de selección.
Códigos de error
Sección titulada «Códigos de error»| Estado | Código | Cuándo |
|---|---|---|
403 Forbidden | — | El llamante tiene rol viewer |
404 Not Found | not_found | planUlid o planCaseUlid no existe o pertenece a otra organización |
404 Not Found | not_found | assigneeUlid no corresponde a un miembro activo de la organización |
422 Unprocessable Entity | validation_failed | Clave assigneeUlid faltante, valor que no es ULID, o clave desconocida |
Ejemplo
Sección titulada «Ejemplo»# Asignar un responsable a un caso del plancurl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"assigneeUlid":"01HZMEMBER000000000000000001"}' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000/cases/01HZPLANCASE000000000000000"
# Quitar el responsable (enviar null)curl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"assigneeUlid":null}' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000/cases/01HZPLANCASE000000000000000"Listar la selección de casos
Sección titulada «Listar la selección de casos»/api/v1/plans/{planUlid}/casesDevuelve la selección actual de casos del plan, ordenada por posición ascendente.
Respuesta
Sección titulada «Respuesta»200 con { items }. Ver Campos de elemento de selección.
Ejemplo
Sección titulada «Ejemplo»curl -sS \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000/cases"Reemplazar la selección de configuraciones
Sección titulada «Reemplazar la selección de configuraciones»/api/v1/plans/{planUlid}/configurationsSemántica de reemplazo total: la selección completa de configuraciones del plan se reemplaza por la lista de ULIDs de valores de configuración proporcionada. Envía un array configurationUlids vacío para vaciar la selección.
Cada ULID proporcionado debe corresponder a un valor de configuración activo (no eliminado) en el proyecto del plan. Un ULID no resuelto, eliminado de forma lógica o de otro proyecto devuelve 404 not_found y deja la selección sin cambios. Los ULIDs duplicados en la solicitud devuelven 422 validation_failed.
Cuerpo de la solicitud
Sección titulada «Cuerpo de la solicitud»| Campo | Requerido | Notas |
|---|---|---|
configurationUlids | sí | Array de ULIDs de valores de configuración activos. Los duplicados son rechazados (422). Los valores deben pertenecer al proyecto del plan |
Respuesta
Sección titulada «Respuesta»200 con { items } — la nueva selección de configuraciones. Ver Campos de elemento de configuración.
Ejemplo
Sección titulada «Ejemplo»curl -sS -X PUT \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"configurationUlids":["01HZCHROME000000000000000000","01HZWINDOWS00000000000000000"]}' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000/configurations"Listar la selección de configuraciones
Sección titulada «Listar la selección de configuraciones»/api/v1/plans/{planUlid}/configurationsDevuelve la selección de configuraciones actual del plan — el conjunto de ULIDs de valores de configuración que el plan usa para calcular su matriz de combinaciones.
Respuesta
Sección titulada «Respuesta»200 con { items }. Ver Campos de elemento de configuración.
Ejemplo
Sección titulada «Ejemplo»curl -sS \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000/configurations"Establecer combinaciones excluidas
Sección titulada «Establecer combinaciones excluidas»/api/v1/plans/{planUlid}/excluded-combinationsSemántica de reemplazo total: las claves de combinación excluidas del plan se reemplazan exactamente por el conjunto proporcionado. Una comboKey que no coincide con ninguna combinación candidata actual es aceptada y almacenada como exclusión inerte — no genera un error.
Cuerpo de la solicitud
Sección titulada «Cuerpo de la solicitud»| Campo | Requerido | Notas |
|---|---|---|
comboKeys | sí | Array de cadenas de clave de combinación. Una clave de combinación es la lista de ULIDs de valores de configuración de la combinación, ordenados de forma ascendente y unidos con : (por ejemplo, 01HZCHROME:01HZWINDOWS). Los duplicados son rechazados (422). Envía un array vacío para borrar todas las exclusiones |
Respuesta
Sección titulada «Respuesta»200 con { comboKeys } — el nuevo conjunto de claves de combinación excluidas del plan.
Ejemplo
Sección titulada «Ejemplo»curl -sS -X PUT \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"comboKeys":["01HZFIREFOX0000000000000000:01HZWINDOWS00000000000000000"]}' \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000/excluded-combinations"Vista previa de combinaciones
Sección titulada «Vista previa de combinaciones»/api/v1/plans/{planUlid}/combinationsDevuelve las combinaciones candidatas calculadas como el producto cartesiano de la selección de configuraciones actual del plan (un valor por grupo participante). Cada combinación incluye su comboKey, los valores por grupo ordenados por posición de grupo, y un indicador included (false cuando la comboKey está en el conjunto de excluidas del plan). La respuesta también devuelve el total de combinaciones candidatas y el conteo de combinaciones incluidas.
Un plan sin selección de configuraciones devuelve exactamente una combinación candidata (la combinación vacía, totalCount = 1, includedCount = 1).
Respuesta
Sección titulada «Respuesta»200 con:
| Campo | Tipo | Notas |
|---|---|---|
items | array | Objetos de combinación candidata. Ver Campos de elemento de combinación |
totalCount | number | Número total de combinaciones candidatas (incluyendo las excluidas) |
includedCount | number | Número de combinaciones con included = true |
Ejemplo
Sección titulada «Ejemplo»curl -sS \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/plans/01HZPLANULID00000000000000/combinations"Crear una ejecución para un plan
Sección titulada «Crear una ejecución para un plan»No existe POST /api/v1/plans/{planUlid}/runs. Para crear una ejecución para un
plan, usa POST /api/v1/projects/{projectId}/runs, pasando planUlid y, si el
plan tiene configuraciones, los configurationUlids de la combinación. Esta
llamada siempre crea exactamente una ejecución — vincula un plan, siembra sus
casos y etiqueta una combinación, todo en una sola solicitud. Para cubrir varias
combinaciones, llama una vez por combinación.
Cuando se envía planUlid y se omite caseUlids, la selección de casos de la
ejecución y sus responsables por caso se siembran desde la selección actual del
plan, siguiendo esta precedencia (gana la primera coincidencia):
- Una entrada explícita por caso en
caseAssignees(del cuerpo de la solicitud) - El responsable almacenado por caso en el plan para ese caso
defaultAssigneeUliddel cuerpo de la solicitud- Sin responsable (
null)
Un responsable del plan que ya no es miembro de la organización en el momento de
la solicitud resulta en null (sin responsable) sin que la solicitud falle.
curl -sS -X POST \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Smoke — Chrome","planUlid":"01HZPLANULID00000000000000","configurationUlids":["01HZCFGVALCHROME0000000000"]}' \ "https://probara.net/api/v1/projects/PROJ/runs"Las ejecuciones del plan se listan de la más reciente a la más antigua mediante
GET /api/v1/plans/{planUlid}/runs.
Campos de respuesta
Sección titulada «Campos de respuesta»El detalle del plan (GET /api/v1/plans/{planUlid}) y la respuesta del PATCH devuelven el objeto completo del plan. La lista de planes (GET /api/v1/projects/{projectId}/plans) devuelve la misma estructura por elemento pero omite progress.
| Campo | Tipo | Notas |
|---|---|---|
ulid | string | ULID asignado por el servidor para el plan |
projectUlid | string | ULID del proyecto al que pertenece el plan |
planNumber | number | Número asignado de forma monotónica dentro del proyecto |
name | string | Nombre del plan |
description | string | null | Descripción opcional |
author | object | null | Instantánea de autoría (ver más abajo). null para registros heredados |
caseCount | number | Cantidad actual de casos activos en la selección |
status | string | Estado actual del ciclo de vida: draft, active o completed |
milestoneUlid | string | null | ULID del hito vinculado, o null cuando no hay hito vinculado |
milestone | object | null | Referencia al hito vinculado ({ ulid, name }), o null cuando no hay hito vinculado |
progress | object | Resumen de progreso calculado (solo en el detalle y en la respuesta del PATCH — ver más abajo) |
createdAt | number | Marca de tiempo de creación (milisegundos epoch Unix) |
updatedAt | number | Marca de tiempo de última actualización (milisegundos epoch Unix) |
Campos de autor
Sección titulada «Campos de autor»| Campo | Tipo | Notas |
|---|---|---|
kind | "user" | "api_token" | Cómo fue creado el plan |
ulid | string | ULID del usuario o token de API |
displayName | string | Nombre para mostrar (solo tipo usuario) |
avatarKey | string | null | Clave del objeto de avatar (solo tipo usuario) |
name | string | Nombre del token (solo tipo api_token) |
Campos de progreso
Sección titulada «Campos de progreso»progress se calcula en el momento de la lectura a partir de las ejecuciones del plan. Está presente en el detalle del plan (GET /api/v1/plans/{planUlid}) y en la respuesta del PATCH. La lista de planes no incluye progress.
| Campo | Tipo | Notas |
|---|---|---|
totalRuns | number | Número total de ejecuciones generadas desde este plan |
closedRuns | number | Cantidad de esas ejecuciones que están en estado closed |
counts | object | Conteos de resultados generales sumados de todas las ejecuciones del plan (ver más abajo) |
byConfiguration | array | Filas del desglose por configuración (ver más abajo). Vacío cuando el plan no tiene ejecuciones |
Conteos de resultados (counts y counts por fila de desglose)
Sección titulada «Conteos de resultados (counts y counts por fila de desglose)»| Campo | Tipo | Notas |
|---|---|---|
passed | number | Suma de resultados pasados |
failed | number | Suma de resultados fallidos |
blocked | number | Suma de resultados bloqueados |
skipped | number | Suma de resultados omitidos |
untested | number | Suma de resultados sin probar (pendientes) |
Estos valores se suman a partir de los contadores por estado que se mantienen en cada fila de test_run. No se hace un re-análisis de los resultados individuales en el momento de la lectura.
Desglose por configuración (elementos de byConfiguration)
Sección titulada «Desglose por configuración (elementos de byConfiguration)»Cada elemento de byConfiguration corresponde a una combinación de configuración (o al grupo sin configuración):
| Campo | Tipo | Notas |
|---|---|---|
comboKey | string | Clave de combinación: los ULIDs de valores de configuración de la ejecución ordenados de forma ascendente y unidos con :. Cadena vacía ("") para el grupo sin configuración (ejecuciones sin etiquetas de configuración) |
values | array | Entradas de valor por grupo ordenadas ({ groupName, valueName }). Array vacío para el grupo sin configuración |
totalRuns | number | Número de ejecuciones en esta combinación |
closedRuns | number | Número de esas ejecuciones que están cerradas |
counts | object | Conteos de resultados para esta combinación (misma estructura que counts a nivel general) |
La suma de todos los byConfiguration[*].counts es igual al counts de nivel general. Las ejecuciones sin etiquetas de configuración aparecen en un único grupo sin configuración (con comboKey vacío y values vacío).
Campos de elemento de selección
Sección titulada «Campos de elemento de selección»Devueltos por GET /plans/{planUlid}/cases y PUT /plans/{planUlid}/cases.
| Campo | Tipo | Notas |
|---|---|---|
ulid | string | ULID asignado por el servidor para la fila de selección |
caseUlid | string | ULID del caso de prueba referenciado |
displayId | string | ID de visualización del caso (por ejemplo, TC-42) |
title | string | Título actual del caso de prueba |
suiteName | string | null | Nombre del conjunto para agrupar, o null |
position | number | Posición dentro de la selección del plan (base 0) |
assigneeUlid | string | null | ULID del miembro asignado a este caso en el plan, o null cuando el caso no tiene responsable |
Campos de elemento de configuración
Sección titulada «Campos de elemento de configuración»Cada elemento en las respuestas de GET /plans/{planUlid}/configurations y PUT /plans/{planUlid}/configurations:
| Campo | Tipo | Notas |
|---|---|---|
configurationUlid | string | ULID del valor de configuración |
groupUlid | string | ULID del grupo de configuración al que pertenece este valor |
groupName | string | Nombre del grupo (por ejemplo, Navegador) |
valueName | string | Nombre del valor (por ejemplo, Chrome) |
Campos de elemento de combinación
Sección titulada «Campos de elemento de combinación»Cada elemento en la respuesta de GET /plans/{planUlid}/combinations:
| Campo | Tipo | Notas |
|---|---|---|
comboKey | string | Clave de combinación determinista: los ULIDs de valores de configuración de la combinación ordenados de forma ascendente y unidos con :. Usa esta clave en PUT /excluded-combinations para excluir la combinación |
values | array | Entradas de valor por grupo, ordenadas por posición de grupo. Cada entrada contiene groupUlid, groupName, configurationUlid y valueName |
included | boolean | true cuando esta combinación no está en el conjunto de excluidas del plan; false cuando está excluida |