Resultados y reintentos de Playwright
Cada playwright test envía sus resultados a una ejecución de Probara: una ejecución automatizada
nueva por defecto, cerrada al final, o una existente. Esta página cubre esa ejecución, el estado de
cada intento, los reintentos y lo que pasa con los resultados que no se pudieron enviar.
Opciones de la ejecución
Sección titulada «Opciones de la ejecución»Estas opciones describen la ejecución que crea el reporter:
reporter: [ [ '@probara/playwright-reporter', { run: { name: 'Nightly regression', description: 'Every night on main, against staging.', environment: 'staging', milestone: 'Sprint 12', plan: 'PLAN-2', configurations: [ { group: 'Browser', name: 'Chromium' }, { group: 'OS', name: 'Linux' }, ], tags: ['nightly', 'e2e'], }, }, ],],| Opción | Variable | Qué define |
|---|---|---|
run.name | PROBARA_RUN_NAME | El nombre. Por defecto: el nombre del build de CI (CI #42), si no Automated run <date> <time> UTC |
run.description | PROBARA_RUN_DESCRIPTION | La descripción, de hasta 2000 caracteres (lo que exceda se recorta, con una advertencia) |
run.environment | PROBARA_ENVIRONMENT | El entorno, por nombre: se crea en el proyecto si no hay ninguno con ese nombre |
run.milestone | PROBARA_MILESTONE | El hito, por ID visible (M-3) o por nombre exacto |
run.plan | PROBARA_PLAN | El plan de prueba, por ID visible (PLAN-2) o por nombre exacto: la ejecución empieza con los casos del plan |
run.configurations | PROBARA_CONFIGURATIONS | Valores de configuración por grupo y nombre (Browser=Chromium,OS=Linux), cada grupo una vez |
run.tags | PROBARA_RUN_TAGS | Etiquetas (nightly,e2e), hasta 50 |
Nombres o ULIDs
Sección titulada «Nombres o ULIDs»El entorno, el hito y las configuraciones también aceptan ULIDs: run.environmentId,
run.milestoneId y run.configurationUlids (PROBARA_ENVIRONMENT_ID, PROBARA_MILESTONE_ID,
PROBARA_CONFIGURATION_ULIDS). Usa una sola forma para cada uno, nunca las dos: las dos a la vez
son un problema de configuración que desactiva el envío. Con un token de aplicación, usa los
nombres: el token no puede consultar ULIDs.
- Un nombre de entorno desconocido crea el entorno.
- Un hito, un plan o una configuración desconocidos hacen que Probara rechace el primer informe
(
422, nombrando el campo): no se registra nada, y el registro explica por qué. Revisa los nombres en Probara.
Origen de la ejecución
Sección titulada «Origen de la ejecución»Una ejecución registra de dónde viene: la rama, el commit y la URL del build de CI, leídos de las variables del CI. Gana el primer proveedor que coincide:
| CI | Se detecta por | Nombre de la ejecución | Rama, commit y URL del build desde |
|---|---|---|---|
| GitHub Actions | GITHUB_ACTIONS=true | GITHUB_WORKFLOW #GITHUB_RUN_NUMBER | GITHUB_HEAD_REF o GITHUB_REF_NAME, GITHUB_SHA, la URL de la ejecución |
| GitLab CI | GITLAB_CI=true | CI_PROJECT_NAME #CI_PIPELINE_IID | CI_MERGE_REQUEST_SOURCE_BRANCH_NAME o CI_COMMIT_REF_NAME, CI_COMMIT_SHA, CI_PIPELINE_URL |
| CircleCI | CIRCLECI=true | CIRCLE_PROJECT_REPONAME #CIRCLE_BUILD_NUM | CIRCLE_BRANCH, CIRCLE_SHA1, CIRCLE_BUILD_URL |
| Azure Pipelines | TF_BUILD=True | BUILD_DEFINITIONNAME #BUILD_BUILDNUMBER | La rama de origen, BUILD_SOURCEVERSION, la URL de los resultados del build |
| Jenkins | JENKINS_URL definida | JOB_NAME #BUILD_NUMBER | BRANCH_NAME o GIT_BRANCH, GIT_COMMIT, BUILD_URL |
| Bitbucket Pipelines | BITBUCKET_BUILD_NUMBER | BITBUCKET_REPO_SLUG #BITBUCKET_BUILD_NUMBER | BITBUCKET_BRANCH, BITBUCKET_COMMIT, la URL del pipeline |
| Buildkite | BUILDKITE=true | BUILDKITE_PIPELINE_SLUG #BUILDKITE_BUILD_NUMBER | BUILDKITE_BRANCH, BUILDKITE_COMMIT, BUILDKITE_BUILD_URL |
Un build de una etiqueta no envía rama. Los valores no válidos se descartan, nunca se envían.
Sustituye un campo con source o con su variable, o no envíes ninguno:
reporter: [['@probara/playwright-reporter', { source: { branch: 'release/2.4' } }]],| Opción | Variable | Por defecto |
|---|---|---|
source.branch | PROBARA_BRANCH | detectado del CI |
source.commit | PROBARA_COMMIT | detectado del CI |
source.buildUrl | PROBARA_BUILD_URL | detectado del CI |
source: false | — | no envía origen |
Una ejecución existente
Sección titulada «Una ejecución existente»run.ulid (PROBARA_RUN_ULID) envía a una ejecución que ya existe, como la que
probara run create crea para los shards de un pipeline
(shards). Las opciones de una ejecución nueva
se ignoran entonces, con una advertencia: la ejecución conserva su propio nombre, entorno, hito y
configuraciones.
Cerrar la ejecución
Sección titulada «Cerrar la ejecución»Una ejecución que crea el reporter se cierra al final, cuando se han enviado todos los resultados y
archivos; una reutilizada queda abierta. closeRun (PROBARA_CLOSE_RUN) decide para cualquier
ejecución. Cuando un informe falla, la ejecución queda abierta: el registro la nombra, y lo que no se
envió puede ir a un archivo de resultados.
Asignar los resultados fallidos
Sección titulada «Asignar los resultados fallidos»assignFailedTo (PROBARA_ASSIGN_FAILED_TO=ana@example.com,bo@example.com) nombra hasta 20
miembros de la organización por email. Cada informe de la ejecución pide a Probara que asigne cada
caso de la ejecución que deja fallido y sin responsable a uno de ellos, por turnos; un caso que ya
tiene responsable lo conserva.
- Los emails se recortan y cuentan una sola vez, sin distinguir mayúsculas. Un valor que no es un email, o más de 20 emails, es un problema de configuración que desactiva el envío.
- Un email que no coincide con ningún miembro asignable en el proyecto no es un error: Probara los cuenta en una advertencia, que el reporter registra sin nombrarlos.
Estados
Sección titulada «Estados»Cada intento se envía con el veredicto de Playwright: lo que hizo el intento comparado con lo que la prueba esperaba.
| El intento | Estado |
|---|---|
| Pasó | passed |
| Falló: una aserción, un error, un hook o un fixture lanzó un error | failed |
| Agotó su tiempo | failed |
Se interrumpió (la ejecución se detuvo: Ctrl+C, --max-failures, un tiempo global) | failed |
test.skip(), test.fixme(), un describe omitido | skipped |
test.fail(), y falló como se esperaba | passed |
test.fail(), pero pasó | failed |
El reporter nunca envía blocked por su cuenta: mapea un estado a él
(abajo) cuando lo necesites.
import { expect, test } from '@playwright/test';
test('passes', async () => {});
test('fails', async () => { expect(1 + 1).toBe(3);});
test('is skipped on CI', async () => { test.skip(true, 'Needs the payment sandbox');});
test.fixme('is not written yet', async () => {});
test('is a known bug', async () => { test.fail(true, 'SHOP-99: totals round down'); expect(0.1 + 0.2).toBe(0.3);});[ { "automationKey": "statuses.spec.ts > passes", "status": "passed" }, { "automationKey": "statuses.spec.ts > fails", "status": "failed" }, { "automationKey": "statuses.spec.ts > is skipped on CI", "status": "skipped", "notes": "Skipped: Needs the payment sandbox" }, { "automationKey": "statuses.spec.ts > is not written yet", "status": "skipped" }, { "automationKey": "statuses.spec.ts > is a known bug", "status": "passed" }]- Los errores van en las notas del resultado: todos los errores del intento, con su mensaje y su stack, después de un comentario si la prueba escribió uno.
- Los motivos de omisión van en las notas como
Skipped: <reason>, la misma línea que escribeprobara import junit, a partir detest.skip(condition, reason)otest.fixme(condition, reason). - Los fallos esperados son los de Playwright: una prueba con
test.fail()que falla hace lo que debe, así que pasa, y la ejecución sigue en verde en Probara igual que en Playwright. Cuando se corrige el bug, la prueba pasa, Playwright la hace fallar, y Probara también, para recordarte que quitestest.fail(). - Los tiempos agotados conservan el mensaje de Playwright (
Test timeout of 30000ms exceeded.) en las notas.
Mapeo y filtro de estados
Sección titulada «Mapeo y filtro de estados»statusMapping envía un estado como otro; statusFilter no envía ningún resultado con los estados
indicados, después del mapeo. Los dos aceptan passed, failed, skipped y blocked:
reporter: [ [ '@probara/playwright-reporter', { statusMapping: { failed: 'blocked' }, statusFilter: ['skipped'] }, ],],Con una prueba que pasa, una que falla y una omitida:
$ npx playwright test[probara] Sending 2 results of 2 tests (1 passed, 0 failed, 0 skipped, 1 blocked); 1 left out by statusFilter[probara] Recorded 2 results (2 new cases, 0 unmatched) in R-1 (closed): https://app.probara.net/projects/SHOP/runs/R-1[probara] Filtered out 1 result by their status (statusFilter): not sent[probara] Attached 1 file to results (0 skipped, 0 failed)Como variables: PROBARA_STATUS_MAPPING=failed=blocked,skipped=passed y
PROBARA_STATUS_FILTER=skipped,blocked. Un valor que no es un estado, o un estado mapeado dos
veces, es un problema de configuración que desactiva el envío. El mapeo solo cambia lo que registra
Probara: el código de salida de Playwright sigue siendo el de las pruebas.
Reintentos y pruebas inestables
Sección titulada «Reintentos y pruebas inestables»Cada intento de una prueba es un resultado propio. Una prueba reintentada dos veces envía tres resultados, en el orden en que se ejecutaron, cada uno con su estado, su duración, sus errores, sus pasos y sus archivos.
// playwright.config.ts (excerpt)retries: 1,import { expect, test } from '@playwright/test';
test('loads the dashboard', async ({}, testInfo) => { // Fails the first time, passes on the retry. expect(testInfo.retry).toBe(1);});[ { "automationKey": "flaky.spec.ts > loads the dashboard", "status": "failed" }, { "automationKey": "flaky.spec.ts > loads the dashboard", "status": "passed" }]$ npx playwright test[probara] Sending 2 results of 1 test (1 passed, 1 failed, 0 skipped, 0 blocked)[probara] Recorded 2 results (1 new case, 0 unmatched) in R-1 (closed): https://app.probara.net/projects/SHOP/runs/R-1[probara] Attached 1 file to results (0 skipped, 0 failed)El archivo es el contexto de error que Playwright escribió para el intento fallido.
- Qué muestra Probara. El caso de la ejecución conserva el último resultado (
passedaquí), y cada intento queda en su historial: una prueba inestable es un caso cuyo historial mezcla fallos y aciertos en la misma ejecución. El registro también lo indica: más resultados que pruebas. - Sin marca de inestable. El reporter no marca los intentos como inestables: los propios intentos son la evidencia, y el veredicto de Playwright (flaky, cuando un reintento pasó) se queda en los informes de Playwright.
- Cada intento empieza vacío. Los metadatos
probara.*se aplican al intento que los definió, así que un reintento que se detiene antes no hereda los metadatos del primer intento. - Orden. Los resultados se envían en el orden en que Playwright termina los intentos; como el caso de la ejecución conserva el último resultado, el reintento final es el que muestra.
Para enviar solo el último intento, filtra en Playwright: ninguna opción del reporter descarta intentos. Para que los fallos de las pruebas reintentadas no cuenten en tus cifras, mapéalos, sabiendo que el mapeo se aplica a todos los fallos.
Archivo de resultados
Sección titulada «Archivo de resultados»Cuando un informe no se puede enviar (Probara inaccesible, la red caída, un informe rechazado), sus
resultados se pierden salvo que los conserves. Define un archivo de resultados, y el reporter
escribe en él lo que no pudo enviar al final de la ejecución; probara import results lo envía más
tarde, a las mismas ejecuciones.
reporter: [['@probara/playwright-reporter', { resultsFile: 'probara-results.json' }]],O PROBARA_RESULTS_FILE=probara-results.json, relativo al directorio en el que se ejecuta
Playwright.
Guardar lo que no se pudo enviar y enviarlo después
Sección titulada «Guardar lo que no se pudo enviar y enviarlo después»$ PROBARA_RESULTS_FILE=probara-results.json npx playwright test[probara] Sending 2 results of 2 tests (2 passed, 0 failed, 0 skipped, 0 blocked)[probara] 2 results were not sent: Probara answered 403 forbidden: <message from Probara>. No run was created or updated[probara] Wrote the 2 results that were not sent to /work/shop/probara-results.json: send them with probara import results /work/shop/probara-results.jsonDespués, desde cualquier job que tenga el token, envía lo que quedó con la CLI de Probara:
npx @probara/cli import results 'probara-results*.json'Pon el glob entre comillas: probara lo expande, y coincide con el archivo y con los hermanos que
se describen abajo. Si no coincide nada, no quedó nada sin enviar: la importación lo indica y
termina con código 0.
- Solo cuando hace falta. El archivo solo se escribe cuando algo no se envió: si todos los resultados llegaron, no hay archivo.
- A las mismas ejecuciones. El archivo nombra las ejecuciones a las que pertenecen sus resultados: una ejecución que el informe fallido dejó abierta recibe el resto de sus resultados, y una ejecución que nunca se creó la crea la importación con el mismo nombre y los mismos ajustes. Las ejecuciones se cierran como las habría cerrado el reporter.
- La importación lo consume.
probara import resultsenvía cada archivo por separado y después lo borra (junto con su carpeta<name>-attachments/) cuando se enviaron todos sus resultados, o lo reescribe solo con lo que sigue pendiente. Importar otra vez nunca envía un resultado dos veces, así que es seguro ejecutar la importación en todos los pipelines.--dry-runnunca toca los archivos. - Nunca toca un archivo anterior. Si ya hay un archivo en esa ruta (el de otro shard en un disco
compartido, o el de una ejecución anterior), el reporter lo deja como está y escribe en el primer
hermano libre:
probara-results-2.json, después-3, y así sucesivamente, cada uno con su propia carpeta de adjuntos. El registro nombra el archivo escrito, y el glob los importa todos, del más antiguo al más reciente. - Nunca a medio escribir. Cada archivo se escribe entero primero en un archivo temporal de la misma carpeta (con un nombre que empieza por punto, que el glob nunca encuentra) y aparece con su nombre de golpe: una importación simultánea ve el archivo entero o nada, y una ejecución detenida a medias no deja ningún archivo parcial.
- Adjuntos por ruta. Los archivos se referencian donde los escribió Playwright, por ruta
absoluta: conserva la carpeta de salida (
test-results/) en su sitio hasta que se envíe el archivo. Los cuerpos en memoria se escriben junto al archivo, en<name>-attachments/, y se referencian de forma relativa a él, así que el archivo y esa carpeta pueden moverse juntos. Una subida que falla durante la importación no se guarda para otro intento: su resultado ya se registró, así que ya no está en el archivo. La importación lo registra y termina con código 1.
Una segunda ejecución que no puede enviar mientras el archivo de la primera sigue ahí escribe un hermano:
$ PROBARA_RESULTS_FILE=probara-results.json npx playwright test[probara] Sending 2 results of 2 tests (2 passed, 0 failed, 0 skipped, 0 blocked)[probara] 2 results were not sent: Probara answered 403 forbidden: <message from Probara>. No run was created or updated[probara] Wrote the 2 results that were not sent to /work/shop/probara-results-2.json (/work/shop/probara-results.json already exists): send them with probara import results /work/shop/probara-results-2.jsonEnvío desactivado: guardarlo todo
Sección titulada «Envío desactivado: guardarlo todo»Con el envío desactivado (PROBARA_ENABLED=false, o sin token), el reporter escribe todos los
intentos en el archivo, con los vínculos a casos incluidos. Ejecuta las pruebas donde no hay token
(un fork, una máquina sin red) e importa el archivo desde un job que sí lo tenga:
$ PROBARA_ENABLED=false PROBARA_RESULTS_FILE=probara-results.json npx playwright test[probara] Wrote 2 results to /work/shop/probara-results.json: send them with probara import results /work/shop/probara-results.jsonEl mismo archivo muestra lo que se enviaría sin enviarlo: consulta comprobar qué se enviaría.
Guarda los archivos, sus carpetas <name>-attachments/ y la carpeta de salida como artefactos del
job de pruebas, e impórtalos en un job posterior que tenga el token. Un archivo de resultados y su
carpeta se pueden descargar en cualquier sitio; los archivos de la carpeta de salida se buscan en la
ruta absoluta que tenían, así que restáurala en esa ruta, o importa en el mismo job:
- name: Run Playwright tests run: npx playwright test env: PROBARA_API_TOKEN: ${{ secrets.PROBARA_API_TOKEN }} PROBARA_RESULTS_FILE: probara-results.json- name: Send what Probara did not get if: always() run: npx --yes @probara/cli@0.2 import results 'probara-results*.json' env: PROBARA_API_TOKEN: ${{ secrets.PROBARA_API_TOKEN }} PROBARA_ENABLED: ${{ secrets.PROBARA_API_TOKEN != '' }}Si Probara solo estuvo inaccesible un momento, la importación envía el resto. Si sigue sin poder, la importación termina con código 1 y conserva en cada archivo lo que no pudo enviar; los archivos que sí envió desaparecen.
Un archivo de resultados es una entrada de confianza: la importación sube los archivos que nombra, desde cualquier ruta que el job pueda leer, así que importa solo los archivos que escribieron tus propios jobs. Un adjunto cuya ruta relativa sale de la carpeta del archivo se deja fuera con una advertencia.
El formato
Sección titulada «El formato»El archivo es la versión 1 de un documento JSON: el proyecto, las ejecuciones y los ajustes del
reporter (nunca el token), y después cada resultado tal como lo construyó el reporter, antes de
statusMapping, que se aplica al enviar el archivo. El formato completo está en el
archivo de resultados de @probara/core
(en inglés), y la importación (varios archivos y globs, el resumen JSON, los códigos de salida) en
probara import results.
Siguiente: una ejecución para pipelines con shards, o solución de problemas.