From 81844e3f43d18fbe124abb017ea9226a47bf8708 Mon Sep 17 00:00:00 2001 From: Nicolas Lopes Date: Thu, 1 Oct 2026 14:01:18 -0300 Subject: [PATCH 1/3] test(mosaic): wait longer for the reverification password field in destructive tests Co-Authored-By: Claude Opus 5.5 (1M context) --- .changeset/mosaic-destructive-test-timeout.md | 2 ++ .../src/blocks/destructive/destructive.feature.test.tsx | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 .changeset/mosaic-destructive-test-timeout.md diff --git a/.changeset/mosaic-destructive-test-timeout.md b/.changeset/mosaic-destructive-test-timeout.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/mosaic-destructive-test-timeout.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/packages/mosaic/src/blocks/destructive/destructive.feature.test.tsx b/packages/mosaic/src/blocks/destructive/destructive.feature.test.tsx index 8e29986f811..bd51eaa1337 100644 --- a/packages/mosaic/src/blocks/destructive/destructive.feature.test.tsx +++ b/packages/mosaic/src/blocks/destructive/destructive.feature.test.tsx @@ -148,7 +148,7 @@ describe('Destructive with reverification', () => { ); const { user } = await openVerification(); - expect(await screen.findByLabelText('Password')).toBeVisible(); + expect(await screen.findByLabelText('Password', undefined, { timeout: 3000 })).toBeVisible(); await untilConfirmStepIsGone(); const stopWatching = watchForConfirmStep(); await user.click(screen.getAllByRole('button', { name: 'Close' })[0]); @@ -171,7 +171,7 @@ describe('Destructive with reverification', () => { ); const { user } = await openVerification(); - const field = await screen.findByLabelText('Password'); + const field = await screen.findByLabelText('Password', undefined, { timeout: 3000 }); await untilConfirmStepIsGone(); const stopWatching = watchForConfirmStep(); await user.type(field, 'hunter2{Enter}'); @@ -196,7 +196,7 @@ describe('Destructive with reverification', () => { />, ); const { user } = await openVerification(); - expect(await screen.findByLabelText('Password')).toBeVisible(); + expect(await screen.findByLabelText('Password', undefined, { timeout: 3000 })).toBeVisible(); await user.click(screen.getAllByRole('button', { name: 'Close' })[0]); await waitFor(() => expect(screen.queryByRole('dialog')).toBeNull()); From b709ddbd2f566f272624d70374b565c70d588534 Mon Sep 17 00:00:00 2001 From: Nicolas Lopes Date: Thu, 1 Oct 2026 14:05:33 -0300 Subject: [PATCH 2/3] test(mosaic): wait for the code inputs after switching reverification methods Co-Authored-By: Claude Opus 5.5 (1M context) --- .../reverification/__tests__/reverification.feature.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mosaic/src/features/reverification/__tests__/reverification.feature.test.tsx b/packages/mosaic/src/features/reverification/__tests__/reverification.feature.test.tsx index bb0f200a164..4a45cdac1b2 100644 --- a/packages/mosaic/src/features/reverification/__tests__/reverification.feature.test.tsx +++ b/packages/mosaic/src/features/reverification/__tests__/reverification.feature.test.tsx @@ -932,7 +932,7 @@ describe('Reverification', () => { // The code step opens with an empty field and no error once the code is sent expect(await screen.findByText(STEP.emailCode)).toBeVisible(); - expect(slotValues()).toEqual(['', '', '', '', '', '']); + await waitFor(() => expect(slotValues()).toEqual(['', '', '', '', '', ''])); expect(screen.queryByText('Incorrect code')).toBeNull(); // Picking a phone code sends the SMS code through the first factor endpoints From f137e9aabbdecc1eda59f17d4af6184be57e107f Mon Sep 17 00:00:00 2001 From: Nicolas Lopes Date: Thu, 1 Oct 2026 14:55:54 -0300 Subject: [PATCH 3/3] test(mosaic): wait for the destructive dialog's initial focus before typing The 3s Password timeouts did not help: the click on Delete account was a no-op because the dialog's initial focus moved focus mid-typing and the confirmation stayed empty. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...imeout.md => mosaic-feature-test-races.md} | 0 .../destructive/destructive.feature.test.tsx | 19 ++++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) rename .changeset/{mosaic-destructive-test-timeout.md => mosaic-feature-test-races.md} (100%) diff --git a/.changeset/mosaic-destructive-test-timeout.md b/.changeset/mosaic-feature-test-races.md similarity index 100% rename from .changeset/mosaic-destructive-test-timeout.md rename to .changeset/mosaic-feature-test-races.md diff --git a/packages/mosaic/src/blocks/destructive/destructive.feature.test.tsx b/packages/mosaic/src/blocks/destructive/destructive.feature.test.tsx index bd51eaa1337..363a3ba7a24 100644 --- a/packages/mosaic/src/blocks/destructive/destructive.feature.test.tsx +++ b/packages/mosaic/src/blocks/destructive/destructive.feature.test.tsx @@ -70,10 +70,16 @@ function Host({ ); } +async function typeConfirmation(user: ReturnType) { + await user.click(screen.getByRole('button', { name: 'Open' })); + const dialog = await screen.findByRole('dialog'); + await waitFor(() => expect(dialog).toContainElement(document.activeElement as HTMLElement)); + await user.type(screen.getByRole('textbox'), 'Delete'); +} + async function openVerification() { const user = userEvent.setup(); - await user.click(screen.getByRole('button', { name: 'Open' })); - await user.type(await screen.findByRole('textbox'), 'Delete'); + await typeConfirmation(user); await user.click(screen.getByRole('button', { name: 'Delete account' })); return { user }; } @@ -148,7 +154,7 @@ describe('Destructive with reverification', () => { ); const { user } = await openVerification(); - expect(await screen.findByLabelText('Password', undefined, { timeout: 3000 })).toBeVisible(); + expect(await screen.findByLabelText('Password')).toBeVisible(); await untilConfirmStepIsGone(); const stopWatching = watchForConfirmStep(); await user.click(screen.getAllByRole('button', { name: 'Close' })[0]); @@ -171,7 +177,7 @@ describe('Destructive with reverification', () => { ); const { user } = await openVerification(); - const field = await screen.findByLabelText('Password', undefined, { timeout: 3000 }); + const field = await screen.findByLabelText('Password'); await untilConfirmStepIsGone(); const stopWatching = watchForConfirmStep(); await user.type(field, 'hunter2{Enter}'); @@ -196,12 +202,11 @@ describe('Destructive with reverification', () => { />, ); const { user } = await openVerification(); - expect(await screen.findByLabelText('Password', undefined, { timeout: 3000 })).toBeVisible(); + expect(await screen.findByLabelText('Password')).toBeVisible(); await user.click(screen.getAllByRole('button', { name: 'Close' })[0]); await waitFor(() => expect(screen.queryByRole('dialog')).toBeNull()); - await user.click(screen.getByRole('button', { name: 'Open' })); - await user.type(await screen.findByRole('textbox'), 'Delete'); + await typeConfirmation(user); const stopWatching = watchForConfirmStep(); await user.click(screen.getByRole('button', { name: 'Delete account' })); await new Promise(resolve => setTimeout(resolve, 150));