Aller au contenu
Facteur
ENCommencer

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 en publions quatre, et cette page donne l’adresse de chacun, ce qui reste sous condition, et ce que nous ne publierons pas.

Aujourd’hui

Une API HTTP, et rien à installer

Les quatre paquets sont optionnels, et c’est le point : l’attente est faite côté serveur et l’extraction à la réception, donc un test appelle la recherche de messages sans rien installer. 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 reprennent.

Ce que nous publions

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
Une 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.

Publié@facteur-eu/sdkLe socle du greffon, et notre première traction publiquement mesurable.
Un greffon Playwright

Une adresse dérivée du test lui-même, donc deux tests en parallèle ne lisent jamais le même courrier, et un test rejoué ne relit pas celui de sa première tentative. Les assertions sont rejouées par le moteur de Playwright, l’attente s’arrête dans le budget du test, et le message reçu est attaché au rapport : un échec montre le courrier arrivé, pas seulement une ligne rouge.

Publiéplaywright-facteurLe canal le plus grand du marché, et personne n’y est.
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.

Publiécypress-facteurLe canal que la concurrence a déjà prouvé, et 80 % du travail partagé avec le greffon Playwright.
Un initialiseur npm create

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

Publiécreate-facteurLa première minute d’un intégrateur, qui est celle qui décide.
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 était écrite avant le code : personne n’y est, et il y avait peut-être une raison. Les fixtures de Playwright rendent un greffon moins indispensable qu’avec Cypress, donc le point de contrôle était qu’une fixture de dix lignes dans la documentation suffise. Elle ne suffisait pas : l’adresse dérivée du test, la reprise, le budget d’attente et le message attaché au rapport ne tiennent pas en dix lignes. C’est ce qui a décidé la publication.

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.