Dinoer

El formulario informa de éxito y nunca se envía

El clic funciona, el escenario termina sin error y el servidor no recibió nada. Dos causas distintas dan este mismo resultado, y la solución de una no arregla la otra.

El síntoma. Rellena un formulario, pulsa el botón de envío, obtiene succes: true y el objetivo no ha cambiado. Al leer la página después, aparece la misma página, nunca el resultado esperado.

Dos causas sin relación dan este mismo resultado. Distíngalas antes de elegir una solución.

Causa 1: el navegador bloqueó el envío

La validación HTML5. Un campo marcado como required está vacío, o un campo type="email" contiene algo que no es una dirección. El navegador se niega a enviar el formulario y muestra un pequeño mensaje junto al campo.

Dinoer informa del clic como correcto, porque lo fue: el clic ocurrió. Fue el navegador el que no le dio curso.

Cómo reconocerlo. No se envió nada, así que nada se carga: en latences_actions, un attendre_navigation situado justo después del clic termina al instante. Para saber qué campos bloquean, pregunte a la página:

{"type": "evaluer",
 "script": "Array.from(document.querySelectorAll(':invalid')).map(e => e.name || e.id)"}

La solución. Rellene el campo que falta. Si debe quedar vacío a propósito, envíe el formulario directamente, lo que evita la validación nativa:

{"type": "evaluer",
 "script": "document.querySelector('#my-form').submit()"}

Causa 2: un clic desde JavaScript no es el clic de un usuario

Llamar a .click() sobre un botón de envío desde JavaScript produce un evento marcado isTrusted: false. Los scripts de la página pueden ignorar o anular ese evento, y algunos lo hacen: el escenario termina con succes: true y el formulario nunca se envió.

{"type": "evaluer",
 "script": "document.querySelector('input[name=upgrade]').click()"}

La solución. Prefiera un cliquer real sobre el botón: el clic de Playwright se trata como el de un usuario. Desde evaluer, envíe el propio formulario:

{"type": "evaluer",
 "script": "document.querySelector('input[value=\"theme-slug\"]').closest('form').requestSubmit()"}

requestSubmit() ejecuta la validación y los controladores submit del formulario, como un envío hecho por un usuario. submit() se salta ambos: úselo solo si sabe que el formulario se envía directamente al servidor.

La regla que conviene recordar

Para enviar un formulario, prefiera cliquer sobre el botón. Desde evaluer, llame a requestSubmit() sobre el formulario, nunca a .click() sobre el botón.

Antes de sacar conclusiones

Un envío que parece haber fallado puede haber funcionado. Una solicitud lenta (una importación, una copia, cualquier cosa que tarde decenas de segundos) puede superar el tiempo de espera mientras el servidor sigue y termina el trabajo. Un TimeoutError en un clic significa que Playwright dejó de esperar, no que no pasara nada.

Compruebe el objetivo antes de repetir, o ejecutará la operación dos veces. La operación que tarda →

En resumen

  • Dos causas, un síntoma: la validación nativa bloqueó el formulario, o se ignoró un .click() de JavaScript.
  • evaluer con :invalid enumera los campos que bloquean.
  • Prefiera cliquer; desde evaluer, requestSubmit() sobre el formulario.
  • Un tiempo agotado no es un fallo: compruébelo antes de repetir.