Aller au contenu
Facteur

Intégrations

Le canal, c’est votre framework de test

Sur ce marché, on n’intègre pas une API : on installe un paquet dans son framework. Nous n’en publions encore aucun, et cette page dit lequel vient, dans quel ordre et à quelle condition, plutôt que d’annoncer cinq bibliothèques qui n’existent pas.

Aujourd’hui

Une API HTTP, et rien à installer

Ce n’est pas un aveu. L’attente est faite côté serveur et l’extraction à la réception, donc un test n’a besoin d’aucune dépendance de notre part : voici un parcours de vérification par email complet, en Playwright, sans un seul paquet à nous.

inscription.spec.tsTypeScript
import { expect, test } from '@playwright/test';

const KEY = process.env.FACTEUR_KEY!;
const INBOX = 'j3k9x2mq';
const DOMAIN = `${INBOX}.inbox.facteur.eu`;

const awaitMessage = (sentTo: string) =>
  fetch('https://api.facteur.eu/v1/messages/search', {
    method: 'POST',
    headers: {
      authorization: `Bearer ${KEY}`,
      'content-type': 'application/json',
    },
    body: JSON.stringify({ inbox: INBOX, sentTo, wait: 30_000 }),
  }).then((response) => response.json());

test('le lien de vérification active le compte', async ({ page }) => {
  const tag = `run-${Date.now()}`;

  // Lancée avant le clic : elle attend, et répond dès
  // que le message arrive.
  const arriving = awaitMessage(`signup+${tag}`);

  await page.goto('/signup');
  await page.getByLabel('Email').fill(`signup+${tag}@${DOMAIN}`);
  await page.getByRole('button', { name: 'Créer mon compte' }).click();

  const { messages } = await arriving;
  const message = messages[0];

  // Le status avant tout champ dérivé du corps.
  expect(message.status).toBe('parsed');
  await page.goto(message.links[0].href);

  await expect(page.getByText('Compte vérifié')).toBeVisible();
});
  • La requête part avant le clic

    Elle attend, et répond à l’instant où le message arrive, pas à l’échéance. Lancée après, elle courrait après un message déjà là.

  • Le sous-adressage sépare les tests

    Tout ce qui suit le « + » est à vous. C’est ce qui permet à deux tests de partager une inbox sans se voler leurs messages.

  • On lit status avant tout champ dérivé

    Un message accepté existe avant d’être analysé : pendant quelques millisecondes il n’a ni sujet, ni code, ni liens. C’est ce qui sépare « pas de code dans ce message » de « le code n’est pas encore extrait ».

  • La clé se lit dans l’environnement

    Jamais écrite dans le test, jamais passée en argument. C’est la convention que les greffons reprendront.

Ce qui vient

Un greffon avant une bibliothèque, et JavaScript avant tout le reste

L’ordre n’est pas négociable en cours de route, et il n’est pas une préférence de goût : il suit une mesure, refaite avant chaque livraison.

LivrableÉtatCe qui le débloque
1Une bibliothèque Node minimale

Ouvrir une boîte, attendre un message, le lire avec ce qui en a été extrait, purger. C’est tout, et c’est délibéré : le périmètre resserré du produit vaut aussi pour sa surface publique. Zéro dépendance : une suite de tests ne veut pas d’un arbre de dépendances.

PrévuLe socle du greffon, et notre première traction publiquement mesurable.
2Un greffon Playwright

Une attente branchée sur le moteur du framework (une fixture et un expect.poll, donc ni sleep ni boucle de relance), une boîte par exécution détruite à la fin, et des assertions qui parlent le langage du test : « ce message porte un code à usage unique », « ce lien mène à ce domaine ».

PrévuLe canal le plus grand du marché, et personne n’y est.
3Un initialiseur npm create

Du dépôt vide au premier test qui passe en une commande.

PrévuLa première minute d’un intégrateur, qui est celle qui décide.
Un greffon Cypress

Une commande enregistrée qui rend une chaîne chaînable, plutôt qu’une fixture. Le travail est commun à 80 % avec le précédent.

Sous conditionDéclencheur : le greffon Playwright livré et documenté.
Une bibliothèque Python

Le seul second écosystème crédible. Nous ne le prenons pas par anticipation : le déclencheur est un chiffre, pas une impression.

Sous conditionDéclencheur : un usage mensuel stable du greffon Playwright, et une demande Python arrivée par les issues ou le support.
Les autres écosystèmes

.NET · Ruby · PHP · Java · Go · Swift · Dart

Pas au programme, et nous préférons l’écrire. La demande y est deux à trois ordres de grandeur plus faible que sur npm, et l’acteur de référence, qui en maintient dix, laisse son paquet le plus ancien trois générations majeures derrière sa bibliothèque principale. Neuf bibliothèques sans usage mesuré sont neuf dettes, pas une couverture.

Non prévuRien. Une case cochée à l’achat n’est pas une intégration.

Pourquoi Playwright d’abord

Le plus grand canal du marché est inoccupé

Relevé sur npm, à la date indiquée, et rejouable par n’importe qui.

FrameworkInstallations mensuellesGreffon concurrent
@playwright/test201 269 570Aucun
cypress30 638 605Deux

Relevé sur npm le 17 août 2026

Aucun de nos concurrents n’a de greffon Playwright ; deux en ont un pour Cypress. Leurs mots-clés npm portent encore « selenium », « webdriver » et « nightwatch » : leur référencement a une génération de retard sur les usages.

La réserve honnête : personne n’y est, et il y a peut-être une raison. Les fixtures de Playwright rendent un greffon moins indispensable qu’avec Cypress, où l’enregistrement de commandes est le seul chemin propre. Si, à l’écriture, une fixture de dix lignes dans la documentation rend le paquet inutile, alors le bon livrable est cette page de documentation, et nous le dirons plutôt que de publier pour publier.

Rien à installer pour un premier test

Une clé en lecture seule, une inbox, et l’exemple ci-dessus. Le plan gratuit ne demande pas de carte bancaire.