Cypress recipe
Cypress doesn’t love async polling out of the box, so we wrap MailFade in a custom command and a small task.
1. Add a custom command
cypress/support/commands.ts:
const API = Cypress.env("MAILFADE_API_URL") ?? "https://api.mailfade.dev";
const KEY = Cypress.env("MAILFADE_KEY") as string | undefined;
declare global {
namespace Cypress {
interface Chainable {
freshInbox(prefix?: string): Chainable<string>;
waitForEmail(
inbox: string,
opts?: { subject?: RegExp; from?: RegExp; timeout?: number },
): Chainable<any>;
}
}
}
Cypress.Commands.add("freshInbox", (prefix = "cy") => {
const inbox = `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}@mailfade.dev`;
return cy.wrap(inbox, { log: false });
});
Cypress.Commands.add("waitForEmail", (inbox, opts = {}) => {
const { subject, from, timeout = 30_000 } = opts;
const start = Date.now();
const poll = (): Cypress.Chainable<any> => {
const auth = KEY ? { Authorization: `Bearer ${KEY}` } : undefined;
return cy.request({
url: `${API}/inbox/${encodeURIComponent(inbox)}`,
headers: auth,
}).then((r) => {
const hit = (r.body.emails ?? []).find((e: any) => {
if (subject && !subject.test(e.subject ?? "")) return false;
if (from && !from.test(e.sender ?? "")) return false;
return true;
});
if (hit) {
return cy.request({ url: `${API}/message/${hit.id}`, headers: auth }).its("body");
}
if (Date.now() - start > timeout) throw new Error(`no email at ${inbox}`);
return cy.wait(1000).then(poll);
});
};
return poll();
});
2. Use it
it("verifies a new signup", () => {
cy.freshInbox("signup").then((inbox) => {
cy.visit("/signup");
cy.get("#email").type(inbox);
cy.get("#password").type("hunter2hunter2");
cy.contains("button", "Sign up").click();
cy.waitForEmail(inbox, { subject: /confirm/i }).then((msg: any) => {
const link = (msg.text as string).match(/https?:\/\/\S+/)![0];
cy.visit(link);
cy.contains("Welcome").should("be.visible");
});
});
});
3. Config
cypress.config.ts:
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
env: {
MAILFADE_API_URL: "https://api.mailfade.dev",
MAILFADE_KEY: process.env.MAILFADE_KEY,
},
},
});