# Context
Part of a CI flakiness sweep. `ci-e2e-main` fails on ~8% of main pushes
(15 failing runs on 2026-07-08 alone), always the same three tests,
always on 5-second `expect` timeouts:
- `onboarding.spec.ts` — `Create your workspace` heading after sign-up
(sign-up mutation → loadCurrentUser → workspace-creation-defaults query,
three sequential round trips)
- `signup_invite_email.spec.ts` — `Create profile` (invite sign-up +
token exchange + full metadata load)
- `create-kanban-view.spec.ts` — `No Value` kanban column (view +
viewFields + viewGroups persistence, no-value group settles last)
The runner hosts the dev-mode NestJS server (`nest start --watch`), the
worker and Chromium simultaneously, so 5s is structurally too tight;
neighboring steps in the same specs already use 30-90s timeouts.
# Fix
- `playwright.config.ts`: `expect.timeout` 5s → 15s and test timeout 30s
→ 60s **on CI only** (the config already branches on `process.env.CI`
for retries/reporter). These are web-first auto-retrying assertions, so
green runs are not slowed — only genuinely failing assertions wait
longer. The 60s test budget also fixes an existing inconsistency: the
kanban spec has a 30s per-assertion timeout inside a 30s test budget.
- `create-kanban-view.spec.ts`: use a per-run unique label for the
Industry select field. The spec is `test.describe.serial`, and
Playwright retries re-run the whole group against the same database (no
reset between in-run retries). The already-created `Industry` field made
the label-uniqueness validation fail permanently, so Save stayed
disabled and **every retry of this group failed deterministically**
("element is not enabled" after 30s) — retries were dead weight for this
spec.
Adversarially reviewed: the alternative (per-assertion timeouts) is the
whack-a-mole pattern already attempted once (`Food` has a 30s patch);
`waitForResponse` on operation names would be more lines and more
brittle.
Test-infra only, 2 files, +11/-6.
Note for the team (out of scope here): `ci-e2e-main.yaml` builds the
server and then discards it — `nx start twenty-server` runs `rimraf dist
&& NODE_ENV=development nest start --watch`. Running the built server
would cut latency and runner load across the whole suite.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01AtD2wWm3EthV6t3Hs31QyB)_
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22701?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
## Problem
The merge queue is red. Two e2e tests fail consistently on `merge_group`
runs, both timing out while clicking `Settings`:
- `tests/create-kanban-view.spec.ts` ("Create Industry Select Field")
- `tests/authentication/signup_invite_email.spec.ts` ("Go to Settings
and copy invite link")
The earlier tokenPair localStorage fix (#21507 / e2e read in #21519)
restored login, so auth works again — but the navigation/settings polish
in #21523 then **moved the Settings entry out of the main app navigation
and into the workspace switcher dropdown** ("Moves Settings below
Support in the workspace switcher menu").
The e2e tests still looked for a top-level `getByRole('button', { name:
'Settings' })`, which no longer exists, so they timed out.
## Fix
Reach Settings the new way — open the workspace switcher dropdown, then
click the `Settings` link (it is now an `UndecoratedLink`/`MenuItem`,
role `link`, in `MultiWorkspaceDropdownDefaultComponents`):
- `lib/pom/leftMenu.ts`: `goToSettings()` now opens `workspace-dropdown`
first; `settingsTab` locator switched from `button` to `link`.
- `tests/create-kanban-view.spec.ts`: open the workspace dropdown before
clicking the Settings link.
- `tests/authentication/signup_invite_email.spec.ts`: the post-signup
"logged in" assertion now checks the `workspace-dropdown` is visible
instead of the removed Settings button.
## Testing
Triggering the merge-queue e2e suite via the `run-merge-queue` label on
this PR.
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21528?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
## Summary
- Fix stale `ObjectMetadataItems` GraphQL response cache after field
creation by using `request.workspaceMetadataVersion` (sourced from
Redis) instead of `workspace.metadataVersion` (from the potentially
stale CoreEntityCacheService)
- Make the E2E kanban view test selector more robust with a regex match
## Root Cause
The `useCachedMetadata` GraphQL plugin keys cached responses using
`workspace.metadataVersion` from the `CoreEntityCacheService`. When a
field is created:
1. The migration runner increments `metadataVersion` in DB and Redis
2. But the `CoreEntityCacheService` for `WorkspaceEntity` is **not**
invalidated
3. So `request.workspace.metadataVersion` still has the old version
4. The cache key resolves to the old cached response
5. The frontend gets stale metadata without the newly created field
This breaks E2E tests (and likely affects users) - after creating a
custom field, the metadata isn't visible until the workspace entity
cache refreshes.
## Fix
Use `request.workspaceMetadataVersion` (populated from Redis by the
middleware, always up-to-date) as the primary version for cache keys,
falling back to the entity cache version.
## Test plan
- [ ] E2E `create-kanban-view` tests should pass (creating a Select
field and immediately using it in a Kanban view)
- [ ] Verify `ObjectMetadataItems` returns fresh data after field
creation (no stale cache)
Made with [Cursor](https://cursor.com)
## Summary
- **Settings selector**: The Settings navigation item is now rendered as
a `<button>` (via `NavigationDrawerItem` with `onClick`) instead of an
`<a>` link (with `to`). Updated `leftMenu.ts` POM and
`create-kanban-view.spec.ts` to use `getByRole('button', { name:
'Settings' })`.
- **create-record URL field**: The Linkedin field interaction was
missing an initial label click to trigger the hover portal rendering.
Added `recordFieldList.getByText('Linkedin').first().click()` before the
value click, matching the pattern used by the working Emails field.
## Test plan
- [ ] E2E `signup_invite_email.spec.ts` passes (uses
`leftMenu.goToSettings()`)
- [ ] E2E `create-kanban-view.spec.ts` passes (uses Settings click
directly)
- [ ] E2E `create-record.spec.ts` passes (Linkedin URL field
interaction)
- [ ] Existing passing E2E tests remain green
Made with [Cursor](https://cursor.com)
In this PR,
- current basic E2E tests are fixed, and some were added, covering some
basic scenarios
- some tests avec been commented out, until we decide whether they are
worth fixing
The next steps are
- evaluate the flakiness of the tests. Once they've proved not to be
flaky, we should add more tests + re-write the current ones not using
aria-label (cf @lucasbordeau indication).
- We will add them back to the development flow