From 0897575fd04ee65c2520b5803faf614ca7962eaa Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Thu, 12 Mar 2026 15:29:35 +0100 Subject: [PATCH] Fix flaky return-to-path e2e tests (#18580) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes flaky `return-to-path` e2e tests that were failing intermittently in CI merge queue runs. **Root cause:** In the multi-workspace environment used by CI (`IS_MULTIWORKSPACE_ENABLED=true`), navigating to `localhost:3001/settings/accounts` triggers a full page redirect to `app.localhost:3001/welcome` via `useRedirectToDefaultDomain`. This redirect is a hard navigation (not a React Router transition), which clears all in-memory Jotai state — including the `returnToPathState` atom that stores the path the user should be redirected to after login. After the redirect, the app has no memory of the intended destination and falls back to `/objects/companies`. **Fix:** Before performing the cross-domain redirect in `useRedirectToDefaultDomain`, read the `returnToPath` from the Jotai store and pass it as a URL search parameter. On the new page load, `useInitializeQueryParamState` picks it up from the URL and re-hydrates the Jotai atom, preserving the return-to-path across the full page reload. ## Test plan - [x] Verified locally against production build (`serve -s build`) with `IS_MULTIWORKSPACE_ENABLED=true` — 33/33 consecutive passes of `return-to-path.spec.ts` - [x] Lint passes (`npx nx lint:diff-with-main twenty-front`) --- .../hooks/useRedirectToDefaultDomain.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/twenty-front/src/modules/domain-manager/hooks/useRedirectToDefaultDomain.ts b/packages/twenty-front/src/modules/domain-manager/hooks/useRedirectToDefaultDomain.ts index 30000345d5..0ba43e130b 100644 --- a/packages/twenty-front/src/modules/domain-manager/hooks/useRedirectToDefaultDomain.ts +++ b/packages/twenty-front/src/modules/domain-manager/hooks/useRedirectToDefaultDomain.ts @@ -1,17 +1,30 @@ +import { returnToPathState } from '@/auth/states/returnToPathState'; import { useLastAuthenticatedWorkspaceDomain } from '@/domain-manager/hooks/useLastAuthenticatedWorkspaceDomain'; import { useReadDefaultDomainFromConfiguration } from '@/domain-manager/hooks/useReadDefaultDomainFromConfiguration'; import { useRedirect } from '@/domain-manager/hooks/useRedirect'; +import { isNonEmptyString } from '@sniptt/guards'; +import { useStore } from 'jotai'; export const useRedirectToDefaultDomain = () => { const { defaultDomain } = useReadDefaultDomainFromConfiguration(); const { setLastAuthenticateWorkspaceDomain } = useLastAuthenticatedWorkspaceDomain(); + const store = useStore(); const { redirect } = useRedirect(); const redirectToDefaultDomain = () => { const url = new URL(window.location.href); if (url.hostname !== defaultDomain) { setLastAuthenticateWorkspaceDomain(null); + + const returnToPath = store.get(returnToPathState.atom); + if ( + isNonEmptyString(returnToPath) && + !url.searchParams.has('returnToPath') + ) { + url.searchParams.set('returnToPath', returnToPath); + } + url.hostname = defaultDomain; redirect(url.toString()); }