From e08faa1631c9241cf28475562d13188306553794 Mon Sep 17 00:00:00 2001 From: Talisson Costa Date: Mon, 15 Jun 2026 09:13:39 -0300 Subject: [PATCH] test(e2e): await permission save and reload-poll for granted env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit setUserPermission toggled the permission and immediately closed the modal, so logout could abort the in-flight POST/PUT to /user-permissions/ and the grant never persisted — the next user then couldn't see the entity (flaky 'switch-environment-production' timeout in environment-permission-test). Await the save response before closing. Also add reloadUntilVisible for state that is only eventually consistent across a fresh navigation: the env list is fetched on navigation, so a just-granted VIEW_ENVIRONMENT needs a reload, not a longer wait on the same page. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../e2e/helpers/e2e-helpers.playwright.ts | 24 +++++++++++++++++++ .../tests/environment-permission-test.pw.ts | 5 +++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/frontend/e2e/helpers/e2e-helpers.playwright.ts b/frontend/e2e/helpers/e2e-helpers.playwright.ts index 543efe790b67..f93f07368f82 100644 --- a/frontend/e2e/helpers/e2e-helpers.playwright.ts +++ b/frontend/e2e/helpers/e2e-helpers.playwright.ts @@ -872,14 +872,38 @@ export class E2EHelpers { if (entityName) { await this.click(byId(`permissions-${entityName.toLowerCase()}`)); } + // The toggle saves async via POST/PUT to .../user-permissions/. Await it + // before closing the modal — otherwise logout can abort the in-flight + // save and the grant never lands, so the next user can't see the entity. + const saved = this.page.waitForResponse( + (res) => + res.url().includes('/user-permissions/') && + res.request().method() !== 'GET', + { timeout: LONG_TIMEOUT }, + ); if (permission === 'ADMIN') { await this.click(byId(`admin-switch-${level}`)); } else { await this.click(byId(`permission-switch-${permission}`)); } + await saved; await this.closeModal(); } + // Reload the page until a selector becomes visible. For state that is + // eventually consistent across a fresh navigation (e.g. a just-granted + // permission) — waiting on a single page load can't help, because the data + // was already fetched without it. + async reloadUntilVisible(selector: string, timeout: number = LONG_TIMEOUT) { + logUsingLastSection(`Reload until visible ${selector}`); + await expect(async () => { + await this.page.reload(); + await expect(this.page.locator(selector).first()).toBeVisible({ + timeout: 5000, + }); + }).toPass({ timeout }); + } + // Create a tag async createTag(label: string, color: string = '#FF6B6B') { logUsingLastSection(`Creating tag: ${label}`); diff --git a/frontend/e2e/tests/environment-permission-test.pw.ts b/frontend/e2e/tests/environment-permission-test.pw.ts index 7bc3a5b56ee3..be725b0c512e 100644 --- a/frontend/e2e/tests/environment-permission-test.pw.ts +++ b/frontend/e2e/tests/environment-permission-test.pw.ts @@ -26,6 +26,7 @@ test.describe('Environment Permission Tests', () => { gotoTraits, login, logout, + reloadUntilVisible, setUserPermission, toggleFeature, waitForElementClickable, @@ -87,7 +88,9 @@ test.describe('Environment Permission Tests', () => { log('User with permissions can see environment') await login(E2E_NON_ADMIN_USER_WITH_ENV_PERMISSIONS, PASSWORD) await gotoProject(PROJECT_NAME) - await waitForElementVisible(byId('switch-environment-production')) + // VIEW_ENVIRONMENT was just granted; the env list was fetched on + // navigation, so reload until it reflects the new permission. + await reloadUntilVisible(byId('switch-environment-production')) await logout() log('User with permissions can update feature state')