Quality, live

Every time one of my test suites finishes, the CI publishes its result here. Nobody edits this page by hand: if something fails, it shows.

Portfolio · e2e

Passing

Playwright against davidameth.dev in production, on desktop (1440 px) and phone (375 px): pages, links, SEO, Spanish/English parity, theme, and WCAG 2.1 AA accessibility with axe.

Latest run: · 56a274f

passed
122
failed
0
skipped
26
duration
2 min 47 s

passeddidn't runlighter: only the result is left

See all 148 tests
accessibility.spec.ts28 passed
  • passed: / has no serious WCAG 2.1 AA violations (light) desktop 3.1 s
  • passed: / has no serious WCAG 2.1 AA violations (dark) desktop 2.4 s
  • passed: /en/ has no serious WCAG 2.1 AA violations (light) desktop 2.4 s
  • passed: /en/ has no serious WCAG 2.1 AA violations (dark) desktop 2.3 s
  • passed: /experiencia/ has no serious WCAG 2.1 AA violations (light) desktop 2.1 s
  • passed: /experiencia/ has no serious WCAG 2.1 AA violations (dark) desktop 2 s
  • passed: /en/experience/ has no serious WCAG 2.1 AA violations (light) desktop 2.1 s
  • passed: /en/experience/ has no serious WCAG 2.1 AA violations (dark) desktop 2.1 s
  • passed: /proyectos/torneo/ has no serious WCAG 2.1 AA violations (light) desktop 3.6 s
  • passed: /proyectos/torneo/ has no serious WCAG 2.1 AA violations (dark) desktop 3.2 s
  • passed: /proyectos/biodiversidad/ has no serious WCAG 2.1 AA violations (light) desktop 2.7 s
  • passed: /proyectos/biodiversidad/ has no serious WCAG 2.1 AA violations (dark) desktop 2.6 s
  • passed: /proyectos/forbesverse/ has no serious WCAG 2.1 AA violations (light) desktop 3.1 s
  • passed: /proyectos/forbesverse/ has no serious WCAG 2.1 AA violations (dark) desktop 3 s
  • passed: / has no serious WCAG 2.1 AA violations (light) mobile 2.4 s
  • passed: / has no serious WCAG 2.1 AA violations (dark) mobile 2.3 s
  • passed: /en/ has no serious WCAG 2.1 AA violations (light) mobile 2.3 s
  • passed: /en/ has no serious WCAG 2.1 AA violations (dark) mobile 2.3 s
  • passed: /experiencia/ has no serious WCAG 2.1 AA violations (light) mobile 2.1 s
  • passed: /experiencia/ has no serious WCAG 2.1 AA violations (dark) mobile 2 s
  • passed: /en/experience/ has no serious WCAG 2.1 AA violations (light) mobile 2 s
  • passed: /en/experience/ has no serious WCAG 2.1 AA violations (dark) mobile 2.2 s
  • passed: /proyectos/torneo/ has no serious WCAG 2.1 AA violations (light) mobile 3.4 s
  • passed: /proyectos/torneo/ has no serious WCAG 2.1 AA violations (dark) mobile 3.2 s
  • passed: /proyectos/biodiversidad/ has no serious WCAG 2.1 AA violations (light) mobile 2.6 s
  • passed: /proyectos/biodiversidad/ has no serious WCAG 2.1 AA violations (dark) mobile 2.6 s
  • passed: /proyectos/forbesverse/ has no serious WCAG 2.1 AA violations (light) mobile 3.1 s
  • passed: /proyectos/forbesverse/ has no serious WCAG 2.1 AA violations (dark) mobile 3.1 s
languages.spec.ts12 passed · 6 skipped
  • passed: / and /en/ › have the same sections, projects, jobs and certificates desktop 647 ms
  • passed: / and /en/ › declare each other as translations desktop 729 ms
  • skipped: / and /en/ › have the same sections, projects, jobs and certificates mobile
  • skipped: / and /en/ › declare each other as translations mobile
  • passed: /experiencia/ and /en/experience/ › have the same sections, projects, jobs and certificates desktop 566 ms
  • passed: /experiencia/ and /en/experience/ › declare each other as translations desktop 602 ms
  • skipped: /experiencia/ and /en/experience/ › have the same sections, projects, jobs and certificates mobile
  • skipped: /experiencia/ and /en/experience/ › declare each other as translations mobile
  • passed: each language speaks its own › the renamed client reads «hoy» in Spanish and «now» in English desktop 973 ms
  • passed: each language speaks its own › the language switch leads to the same page in the other language desktop 894 ms
  • skipped: each language speaks its own › the renamed client reads «hoy» in Spanish and «now» in English mobile
  • skipped: each language speaks its own › the language switch leads to the same page in the other language mobile
  • passed: architecture pages, which exist in Spanish only › send an English reader back to the English home desktop 893 ms
  • passed: architecture pages, which exist in Spanish only › send a Spanish reader back to the Spanish home desktop 897 ms
  • passed: architecture pages, which exist in Spanish only › default to the Spanish home for a reader who arrives from outside desktop 465 ms
  • passed: architecture pages, which exist in Spanish only › send an English reader back to the English home mobile 907 ms
  • passed: architecture pages, which exist in Spanish only › send a Spanish reader back to the Spanish home mobile 871 ms
  • passed: architecture pages, which exist in Spanish only › default to the Spanish home for a reader who arrives from outside mobile 551 ms
layout.spec.ts26 passed · 2 skipped
  • passed: the home bar carries the «.d» mark, named for screen readers desktop 952 ms
  • passed: project captures are shown whole, never cropped desktop 1.1 s
  • passed: links to the old section names still land on their section desktop 980 ms
  • passed: architecture pages start below the floating bar desktop 990 ms
  • passed: the dark theme survives a reload and a change of page desktop 2.2 s
  • passed: a reader who picked night in the previous design keeps it desktop 597 ms
  • passed: the home bar carries the «.d» mark, named for screen readers mobile 650 ms
  • passed: project captures are shown whole, never cropped mobile 687 ms
  • passed: links to the old section names still land on their section mobile 908 ms
  • passed: architecture pages start below the floating bar mobile 770 ms
  • passed: the dark theme survives a reload and a change of page mobile 753 ms
  • passed: a reader who picked night in the previous design keeps it mobile 626 ms
  • passed: the floating bar › stays one short row at every width, with no crowding desktop 4.2 s
  • passed: the floating bar › offers the menu on a phone and the section links on a wide screen desktop 957 ms
  • passed: the floating bar › stays one short row at every width, with no crowding mobile 1.7 s
  • passed: the floating bar › offers the menu on a phone and the section links on a wide screen mobile 647 ms
  • skipped: the phone menu › opens onto its first link and closes with Escape, back to its button desktop
  • skipped: the phone menu › closes when a section is chosen desktop
  • passed: the phone menu › opens onto its first link and closes with Escape, back to its button mobile 1.4 s
  • passed: the phone menu › closes when a section is chosen mobile 1.4 s
  • passed: the first screen › names David in full as the page heading (/) desktop 703 ms
  • passed: the first screen › shows the call to action without scrolling (/) desktop 756 ms
  • passed: the first screen › names David in full as the page heading (/en/) desktop 714 ms
  • passed: the first screen › shows the call to action without scrolling (/en/) desktop 831 ms
  • passed: the first screen › names David in full as the page heading (/) mobile 496 ms
  • passed: the first screen › shows the call to action without scrolling (/) mobile 519 ms
  • passed: the first screen › names David in full as the page heading (/en/) mobile 471 ms
  • passed: the first screen › shows the call to action without scrolling (/en/) mobile 527 ms
links.spec.ts3 passed · 3 skipped
  • passed: every internal link resolves, and every #anchor exists on its page desktop 12 s
  • passed: every external link answers desktop 8.6 s
  • passed: the email links open a message to the published address desktop 651 ms
  • skipped: every internal link resolves, and every #anchor exists on its page mobile
  • skipped: every external link answers mobile
  • skipped: the email links open a message to the published address mobile
pages.spec.ts38 passed
  • passed: an unknown address answers 404, not a blank 200 desktop 469 ms
  • passed: retired route /proyectos/ lands on /#proyectos desktop 523 ms
  • passed: retired route /contacto/ lands on /#contacto desktop 582 ms
  • passed: retired route /en/projects/ lands on /en/#projects desktop 581 ms
  • passed: retired route /en/contact/ lands on /en/#contact desktop 589 ms
  • passed: an unknown address answers 404, not a blank 200 mobile 389 ms
  • passed: retired route /proyectos/ lands on /#proyectos mobile 534 ms
  • passed: retired route /contacto/ lands on /#contacto mobile 475 ms
  • passed: retired route /en/projects/ lands on /en/#projects mobile 483 ms
  • passed: retired route /en/contact/ lands on /en/#contact mobile 480 ms
  • passed: page / › loads cleanly, in its own language desktop 1.1 s
  • passed: page / › never scrolls sideways desktop 510 ms
  • passed: page / › loads cleanly, in its own language mobile 945 ms
  • passed: page / › never scrolls sideways mobile 465 ms
  • passed: page /en/ › loads cleanly, in its own language desktop 1 s
  • passed: page /en/ › never scrolls sideways desktop 410 ms
  • passed: page /en/ › loads cleanly, in its own language mobile 977 ms
  • passed: page /en/ › never scrolls sideways mobile 422 ms
  • passed: page /experiencia/ › loads cleanly, in its own language desktop 822 ms
  • passed: page /experiencia/ › never scrolls sideways desktop 433 ms
  • passed: page /experiencia/ › loads cleanly, in its own language mobile 877 ms
  • passed: page /experiencia/ › never scrolls sideways mobile 411 ms
  • passed: page /en/experience/ › loads cleanly, in its own language desktop 817 ms
  • passed: page /en/experience/ › never scrolls sideways desktop 368 ms
  • passed: page /en/experience/ › loads cleanly, in its own language mobile 871 ms
  • passed: page /en/experience/ › never scrolls sideways mobile 395 ms
  • passed: page /proyectos/torneo/ › loads cleanly, in its own language desktop 875 ms
  • passed: page /proyectos/torneo/ › never scrolls sideways desktop 437 ms
  • passed: page /proyectos/torneo/ › loads cleanly, in its own language mobile 932 ms
  • passed: page /proyectos/torneo/ › never scrolls sideways mobile 469 ms
  • passed: page /proyectos/biodiversidad/ › loads cleanly, in its own language desktop 872 ms
  • passed: page /proyectos/biodiversidad/ › never scrolls sideways desktop 468 ms
  • passed: page /proyectos/biodiversidad/ › loads cleanly, in its own language mobile 961 ms
  • passed: page /proyectos/biodiversidad/ › never scrolls sideways mobile 481 ms
  • passed: page /proyectos/forbesverse/ › loads cleanly, in its own language desktop 862 ms
  • passed: page /proyectos/forbesverse/ › never scrolls sideways desktop 657 ms
  • passed: page /proyectos/forbesverse/ › loads cleanly, in its own language mobile 936 ms
  • passed: page /proyectos/forbesverse/ › never scrolls sideways mobile 449 ms
seo.spec.ts13 passed · 13 skipped
  • passed: / declares its canonical address and a working social image desktop 1.1 s
  • passed: /en/ declares its canonical address and a working social image desktop 1.4 s
  • passed: /experiencia/ declares its canonical address and a working social image desktop 582 ms
  • passed: /en/experience/ declares its canonical address and a working social image desktop 616 ms
  • passed: /proyectos/torneo/ declares its canonical address and a working social image desktop 778 ms
  • passed: /proyectos/biodiversidad/ declares its canonical address and a working social image desktop 665 ms
  • passed: the es home describes its author as structured data desktop 502 ms
  • passed: the en home describes its author as structured data desktop 434 ms
  • passed: the sitemap lists exactly the published pages desktop 331 ms
  • passed: /proyectos/forbesverse/ is readable by link and invisible to search desktop 539 ms
  • passed: robots.txt allows crawling and points at the sitemap desktop 196 ms
  • passed: llms.txt introduces the author to language models desktop 226 ms
  • passed: every icon the browser and the home screen ask for exists desktop 1.5 s
  • skipped: / declares its canonical address and a working social image mobile
  • skipped: /en/ declares its canonical address and a working social image mobile
  • skipped: /experiencia/ declares its canonical address and a working social image mobile
  • skipped: /en/experience/ declares its canonical address and a working social image mobile
  • skipped: /proyectos/torneo/ declares its canonical address and a working social image mobile
  • skipped: /proyectos/biodiversidad/ declares its canonical address and a working social image mobile
  • skipped: the es home describes its author as structured data mobile
  • skipped: the en home describes its author as structured data mobile
  • skipped: the sitemap lists exactly the published pages mobile
  • skipped: /proyectos/forbesverse/ is readable by link and invisible to search mobile
  • skipped: robots.txt allows crawling and points at the sitemap mobile
  • skipped: llms.txt introduces the author to language models mobile
  • skipped: every icon the browser and the home screen ask for exists mobile
shortlinks.spec.ts2 passed · 2 skipped
  • passed: short links point where the site's data says desktop 5 ms
  • passed: short links redirect on the live site desktop 246 ms
  • skipped: short links point where the site's data says mobile
  • skipped: short links redirect on the live site mobile

When it runs: Monday, Thursday, and Saturday at 6:00 a.m. (Panama time).

See what it tests

Tournament API

Passing

pytest on the api.davidameth.dev API: unit tests, Hypothesis properties, Schemathesis contract tests, and an oracle against the app's standings table.

Latest run: · 86f001d

passed
90
failed
0
coverage
99.4 %
duration
25 s

passeddidn't run

See all 90 tests
tests/test_api.py36 passed
  • passed: test_equipos_en_orden_de_siembra 10 ms
  • passed: test_un_equipo 6 ms
  • passed: test_jornadas_con_estado_derivado 10 ms
  • passed: test_partido_con_resultado_coherente 5 ms
  • passed: test_la_liga_tiene_21_partidos_y_cada_equipo_juega_6 39 ms
  • passed: test_filtros_combinados 5 ms
  • passed: test_paginacion_recorre_todo_sin_repetir 28 ms
  • passed: test_filtro_sin_resultados_es_lista_vacia_no_404 5 ms
  • passed: test_tabla_historica 6 ms
  • passed: test_tabla_explica_los_empates 5 ms
  • passed: test_simular_suma_a_la_temporada_sin_guardar 15 ms
  • passed: test_simular_desde_cero 6 ms
  • passed: test_simular_rechaza_lo_imposible[resultado0-results.0] 5 ms
  • passed: test_simular_rechaza_lo_imposible[resultado1-results.0.sets] 5 ms
  • passed: test_simular_rechaza_lo_imposible[resultado2-results.0] 5 ms
  • passed: test_simular_rechaza_lo_imposible[resultado3-results.0.home] 5 ms
  • passed: test_simular_rechaza_lo_imposible[resultado4-results.0.extra] 5 ms
  • passed: test_simular_con_equipo_que_no_existe 5 ms
  • passed: test_404_en_formato_rfc_9457[/v1/teams/aguilas] 5 ms
  • passed: test_404_en_formato_rfc_9457[/v1/jornadas/99] 4 ms
  • passed: test_404_en_formato_rfc_9457[/v1/matches/j9-p9] 5 ms
  • passed: test_404_en_formato_rfc_9457[/v1/standings?through_jornada=40] 5 ms
  • passed: test_404_en_formato_rfc_9457[/v1/nada] 4 ms
  • passed: test_parametro_fuera_de_rango 4 ms
  • passed: test_metodo_no_permitido_dice_cuales_si 3 ms
  • passed: test_head_como_get_sin_cuerpo 13 ms
  • passed: test_cuerpo_que_no_es_json 4 ms
  • passed: test_cada_tipo_de_error_esta_documentado 23 ms
  • passed: test_error_inesperado_no_filtra_detalles 6 ms
  • passed: test_etag_y_304 13 ms
  • passed: test_el_etag_cambia_con_la_consulta 9 ms
  • passed: test_request_id_propio_o_generado 12 ms
  • passed: test_cors_abierto_para_leer 5 ms
  • passed: test_salud_y_raiz 8 ms
  • passed: test_fase_final_sin_marcador_y_con_podio 5 ms
  • passed: test_la_fase_final_no_toca_la_tabla_de_la_liga 9 ms
tests/test_contrato.py11 passed
  • passed: test_la_api_cumple_su_openapi[GET /v1/teams] 284 ms
  • passed: test_la_api_cumple_su_openapi[GET /v1/teams/{team_id}] 716 ms
  • passed: test_la_api_cumple_su_openapi[GET /v1/jornadas] 45 ms
  • passed: test_la_api_cumple_su_openapi[GET /v1/jornadas/{number}] 642 ms
  • passed: test_la_api_cumple_su_openapi[GET /v1/matches] 1.2 s
  • passed: test_la_api_cumple_su_openapi[GET /v1/matches/{match_id}] 870 ms
  • passed: test_la_api_cumple_su_openapi[GET /v1/standings] 644 ms
  • passed: test_la_api_cumple_su_openapi[POST /v1/standings/simulate] 2.4 s
  • passed: test_la_api_cumple_su_openapi[GET /v1/final-phase] 49 ms
  • passed: test_la_api_cumple_su_openapi[GET /health] 45 ms
  • passed: test_la_api_cumple_su_openapi[GET /problems/{slug}] 746 ms
tests/test_datos.py8 passed
  • passed: test_el_archivo_real_carga 1 ms
  • passed: test_jornada_inexistente 2 ms
  • passed: test_equipo_inexistente 2 ms
  • passed: test_marcador_imposible_no_arranca 1 ms
  • passed: test_estado_de_jornada_derivado[estados0-pending] 1 ms
  • passed: test_estado_de_jornada_derivado[estados1-in_progress] 1 ms
  • passed: test_estado_de_jornada_derivado[estados2-completed] 1 ms
  • passed: test_fase_final_incoherente_no_arranca 3 ms
tests/test_dominio.py33 passed
  • passed: test_set_valido[25-0] 1 ms
  • passed: test_set_valido[25-23] 1 ms
  • passed: test_set_valido[23-25] 1 ms
  • passed: test_set_valido[26-24] 1 ms
  • passed: test_set_valido[33-31] 1 ms
  • passed: test_set_valido[3-25] 1 ms
  • passed: test_set_imposible[25-24-ventaja] 2 ms
  • passed: test_set_imposible[24-22-al menos a 25] 2 ms
  • passed: test_set_imposible[27-24-en cuanto hay] 2 ms
  • passed: test_set_imposible[30-20-en cuanto hay] 1 ms
  • passed: test_set_imposible[25-25-empatado] 2 ms
  • passed: test_set_imposible[-1-25-negativos] 2 ms
  • passed: test_partido_necesita_tres_sets 1 ms
  • passed: test_un_equipo_no_juega_contra_si_mismo 1 ms
  • passed: test_ganador_y_sets 1 ms
  • passed: test_puntos_fivb[3-0-3] 1 ms
  • passed: test_puntos_fivb[2-1-2] 1 ms
  • passed: test_puntos_fivb[1-2-1] 1 ms
  • passed: test_puntos_fivb[0-3-0] 1 ms
  • passed: test_ratio_sin_derrotas_es_infinito 1 ms
  • passed: test_desempata_partidos_ganados 1 ms
  • passed: test_desempata_ratio_de_puntos_y_si_no_comparten_posicion 1 ms
  • passed: test_equipo_desconocido 1 ms
  • passed: test_todo_set_generado_es_valido 92 ms
  • passed: test_invariantes_de_la_tabla 6.5 s
  • passed: test_el_orden_de_los_partidos_no_cambia_la_tabla 4 s
  • passed: test_podio_de_un_cuadro_valido 1 ms
  • passed: test_cuadro_imposible[cambio0-cuatro primeros] 2 ms
  • passed: test_cuadro_imposible[cambio1-las dos semifinales] 2 ms
  • passed: test_cuadro_imposible[cambio2-perdedores de semifinal] 2 ms
  • passed: test_cuadro_imposible[cambio3-ganadores de semifinal] 1 ms
  • passed: test_falta_un_partido_de_la_fase_final 1 ms
  • passed: test_el_ganador_tiene_que_haber_jugado 2 ms
tests/test_oraculo_produccion.py2 passed
  • passed: test_la_tabla_coincide_con_la_app_en_produccion 6 ms
  • passed: test_el_podio_coincide_con_la_app_en_produccion 5 ms

When it runs: on every push to main.

See what it testsSee the run on GitHubSee the code