PLAYWRIGHT: fix the flaky delete step failing in entity and serviceEntity around bar (#21671)

This commit is contained in:
Ashish Gupta 2025-06-12 15:10:49 +05:30 committed by Shailesh Parmar
parent 81469afd63
commit 5f60bc0b2e
11 changed files with 76 additions and 53 deletions

View File

@ -52,8 +52,11 @@ const entity = new TableClass();
const entity2 = new TableClass();
const entity3 = new TableClass();
const entity4 = new TableClass();
const entity5 = new TableClass();
const user1 = new UserClass();
const user2 = new UserClass();
const user3 = new UserClass();
const user4 = new UserClass();
const adminUser = new UserClass();
const test = base.extend<{ page: Page }>({
@ -76,8 +79,11 @@ test.describe('Activity feed', () => {
await entity2.create(apiContext);
await entity3.create(apiContext);
await entity4.create(apiContext);
await entity5.create(apiContext);
await user1.create(apiContext);
await user2.create(apiContext);
await user3.create(apiContext);
await user4.create(apiContext);
await afterAction();
});
@ -88,8 +94,11 @@ test.describe('Activity feed', () => {
await entity2.delete(apiContext);
await entity3.delete(apiContext);
await entity4.delete(apiContext);
await entity5.delete(apiContext);
await user1.delete(apiContext);
await user2.delete(apiContext);
await user3.delete(apiContext);
await user4.delete(apiContext);
await adminUser.delete(apiContext);
await afterAction();
@ -504,18 +513,18 @@ test.describe('Activity feed', () => {
test('Check Task Filter in Landing Page Widget', async ({ browser }) => {
const { page: page1, afterAction: afterActionUser1 } =
await performUserLogin(browser, user1);
const { page: page2, afterAction: afterActionUser2 } =
await performUserLogin(browser, user2);
const { page: page2, afterAction: afterActionUser3 } =
await performUserLogin(browser, user3);
await base.step('Create and Assign Task to User 2', async () => {
await base.step('Create and Assign Task to User 3', async () => {
await redirectToHomePage(page1);
await entity.visitEntityPage(page1);
// Create task for the user 2
// Create task for the user 3
await page1.getByTestId('request-description').click();
await createDescriptionTask(page1, {
term: entity.entity.displayName,
assignee: user2.responseData.name,
assignee: user3.responseData.name,
});
await afterActionUser1();
@ -544,6 +553,7 @@ test.describe('Activity feed', () => {
.click();
await taskResponse;
await page2.waitForLoadState('networkidle');
await expect(
page2.locator(
@ -571,7 +581,7 @@ test.describe('Activity feed', () => {
await page2.getByTestId('task-feed-card').locator('.ant-avatar').hover();
await expect(
page2.getByText(user2.responseData.displayName).first()
page2.getByText(user3.responseData.displayName).first()
).toBeVisible();
// Check the Task based on Created by me task filter
@ -592,21 +602,23 @@ test.describe('Activity feed', () => {
await page2.getByTestId('task-feed-card').locator('.ant-avatar').hover();
await expect(
page2.getByText(user2.responseData.displayName).first()
page2.getByText(user3.responseData.displayName).first()
).toBeVisible();
await afterActionUser2();
await afterActionUser3();
});
});
test('Verify feed count', async ({ page }) => {
await redirectToHomePage(page);
await entity.visitEntityPage(page);
await entity5.visitEntityPage(page);
await page.getByTestId('request-description').click();
await createDescriptionTask(page, {
term: entity.entity.displayName,
assignee: user1.responseData.name,
term: entity5.entity.displayName,
assignee: user4.responseData.name,
});
await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
await page.waitForLoadState('networkidle');
await expect(page.getByTestId('left-panel-task-count')).toHaveText('1');
});

View File

@ -122,9 +122,6 @@ test.describe('Bulk Edit Entity', () => {
);
await page.click('[data-testid="bulk-edit-table"]');
// Adding manual wait for the file to load
await page.waitForTimeout(500);
await page.waitForSelector('[data-testid="loader"]', {
state: 'detached',
});
@ -138,6 +135,9 @@ test.describe('Bulk Edit Entity', () => {
page.getByRole('button', { name: 'Previous' })
).not.toBeVisible();
// Adding manual wait for the file to load
await page.waitForTimeout(500);
// Click on first cell and edit
await page.click(
@ -260,9 +260,6 @@ test.describe('Bulk Edit Entity', () => {
await page.click('[data-testid="bulk-edit-table"]');
// Adding manual wait for the file to load
await page.waitForTimeout(500);
await page.waitForSelector('[data-testid="loader"]', {
state: 'detached',
});
@ -276,6 +273,9 @@ test.describe('Bulk Edit Entity', () => {
page.getByRole('button', { name: 'Previous' })
).not.toBeVisible();
// Adding manual wait for the file to load
await page.waitForTimeout(500);
// click on last row first cell
await page.click(
'.InovuaReactDataGrid__row--first > .InovuaReactDataGrid__row-cell-wrap > .InovuaReactDataGrid__cell--first'
@ -410,9 +410,6 @@ test.describe('Bulk Edit Entity', () => {
await page.click('[data-testid="bulk-edit-table"]');
// Adding manual wait for the file to load
await page.waitForTimeout(500);
// Adding some assertion to make sure that CSV loaded correctly
await expect(
page.locator('.InovuaReactDataGrid__header-layout')
@ -422,6 +419,9 @@ test.describe('Bulk Edit Entity', () => {
page.getByRole('button', { name: 'Previous' })
).not.toBeVisible();
// Adding manual wait for the file to load
await page.waitForTimeout(500);
// Click on first cell and edit
await page.click(
'.InovuaReactDataGrid__row--first > .InovuaReactDataGrid__row-cell-wrap > .InovuaReactDataGrid__cell--first'
@ -524,9 +524,6 @@ test.describe('Bulk Edit Entity', () => {
await page.click('[data-testid="bulk-edit-table"]');
// Adding manual wait for the file to load
await page.waitForTimeout(500);
// Adding some assertion to make sure that CSV loaded correctly
await expect(
page.locator('.InovuaReactDataGrid__header-layout')
@ -536,6 +533,9 @@ test.describe('Bulk Edit Entity', () => {
page.getByRole('button', { name: 'Previous' })
).not.toBeVisible();
// Adding manual wait for the file to load
await page.waitForTimeout(500);
// click on row first cell
await page.click(
'.InovuaReactDataGrid__row--first > .InovuaReactDataGrid__row-cell-wrap > .InovuaReactDataGrid__cell--first'
@ -623,9 +623,6 @@ test.describe('Bulk Edit Entity', () => {
await page.click('[data-testid="bulk-edit-table"]');
// Adding manual wait for the file to load
await page.waitForTimeout(500);
// Adding some assertion to make sure that CSV loaded correctly
await expect(
page.locator('.InovuaReactDataGrid__header-layout')
@ -635,6 +632,9 @@ test.describe('Bulk Edit Entity', () => {
page.getByRole('button', { name: 'Previous' })
).not.toBeVisible();
// Adding manual wait for the file to load
await page.waitForTimeout(500);
// Click on first cell and edit
await page.click(
'.InovuaReactDataGrid__row--first > .InovuaReactDataGrid__row-cell-wrap > .InovuaReactDataGrid__cell--first'

View File

@ -137,9 +137,8 @@ test.describe('Tag Page with Admin Roles', () => {
test('Rename Tag name', async ({ adminPage }) => {
await redirectToHomePage(adminPage);
const res = adminPage.waitForResponse(`/api/v1/tags/name/*`);
await tag.visitPage(adminPage);
await res;
await adminPage.getByTestId('manage-button').click();
await expect(
@ -163,9 +162,8 @@ test.describe('Tag Page with Admin Roles', () => {
test('Restyle Tag', async ({ adminPage }) => {
await redirectToHomePage(adminPage);
const res = adminPage.waitForResponse(`/api/v1/tags/name/*`);
await tag.visitPage(adminPage);
await res;
await adminPage.getByTestId('manage-button').click();
await expect(
@ -189,9 +187,8 @@ test.describe('Tag Page with Admin Roles', () => {
test('Edit Tag Description', async ({ adminPage }) => {
await redirectToHomePage(adminPage);
const res = adminPage.waitForResponse(`/api/v1/tags/name/*`);
await tag.visitPage(adminPage);
await res;
await adminPage.getByTestId('edit-description').click();
await expect(adminPage.getByRole('dialog')).toBeVisible();
@ -212,9 +209,7 @@ test.describe('Tag Page with Admin Roles', () => {
test('Delete a Tag', async ({ adminPage }) => {
await redirectToHomePage(adminPage);
const res = adminPage.waitForResponse(`/api/v1/tags/name/*`);
await tag.visitPage(adminPage);
await res;
await adminPage.getByTestId('manage-button').click();
await expect(

View File

@ -98,6 +98,8 @@ const test = base.extend<{
});
base.beforeAll('Setup pre-requests', async ({ browser }) => {
test.slow(true);
const { apiContext, afterAction } = await performAdminLogin(browser);
await adminUser.create(apiContext);
@ -116,6 +118,8 @@ base.beforeAll('Setup pre-requests', async ({ browser }) => {
});
base.afterAll('Cleanup', async ({ browser }) => {
test.slow(true);
const { apiContext, afterAction } = await performAdminLogin(browser);
await adminUser.delete(apiContext);
await dataConsumerUser.delete(apiContext);
@ -417,7 +421,7 @@ test.describe('User with Data Steward Roles', () => {
await addOwner({
page: adminPage,
owner: user.responseData.displayName,
owner: user.responseData.displayName ?? user.responseData.name,
type: 'Users',
endpoint: EntityTypeEndpoint.Table,
dataTestId: 'data-assets-header',
@ -471,9 +475,10 @@ test.describe('User Profile Feed Interactions', () => {
);
const avatar = adminPage
.locator('[data-testid="message-container"]')
.locator('#feedData [data-testid="message-container"]')
.first()
.locator('[data-testid="profile-avatar"]');
.locator('[data-testid="profile-avatar"]')
.first();
await avatar.hover();
await adminPage.waitForSelector('.ant-popover-card');

View File

@ -187,6 +187,7 @@ test('GlossaryTerm', async ({ page }) => {
});
await page.reload();
await page.waitForLoadState('networkidle');
const versionPageResponse = page.waitForResponse(
`/api/v1/glossaryTerms/${term2.responseData.id}/versions/0.2`
);
@ -199,14 +200,10 @@ test('GlossaryTerm', async ({ page }) => {
)
).toBeVisible();
await page.waitForLoadState('networkidle');
const glossaryTermsRes = page.waitForResponse(
'/api/v1/glossaryTerms/name/**'
);
await page.getByRole('dialog').getByRole('img').click();
await page.waitForLoadState('networkidle');
await glossaryTermsRes;
await addMultiOwner({
@ -219,11 +216,11 @@ test('GlossaryTerm', async ({ page }) => {
});
await page.reload();
await page.waitForLoadState('networkidle');
await page.click('[data-testid="version-button"]');
await versionPageResponse;
await page.waitForLoadState('networkidle');
const diffLocator = page.locator(
'[data-testid="glossary-reviewer"] [data-testid="diff-added"]'
);

View File

@ -69,7 +69,10 @@ export class TagClass {
this.responseData.classification.name,
this.responseData.classification.displayName
);
const res = page.waitForResponse(`/api/v1/tags/name/*`);
await page.getByTestId(this.data.name).click();
await res;
await page.waitForLoadState('networkidle');
}
async create(apiContext: APIRequestContext) {

View File

@ -58,8 +58,8 @@ export const getAuthContext = async (token: string) => {
export const redirectToHomePage = async (page: Page) => {
await page.goto('/');
await page.waitForLoadState('networkidle');
await page.waitForURL('**/my-data');
await page.waitForLoadState('networkidle');
};
export const removeLandingBanner = async (page: Page) => {

View File

@ -43,10 +43,10 @@ export const visitEntityPage = async (data: {
dataTestId: string;
}) => {
const { page, searchTerm, dataTestId } = data;
await page.waitForLoadState('networkidle');
const waitForSearchResponse = page.waitForResponse(
'/api/v1/search/query?q=*index=dataAsset*'
);
await page.waitForLoadState('networkidle');
await page.getByTestId('searchBox').fill(searchTerm);
await waitForSearchResponse;
await page.getByTestId(dataTestId).getByTestId('data-name').click();
@ -1367,10 +1367,9 @@ export const hardDeleteEntity = async (
await page.click('[data-testid="confirm-button"]');
await deleteResponse;
await toastNotification(
page,
/deleted successfully!/,
BIG_ENTITY_DELETE_TIMEOUT
await expect(page.getByTestId('alert-bar')).toHaveText(
/(deleted successfully!|Delete operation initiated)/,
{ timeout: BIG_ENTITY_DELETE_TIMEOUT }
);
};

View File

@ -46,9 +46,19 @@ export const createGlossaryTermRowDetails = () => {
export const fillTextInputDetails = async (page: Page, text: string) => {
await page.keyboard.press('Enter', { delay: 100 });
const isVisible = await page
.locator('.ant-layout-content')
.getByRole('textbox')
.isVisible();
if (!isVisible) {
await page.keyboard.press('Enter', { delay: 100 });
}
const textboxLocator = page
.locator('.ant-layout-content')
.getByRole('textbox');
await textboxLocator.fill(text);
await textboxLocator.press('Enter', { delay: 100 });
};

View File

@ -91,9 +91,7 @@ export const addAssetsToTag = async (
tag: TagClass,
otherAsset?: EntityClass[]
) => {
const res = page.waitForResponse(`/api/v1/tags/name/*`);
await tag.visitPage(page);
await res;
await page.waitForSelector(
'[data-testid="tags-container"] [data-testid="loader"]',
@ -334,9 +332,7 @@ export const verifyTagPageUI = async (
limitedAccess = false
) => {
await redirectToHomePage(page);
const res = page.waitForResponse(`/api/v1/tags/name/*`);
await tag.visitPage(page);
await res;
await page.waitForSelector(
'[data-testid="tags-container"] [data-testid="loader"]',
@ -363,6 +359,7 @@ export const verifyTagPageUI = async (
await page.getByRole('link', { name: classificationName }).click();
classificationTable;
const res = page.waitForResponse(`/api/v1/tags/name/*`);
await page.getByTestId(tag.data.name).click();
await res;

View File

@ -578,6 +578,11 @@ export const checkStewardServicesPermissions = async (page: Page) => {
await queryResponse;
// Perform search actions
await page.click('[data-testid="search-dropdown-Data Assets"]');
await page.getByTestId('drop-down-menu').getByTestId('loader').waitFor({
state: 'detached',
});
await page.locator('[data-testid="table-checkbox"]').scrollIntoViewIfNeeded();
await page.click('[data-testid="table-checkbox"]');