Skip to content

Commit b6bdd8d

Browse files
committed
fix: flaky email tests
for email test switching to a polling approach is the right fix, like the todo says. for outbox api it's dicier due to a race condition. We
1 parent a777aa1 commit b6bdd8d

2 files changed

Lines changed: 33 additions & 24 deletions

File tree

apps/e2e/tests/backend/endpoints/api/v1/emails/outbox-api.test.ts

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ const slowTemplate = deindent`
3838
3939
// Artificial delay to make the email slow to render
4040
const startTime = performance.now();
41-
while (performance.now() - startTime < 500) {
42-
// Busy wait - 500ms delay
41+
while (performance.now() - startTime < 2000) {
42+
// Busy wait - 2000ms delay
4343
}
4444
4545
export function EmailTemplate({ user, project }) {
@@ -648,8 +648,8 @@ describe("email outbox API", () => {
648648
649649
// Artificial delay to make the email slow to render
650650
const startTime = performance.now();
651-
while (performance.now() - startTime < 500) {
652-
// Busy wait - 500ms delay
651+
while (performance.now() - startTime < 2000) {
652+
// Busy wait - 2000ms delay
653653
}
654654
655655
export function EmailTemplate({ user, project }) {
@@ -670,12 +670,12 @@ describe("email outbox API", () => {
670670
`);
671671
break;
672672
} else {
673-
if (i >= 20) {
673+
if (i >= 50) {
674674
throw new StackAssertionError(`Timeout waiting for email in the outbox`, {
675675
outboxEmails: await getOutboxEmails(),
676676
});
677677
}
678-
await wait(25);
678+
await wait(100);
679679
}
680680
}
681681

@@ -884,7 +884,7 @@ describe("email outbox API", () => {
884884
let emailId: string | null = null;
885885
let pauseSucceeded = false;
886886

887-
for (let i = 0; i < 20; i++) {
887+
for (let i = 0; i < 50; i++) {
888888
const listResponse = await niceBackendFetch("/api/v1/emails/outbox", {
889889
method: "GET",
890890
accessType: "server",
@@ -908,7 +908,7 @@ describe("email outbox API", () => {
908908
}
909909
}
910910

911-
await wait(25);
911+
await wait(100);
912912
}
913913

914914
// These assertions must always run - test fails if we couldn't pause
@@ -937,15 +937,20 @@ describe("email outbox API", () => {
937937
// After unpausing, the email should go back to processing (preparing/rendering/scheduled/etc)
938938
expect(unpauseResponse.body.status).not.toBe("paused");
939939

940-
// Wait for the email to be sent (since we unpaused it)
941-
await wait(7_000);
942-
943-
// Verify the email was eventually sent
944-
const finalGetResponse = await niceBackendFetch(`/api/v1/emails/outbox/${emailId}`, {
945-
method: "GET",
946-
accessType: "server",
947-
});
948-
expect(finalGetResponse.body.status).toBe("sent");
940+
// Poll until the email is sent (since we unpaused it)
941+
for (let i = 0; ; i++) {
942+
const finalGetResponse = await niceBackendFetch(`/api/v1/emails/outbox/${emailId}`, {
943+
method: "GET",
944+
accessType: "server",
945+
});
946+
if (finalGetResponse.body.status === "sent") break;
947+
if (i >= 50) {
948+
throw new StackAssertionError(`Timed out waiting for email to be sent after unpause`, {
949+
status: finalGetResponse.body.status,
950+
});
951+
}
952+
await wait(500);
953+
}
949954
});
950955

951956
it("should cancel email with MANUALLY_CANCELLED reason", async ({ expect }) => {
@@ -1000,7 +1005,7 @@ describe("email outbox API", () => {
10001005
let emailId: string | null = null;
10011006
let pauseSucceeded = false;
10021007

1003-
for (let i = 0; i < 20; i++) {
1008+
for (let i = 0; i < 50; i++) {
10041009
const listResponse = await niceBackendFetch("/api/v1/emails/outbox", {
10051010
method: "GET",
10061011
accessType: "server",
@@ -1024,7 +1029,7 @@ describe("email outbox API", () => {
10241029
}
10251030
}
10261031

1027-
await wait(25);
1032+
await wait(100);
10281033
}
10291034

10301035
// We need to have successfully paused the email to test cancel

apps/e2e/tests/js/email.test.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,15 @@ it("should provide delivery statistics", async ({ expect }) => {
187187
subject: "Stats",
188188
});
189189

190-
// wait until the email is sent
191-
// TODO: use the equivalent of waitForMessagesWithSubject
192-
await wait(10_000);
193-
194-
const info = await serverApp.getEmailDeliveryStats();
190+
let info;
191+
for (let i = 0; ; i++) {
192+
info = await serverApp.getEmailDeliveryStats();
193+
if (info.stats.hour.sent >= 1) break;
194+
if (i >= 50) {
195+
throw new Error(`Timed out waiting for email delivery stats to reflect sent email: ${JSON.stringify(info)}`);
196+
}
197+
await wait(500);
198+
}
195199

196200
expect(info).toMatchInlineSnapshot(`
197201
{

0 commit comments

Comments
 (0)