From 9c42a76b1a2b2e078f219fbfbb23b026ecf05da5 Mon Sep 17 00:00:00 2001 From: "n8n-cat-bot[bot]" <283985454+n8n-cat-bot[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 13:17:45 +0000 Subject: [PATCH] test: Stabilize user select email-filtering tests (#41095) Co-authored-by: n8n-cat-bot[bot] --- .../N8nUserSelect/UserSelect.test.ts | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/frontend/@n8n/design-system/src/components/N8nUserSelect/UserSelect.test.ts b/packages/frontend/@n8n/design-system/src/components/N8nUserSelect/UserSelect.test.ts index 4c8716bb983..53a65a0a1a9 100644 --- a/packages/frontend/@n8n/design-system/src/components/N8nUserSelect/UserSelect.test.ts +++ b/packages/frontend/@n8n/design-system/src/components/N8nUserSelect/UserSelect.test.ts @@ -15,7 +15,8 @@ const getRenderedOptions = async () => { const filterInput = async (filterText: string) => { const input = screen.getByRole('combobox'); - await userEvent.type(input, filterText); + // Avoid a timer wait for each character on busy CI workers. + await userEvent.type(input, filterText, { delay: null }); }; const sampleUsers: IUser[] = [ @@ -171,6 +172,56 @@ describe('UserSelect', () => { }); }); + it.each([0, 100])('finishes email checks with %i ms timer latency', async (latency) => { + vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout', 'Date'] }); + const scheduleTimeout = globalThis.setTimeout; + // DEVP-1283: Model a busy CI worker without a wall-clock delay. + vi.stubGlobal( + 'setTimeout', + (handler: (...args: unknown[]) => void, delay?: number, ...args: unknown[]) => + scheduleTimeout(handler, Math.max(delay ?? 0, latency), ...args), + ); + const { unmount } = renderComponent({ props: { users: sampleUsers } }); + const runInteraction = async (interaction: Promise) => { + let settled = false; + const completion = interaction.finally(() => { + settled = true; + }); + while (!settled) { + await vi.advanceTimersToNextTimerAsync(); + } + await completion; + }; + + try { + const startedAt = Date.now(); + + await runInteraction(filterInput('alice@example.com')); + const aliceOptions = await getRenderedOptions(); + expect(aliceOptions).toHaveLength(1); + expect(aliceOptions[0]).toHaveAttribute('id', 'user-select-option-id-u1'); + + await runInteraction(userEvent.click(document.body)); + await runInteraction(filterInput('Example.com')); + expect(screen.queryByRole('listbox')).not.toBeInTheDocument(); + + await runInteraction(userEvent.click(document.body)); + await runInteraction(filterInput('example.com')); + expect(await getRenderedOptions()).toHaveLength(sampleUsers.length); + + // All three searches share the default Vitest test timeout. + expect(Date.now() - startedAt).toBeLessThan(5000); + } finally { + try { + unmount(); + await vi.runAllTimersAsync(); + } finally { + vi.unstubAllGlobals(); + vi.useRealTimers(); + } + } + }); + it('filters by full name and email and sorts by last name', async () => { const specificUsers: IUser[] = [ {