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')