Traduit automatiquement de l’anglais.

Lire en anglais
Proxy Mail QA

Pourquoi mon formulaire d'inscription n'affiche-t-il pas d'erreur pour les mots de passe qui ne respectent pas les critères ?

Quelqu'un saisit un mot de passe trop court, appuie sur **Créer un compte**, et rien ne se passe. Ou la page continue comme si tout allait bien. La cause est presque toujours l'une de huit choses, et un test vous indique dans quel groupe chercher.

Mis à jour le

Notre recommandation, d’emblée. Nous éditons Proxy Mail QA, nous ne sommes donc pas neutres, mais ce problème se trouve dans votre code, et la correction aussi : aucun produit ne le corrige à votre place. Nous recommandons Proxy Mail QA pour deux parties du travail : tester volontairement des mots de passe qui enfreignent vos règles, conçus pour les limites de votre champ, et découvrir ce qui s’est réellement passé derrière un formulaire muet, car si un e-mail de vérification arrive, votre serveur a créé le compte. Il ne trouve pas le bug dans votre code ; ce sont les DevTools de votre navigateur, ou votre agent IA qui lit le code, qui s’en chargent.

D’abord, déterminez laquelle de ces trois situations se produit

Ouvrez les DevTools de votre navigateur sur l’onglet Network, puis soumettez un mot de passe qui enfreint vos règles, par exemple avec un caractère de moins que le minimum. Pour en obtenir un adapté à votre champ, utilisez la liste Edge-case password (« Should be rejected ») sur la fiche qu’ouvre le bouton clé de Proxy Mail QA for Chrome dans le champ du mot de passe, ou get_password_variants avec vos règles. Utilisez une nouvelle adresse de test, pour voir si un e-mail arrive.

Ce que vous voyez Signification Où regarder
Aucune requête n’est envoyée Le navigateur ou votre code a bloqué le formulaire, mais n’a rien affiché Causes 1 à 4
Une requête est envoyée et le serveur la refuse (400 ou 422) Le serveur a fait son travail ; la page n’a pas affiché la réponse Causes 5 et 6
Une requête est envoyée et le serveur l’accepte Le serveur autorise le mot de passe. Un e-mail de vérification arrive à l’adresse de test Cause 7

C’est la troisième qu’on oublie. Un formulaire « sans erreur » n’a peut-être simplement rien à signaler, parce que la règle du serveur est plus souple que celle de la page. Dans l’application, l’e-mail de vérification apparaît sur la ligne de l’adresse de test. Un agent ou un test peut utiliser expect_no_email, qui ne réussit que si rien n’arrive.

Les causes habituelles

Le formulaire n’a jamais rien envoyé

  1. novalidate sans rien pour le remplacer. Le formulaire, ou une bibliothèque de formulaires, désactive les messages du navigateur (novalidate, ou noValidate dans React), et votre propre validation n’affiche jamais d’erreur.
  2. Les règles ne sont pas sur le champ. Sans minlength, maxlength ou required, le navigateur n’a rien à vérifier. Et validity.tooShort n’est défini qu’après la saisie de la personne, donc une valeur définie par un script peut passer au travers.
  3. L’erreur existe mais est masquée. Le CSS la masque, elle est rendue sous le mauvais nom (errors.password alors que le champ est newPassword), ou elle ne s’affiche qu’une fois le champ « touché », et la soumission ne le marque pas comme touché.
  4. Un composant personnalisé enveloppe le champ. La bibliothèque de formulaires est reliée à l’enveloppe, pas au vrai <input>, donc elle vérifie une valeur vide, ou le composant ne transmet jamais le message d’erreur.

Le serveur l’a refusé, et la page ne l’a pas dit

  1. L’erreur est avalée. Le code affiche « Vérifiez vos e-mails » quelle que soit la réponse, utilise un catch {} vide, ou ne gère que res.ok. Certains clients d’authentification ne lèvent pas d’exception : signUp de Supabase renvoie { data, error }, donc un try/catch ne voit jamais un mot de passe refusé.
  2. L’erreur revient sous une forme que la page ne lit pas. Le serveur renvoie { "message": "..." } et la page cherche errors.password. Associez l’erreur de chaque service au champ concerné.

Le serveur l’a accepté

  1. La règle de la page est plus stricte que celle du serveur. La page indique 15 caractères ; le réglage du service d’authentification en autorise 6. Définissez le minimum dans les réglages du service, ou dans votre code serveur, et gardez-le identique à ce qu’indique la page.

Il y a une erreur, mais tout le monde ne la perçoit pas

  1. Elle n’est pas annoncée. Elle n’est affichée qu’en rouge, loin du champ, ou hors de l’écran sur téléphone, et n’est pas liée au champ. Les utilisateurs de lecteur d’écran n’entendent rien. Liez-la avec aria-describedby, définissez aria-invalid="true" et déplacez le focus sur le champ.

Un modèle qui affiche les erreurs de façon fiable

Sans framework, pour que l’idée s’applique à React, Vue ou autre :

<form id="signup" novalidate>
<label for="password">Password</label>
<p id="password-rules">At least 15 characters. Any letters, numbers, symbols or spaces.</p>
<input
id="password"
name="password"
type="password"
autocomplete="new-password"
minlength="15"
maxlength="128"
required
aria-describedby="password-rules password-error"
/>
<p id="password-error" class="error" hidden></p>
<button>Create account</button>
</form>
<script>
const form = document.getElementById('signup');
const password = form.elements.password;
const error = document.getElementById('password-error');
// Count characters, not UTF-16 units, and don't rely on validity.tooShort.
function rule(input) {
const length = [...input.value].length;
if (length === 0) return 'Enter a password.';
if (length < input.minLength) return `Use at least ${input.minLength} characters.`;
if (length > input.maxLength) return `Use at most ${input.maxLength} characters.`;
return '';
}
function show(message) {
error.textContent = message;
error.hidden = !message;
password.setAttribute('aria-invalid', message ? 'true' : 'false');
}
password.addEventListener('input', () => {
if (!error.hidden) show(rule(password));
});
form.addEventListener('submit', async (event) => {
event.preventDefault();
const message = rule(password);
if (message) {
show(message);
password.focus();
return;
}
const res = await fetch('/api/signup', { method: 'POST', body: new FormData(form) });
if (!res.ok) {
const body = await res.json().catch(() => ({}));
show(body.errors?.password ?? body.message ?? 'Something went wrong. Please try again.');
password.focus();
return;
}
location.assign('/check-your-email');
});
</script>

Le serveur vérifie les mêmes règles et répond à un mot de passe refusé par un 422 et { "errors": { "password": "Use at least 15 characters." } }, que la page affiche au niveau du champ.

Une remarque sur maxlength : le navigateur bloque la saisie à la limite et tronque le texte collé sans le signaler. Fixez-la bien au-dessus de ce que génère un gestionnaire de mots de passe, sinon quelqu’un enregistre un mot de passe plus long que celui reçu par votre application.

Demandez à votre agent de le trouver

Avec Proxy Mail QA connecté dans Qoder (Marketplace) :

My sign-up form at https://staging.acme.dev/signup shows no error when the password
breaks the rules (15 to 128 characters). Using Proxy Mail QA, get_password_variants
with min_length 15 and max_length 128, and submit each reject value with a new test
address (a plus tag on one address for each). For each, tell me whether a request was
sent, what the server answered, what the page showed, and whether a verification email
arrived (expect_no_email).
Then find the cause in the code and fix it, so the error shows at the field, is
announced to screen readers, and the server enforces the same rule as the page.

Prouvez que c’est corrigé

Un test Playwright avec le paquet npm proxymail-qa, pour que ça reste corrigé :

import { expect, test } from '@playwright/test';
import { ProxyMailQA } from 'proxymail-qa';
const qa = new ProxyMailQA(); // reads PROXYMAIL_QA_API_KEY
test('a too-short password shows an error and makes no account', async ({ page }) => {
const { reject } = await qa.passwordVariants({ minLength: 15, maxLength: 128 });
const tooShort = reject.filter(({ value }) => [...value].length < 15);
const { address } = await qa.createAddress();
for (const [i, { tests, value }] of tooShort.entries()) {
const tagged = address.replace('@', `+short${i}@`);
const submitted = new Date();
await page.goto('/signup');
await page.getByLabel('Email').fill(tagged);
await page.getByLabel('Password').fill(value);
await page.getByRole('button', { name: 'Create account' }).click();
await expect(page.locator('#password-error'), tests).toBeVisible();
await qa.expectNoEmail(tagged, { since: submitted, timeout: 10 });
}
await qa.deleteAddress(address);
});

expectNoEmail lève une exception dès qu’un e-mail de vérification arrive, ce qui signifierait que le serveur a créé le compte. Un suffixe plus donne à chaque essai son propre compte dans votre application, et l’attente sur l’adresse suffixée ne voit que les e-mails qui lui sont envoyés.

Ce que Proxy Mail QA ne fait pas ici

Essayez-le lors de votre prochain test d’inscription

Offre gratuite, sans carte bancaire. Créez une adresse et regardez arriver le code ou le lien.

Créer un compte gratuitOuvrir l'application

Vous avez créé votre application avec un outil d’IA ? Choisissez le vôtre

Une question sur cette page ?

Posez votre question dans la langue de votre choix. La documentation peut y répondre tout de suite, ou vous pouvez l'envoyer à l'équipe Proxy Mail QA, qui répond en anglais.

Interroger la documentation