Adjuntos de resultado
Un resultado (un intento de un caso de ejecución) puede llevar hasta 20 archivos de casi cualquier tipo: capturas de pantalla, trazas de Playwright, vídeos, logs. Súbelos en dos pasos: prepara los archivos y luego confirma la lista de adjuntos del resultado. Un adjunto pertenece al resultado completo o, con stepIndex, a uno de los pasos que un reporte de CI envió con él (Adjuntar a un paso reportado); para las imágenes que un tester añade a un paso del caso mientras ejecuta, consulta Adjuntos de resultado de ejecución.
El acceso requiere member+ en el proyecto de la ejecución; un viewer recibe 403 forbidden. Las escrituras siguen la misma regla de ejecución cerrada que el resto de escrituras de resultados: se permiten en una ejecución open, y en una ejecución closed no abortada mientras la configuración de ejecución allowResultsInClosedRuns del proyecto resuelva a true (el valor por defecto). Una ejecución aborted siempre responde 409 conflict. Cuando el proyecto reserva los resultados al asignado (assigneeResultLock), quien no es el tester asignado recibe 403 run_case_assignee_locked; los tokens de API nunca están exentos.
- Obtén el resultado. Un reporte de CI contesta cada entrada emparejada con su
resultUlid(results[i].resultUliddePOST /api/v1/projects/{projectId}/reports).GET /api/v1/runs/{runUlid}/resultslista todos los resultados de una ejecución. - Preparar —
POST /api/v1/runs/{runUlid}/results/{resultUlid}/attachments:stageconmultipart/form-datay una o más partesfile. Devuelve una referencia preparada por archivo. Todavía no se adjunta nada ni se cobra almacenamiento. - Confirmar —
PATCH /api/v1/runs/{runUlid}/results/{resultUlid}/attachmentscon la lista completa del resultado, cada elemento con suposition. Devuelve la lista confirmada. - Leer —
GET /api/v1/runs/{runUlid}/results/{resultUlid}devuelveresultAttachments, ordenados porposition: los archivos confirmados y las imágenes de los textos del resultado (ver la sección Imágenes en el texto).
Un archivo preparado que nunca se confirma caduca por sí solo (unas 48 horas). Por eso reintentar una preparación es seguro; las peticiones de preparación ignoran la cabecera Idempotency-Key. La confirmación y el borrado sí la aceptan.
Preparar (multipart)
Sección titulada «Preparar (multipart)»Mantén el cuerpo completo de la petición en 64 MiB como máximo (ATTACHMENT_UPLOAD_REQUEST_RECOMMENDED_MAX_BYTES) y reparte los lotes más grandes en varias peticiones. Cloudflare rechaza un cuerpo de más de 100 MB con 413 antes de que llegue a la API, permitan lo que permitan los límites por archivo y por petición; ese 413 no lleva el envoltorio de error de la API.
curl -sS -X POST \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -F "file=@screenshot.png" \ -F "file=@trace.zip" \ "https://app.probara.net/api/v1/runs/$RUN/results/$RESULT/attachments:stage"{ "attachments": [ { "ulid": "01J...ATT1", "objectKey": "staging/01J...ORG/01J...UPLOAD1.webp", "thumbKey": "staging/01J...ORG/01J...UPLOAD1_thumb.webp", "mime": "image/webp", "byteSize": 8420, "originalFilename": "screenshot.png", "disposition": "inline", "width": 1280, "height": 720 }, { "ulid": "01J...ATT2", "objectKey": "staging/01J...ORG/01J...UPLOAD2.zip", "thumbKey": null, "mime": "application/zip", "byteSize": 1048576, "originalFilename": "trace.zip", "disposition": "attachment", "width": null, "height": null } ]}Límites:
- Hasta 20 partes
filepor petición. Los archivos vacíos se rechazan. - Cualquier tipo salvo ejecutables y scripts (
application/x-msdownload,application/x-msdos-program,application/x-sh,application/x-bat,application/x-msi,application/x-executable,application/vnd.microsoft.portable-executable), comprobado contra el tipo de contenido declarado de cada parte. - Las imágenes PNG, JPEG y WebP (según el tipo de contenido declarado) se convierten a WebP con miniatura y vuelven con
disposition: "inline". Tienen un límite de 10 MiB y 8192 px por lado. - Cualquier otro archivo se guarda tal cual, hasta 32 MiB, con
disposition: "attachment".
La primera parte inválida rechaza la petición entera con 422 validation_failed: no vuelve ninguna referencia, ni siquiera de las partes anteriores (esas caducan como cualquier otro archivo preparado sin referenciar). El message del error es empty_file, denied_type o file_too_large, que también cubre una imagen que supera el límite de píxeles o cuya cabecera no se puede leer. Valida los archivos antes de subirlos, o reintenta los archivos restantes de uno en uno por petición para que un archivo malo no retenga a los demás.
Antes de que exista el resultado
Sección titulada «Antes de que exista el resultado»Un cliente que sube evidencias antes de registrar el resultado puede preparar contra el caso de ejecución: POST /api/v1/runs/{runUlid}/cases/{runCaseUlid}/result-attachments:stage. Acepta el mismo cuerpo, tiene los mismos límites y devuelve las mismas referencias. Rechaza cualquier ejecución cerrada con 409 conflict, sea cual sea la configuración. Confirma las referencias en el resultado cuando exista.
Confirmar (reemplaza la lista)
Sección titulada «Confirmar (reemplaza la lista)»El cuerpo es la lista completa de adjuntos del resultado. Los archivos confirmados que falten se borran, así que reenvía cada archivo existente como { ulid, position } para conservarlo. Un elemento nuevo es una referencia preparada más su position.
{ "attachments": [ { "ulid": "01J...KEEP", "position": 0 }, { "ulid": "01J...ATT2", "position": 1, "objectKey": "staging/01J...ORG/01J...UPLOAD2.zip", "mime": "application/zip", "byteSize": 1048576, "originalFilename": "trace.zip", "disposition": "attachment", "thumbKey": null, "width": null, "height": null } ]}- Un elemento nuevo necesita al menos
ulid,position,objectKeyyoriginalFilename; lo más sencillo es enviar la referencia preparada tal cual másposition. - Un resultado admite como máximo 20 adjuntos. La confirmación es todo o nada: una confirmación rechazada no cambia nada.
{ "attachments": [] }elimina todos los adjuntos del resultado.- Un elemento puede llevar
stepIndexpara adjuntar el archivo a un paso reportado; ver abajo. - Un token de aplicación solo puede añadir: un cuerpo que deja fuera un adjunto que el resultado ya tiene responde
403 forbiddeny no cambia nada. Un token de aplicación no puede preparar contra el caso de ejecución ni eliminar un adjunto. - Los bytes confirmados cuentan para la cuota de almacenamiento de la organización (categoría
result_attachment); los preparados no. Una confirmación cuyo crecimiento superaría la cuota responde413 storage_quota_exceeded.
Adjuntar a un paso reportado
Sección titulada «Adjuntar a un paso reportado»Un resultado registrado por un reporte de CI puede
llevar los pasos que ejecutó (los steps de la entrada). Para adjuntar un archivo a uno de ellos,
añade al elemento stepIndex: el índice del paso en un recorrido en profundidad y en preorden de los
pasos tal como se enviaron, desde 0 — la position del paso en resultSteps de la
instantánea del intento.
{ "attachments": [ { "ulid": "01J...KEEP", "position": 0 }, { "ulid": "01J...SHOT", "position": 1, "stepIndex": 3, "objectKey": "staging/01J...ORG/01J...UPLOAD3.webp", "originalFilename": "pay.png" } ]}stepIndex en el elemento | Elemento nuevo | Adjunto existente |
|---|---|---|
| Omitido | Se adjunta al resultado | Conserva su paso actual |
null | Se adjunta al resultado | Vuelve al resultado |
| Un número | Se adjunta a ese paso | Se mueve a ese paso |
- El índice debe nombrar un paso de este resultado. Si no, toda la confirmación responde
422 validation_failedy no se escribe nada. - Los adjuntos de pasos cuentan para el mismo límite de 20 archivos por resultado.
- La respuesta de la confirmación,
resultAttachmentsde la instantánea del intento y el detalle del caso de la ejecución devuelven elstepIndexde cada adjunto (nullpara un archivo del resultado). Reenvíalo tal cual al confirmar de nuevo la lista, u omítelo para conservarlo.
Borrar un adjunto
Sección titulada «Borrar un adjunto»curl -sS -X DELETE \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://app.probara.net/api/v1/runs/$RUN/results/$RESULT/attachments/$ATT"204 si tiene éxito. Borrar un adjunto que ya no existe también responde 204.
Errores
Sección titulada «Errores»| Estado | Código | Cuándo |
|---|---|---|
| 403 | forbidden | Rol viewer; o un token de aplicación cuya confirmación eliminaría un adjunto, o que llama a una operación distinta de preparar y confirmar a nivel de resultado |
| 403 | run_case_assignee_locked | El proyecto reserva los resultados al asignado y quien llama no es el tester asignado (operaciones sobre el resultado) |
| 403 | project_locked | El proyecto está bloqueado |
| 404 | not_found | Ejecución, resultado o caso de ejecución desconocido, o de otra organización |
| 409 | conflict | La ejecución está abortada, o cerrada con allowResultsInClosedRuns a false; la preparación sobre el caso rechaza toda ejecución cerrada |
| 409 | staging_already_committed | Solo confirmación: una referencia preparada ya se confirmó |
| 409 | project_archived | El proyecto está archivado |
| 413 | — | Solo preparación: el cuerpo de la petición supera los 100 MB; Cloudflare lo rechaza antes de que llegue a la API, sin el envoltorio de error |
| 413 | storage_quota_exceeded | Solo confirmación: se superaría la cuota de almacenamiento de la organización |
| 415 | unsupported_media_type | Solo confirmación: el cuerpo no es application/json |
| 422 | validation_failed | Preparación: sin parte file, demasiados archivos, un archivo vacío o demasiado grande, una imagen que supera el límite de píxeles, o un tipo denegado; una parte inválida rechaza la petición entera. Confirmación: cuerpo inválido, más de 20 adjuntos, una referencia preparada inválida o caducada, o un stepIndex que no nombra ningún paso del resultado |
| 429 | too_many_requests | El límite de peticiones de API de la organización; espera Retry-After segundos |
Imágenes en el texto
Sección titulada «Imágenes en el texto»La lista resultAttachments también incluye las imágenes insertadas en los textos del resultado, junto con sus archivos. Cada imagen tiene kind image y los campos de una subida (ulid, mime, width, height, byteSize, createdAt), más field, que indica en qué texto está:
{ "kind": "description" },{ "kind": "precondition" }o{ "kind": "postcondition" }para los textos del caso que el intento congeló con su encabezado.{ "kind": "step_actual_result", "runCaseStepUlid": "01J...", "position": 2 }para el resultado real de un paso.{ "kind": "notes" }para las notas del resultado.
Los archivos conservan kind file. Una imagen sale de la lista cuando sale de su texto.
Relacionado
Sección titulada «Relacionado»- Resultados reales de los pasos — el texto y las imágenes insertadas del resultado de un paso
- Configuración de ejecución —
allowResultsInClosedRunsyassigneeResultLock - Referencia interactiva v1 — esquemas completos