From 4e617af3e8a5a5b4bfceee8de849bd4b978d4f7e Mon Sep 17 00:00:00 2001 From: Pranita Fulsundar Date: Thu, 19 Jun 2025 09:52:23 +0530 Subject: [PATCH] fix(test): AUT failures for Policies.spec and Roles.spec (#21844) * fix policies and roles aut tests * minor refactor * fix getElementWithPagination function * remove flakyness for policies test --- .../ui/playwright/e2e/Pages/Policies.spec.ts | 17 ++++-- .../ui/playwright/e2e/Pages/Roles.spec.ts | 60 +++++++++++++------ .../resources/ui/playwright/utils/roles.ts | 32 +++++++++- 3 files changed, 85 insertions(+), 24 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Policies.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Policies.spec.ts index 713cc20e6a1..96562db2a89 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Policies.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Policies.spec.ts @@ -37,6 +37,7 @@ import { toastNotification, } from '../../utils/common'; import { validateFormNameFieldInput } from '../../utils/form'; +import { getElementWithPagination } from '../../utils/roles'; import { settingClick } from '../../utils/sidebar'; // use the admin user to login @@ -101,7 +102,7 @@ test.describe('Policy page should work properly', () => { hasText: policy, }); - await expect(policyElement).toBeVisible(); + await getElementWithPagination(page, policyElement, false); } } ); @@ -361,14 +362,18 @@ test.describe('Policy page should work properly', () => { effect: 'allow', }, ]; - const policyLocator = `[data-testid="policy-name"][href="/settings/access/policies/${encodeURIComponent( - policy.data.name - )}"]`; + const policyLocator = page.locator( + `[data-testid="policy-name"][href="/settings/access/policies/${encodeURIComponent( + policy.data.name + )}"]` + ); await policy.create(apiContext, policyRules); await page.reload(); - await page.locator(policyLocator).click(); + + await getElementWithPagination(page, policyLocator); + await page.getByTestId('manage-button').click(); await page.getByTestId('delete-button').click(); await page @@ -376,7 +381,7 @@ test.describe('Policy page should work properly', () => { .fill('DELETE'); await page.locator('[data-testid="confirm-button"]').click(); - await expect(page.locator(policyLocator)).not.toBeVisible(); + await expect(policyLocator).not.toBeVisible(); await policy.delete(apiContext); await afterAction(); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Roles.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Roles.spec.ts index 60d24c8e18a..5fe4892e568 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Roles.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Roles.spec.ts @@ -20,7 +20,10 @@ import { toastNotification, uuid, } from '../../utils/common'; -import { removePolicyFromRole } from '../../utils/roles'; +import { + getElementWithPagination, + removePolicyFromRole, +} from '../../utils/roles'; import { settingClick } from '../../utils/sidebar'; const policies = { @@ -107,11 +110,10 @@ test('Roles page should work properly', async ({ page }) => { // Navigating to roles tab to verify the added role await page.locator('[data-testid="breadcrumb-link"]').first().click(); - await expect( - page.getByRole('cell', { name: roleName, exact: true }) - ).toBeVisible(); + const roleLocator = page.getByRole('cell', { name: roleName, exact: true }); + + await getElementWithPagination(page, roleLocator, false); - // second policy should be visible on tooltip await page .locator(`[data-row-key="${roleName}"] [data-testid="plus-more-count"]`) .click(); @@ -147,7 +149,11 @@ test('Roles page should work properly', async ({ page }) => { await test.step('Edit created role', async () => { await settingClick(page, GlobalSettingOptions.ROLES); // Edit description - await page.getByRole('link', { name: roleName }).click(); + + const roleLocator = page.getByRole('link', { name: roleName }); + + await getElementWithPagination(page, roleLocator); + await page.locator('[data-testid="edit-description"]').click(); await page.locator(descriptionBox).fill(`${description}-updated`); @@ -176,7 +182,11 @@ test('Roles page should work properly', async ({ page }) => { await test.step('Add new policy to created role', async () => { await settingClick(page, GlobalSettingOptions.ROLES); - await page.getByRole('link', { name: roleName }).click(); + + const roleLocator = page.getByRole('link', { name: roleName }); + + await getElementWithPagination(page, roleLocator); + // Asserting navigation await page.locator('[data-testid="add-policy"]').click(); // Checking the added policy is selected in the add policy modal @@ -199,7 +209,11 @@ test('Roles page should work properly', async ({ page }) => { await test.step('Remove added policy from created role', async () => { await settingClick(page, GlobalSettingOptions.ROLES); - await page.getByRole('link', { name: roleName }).click(); + + const roleLocator = page.getByRole('link', { name: roleName }); + + await getElementWithPagination(page, roleLocator); + // Asserting navigation await removePolicyFromRole( page, @@ -215,7 +229,11 @@ test('Roles page should work properly', async ({ page }) => { await test.step('Check if last policy is not removed', async () => { await settingClick(page, GlobalSettingOptions.ROLES); - await page.getByRole('link', { name: roleName }).click(); + + const roleLocator = page.getByRole('link', { name: roleName }); + + await getElementWithPagination(page, roleLocator); + // Removing second policy from the role await removePolicyFromRole( page, @@ -247,9 +265,13 @@ test('Roles page should work properly', async ({ page }) => { await test.step('Delete created Role', async () => { await settingClick(page, GlobalSettingOptions.ROLES); - await page - .locator(`[data-testid="delete-action-${updatedRoleName}"]`) - .click(); + + const roleLocator = page.locator( + `[data-testid="delete-action-${updatedRoleName}"]` + ); + + await getElementWithPagination(page, roleLocator); + await page .locator('[data-testid="confirmation-text-input"]') .fill('DELETE'); @@ -269,20 +291,24 @@ test('Delete role action from manage button options', async ({ page }) => { const role = new RolesClass(); const policies = ['ApplicationBotPolicy']; - const roleLocator = `[data-testid="role-name"][href="/settings/access/roles/${encodeURIComponent( - role.data.name - )}"]`; + const roleLocator = page.locator( + `[data-testid="role-name"][href="/settings/access/roles/${encodeURIComponent( + role.data.name + )}"]` + ); await role.create(apiContext, policies); await settingClick(page, GlobalSettingOptions.ROLES); - await page.locator(roleLocator).click(); + + await getElementWithPagination(page, roleLocator); + await page.getByTestId('manage-button').click(); await page.getByTestId('delete-button').click(); await page.locator('[data-testid="confirmation-text-input"]').fill('DELETE'); await page.locator('[data-testid="confirm-button"]').click(); - await expect(page.locator(roleLocator)).not.toBeVisible(); + await expect(roleLocator).not.toBeVisible(); await role.delete(apiContext); await afterAction(); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/utils/roles.ts b/openmetadata-ui/src/main/resources/ui/playwright/utils/roles.ts index a82a571bd77..079fede23b0 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/roles.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/roles.ts @@ -10,7 +10,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { expect, Page } from '@playwright/test'; +import { expect, Locator, Page } from '@playwright/test'; export const removePolicyFromRole = async ( page: Page, @@ -28,3 +28,33 @@ export const removePolicyFromRole = async ( await page.locator('[type="button"]:has-text("Confirm")').click(); }; + +// TODO: Remove this function once we have a better way to get locator using SearchBar +export const getElementWithPagination = async ( + page: Page, + locator: Locator, + click = true +) => { + let hasNext = true; + + while (hasNext) { + if (await locator.isVisible()) { + click && (await locator.click()); + + break; + } + + const nextBtn = page.locator('[data-testid="next"]'); + await nextBtn.waitFor({ state: 'visible' }); + + hasNext = !(await nextBtn.getAttribute('disabled')); + + if (!hasNext) { + throw new Error('Element not found and no more pages to paginate.'); + } + + await nextBtn.click(); + + await page.waitForSelector('[data-testid="loader"]', { state: 'detached' }); + } +};