Skip to content

Commit 2ac973f

Browse files
committed
Merge remote-tracking branch 'origin/1.12.5' into 1.12.5
2 parents dc36b10 + 93ac30b commit 2ac973f

7 files changed

Lines changed: 162 additions & 120 deletions

File tree

openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ImpactAnalysis.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ test.describe('Impact Analysis', () => {
581581

582582
await page.getByRole('button', { name: 'Upstream' }).click();
583583
await expect(
584-
page.getByRole('button', { name: 'Upstream 0' })
584+
page.getByRole('button', { name: 'Upstream 5' })
585585
).toBeVisible();
586586
});
587587

openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageFilters.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ test.describe('Lineage Filters', () => {
8888
const [depth1Entity, ...depth2ndEntities] = entities;
8989

9090
test.beforeAll(async ({ browser }) => {
91+
test.setTimeout(120_000);
92+
9193
const { apiContext, afterAction } = await getDefaultAdminAPIContext(
9294
browser
9395
);
@@ -125,6 +127,8 @@ test.describe('Lineage Filters', () => {
125127
});
126128

127129
test.beforeEach(async ({ page }) => {
130+
test.setTimeout(120_000);
131+
128132
await redirectToHomePage(page);
129133
await lineageEntity.visitEntityPage(page);
130134
await visitLineageTab(page);

openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/PlatformLineage.spec.ts

Lines changed: 115 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { TableClass } from '../../../support/entity/TableClass';
1818
import {
1919
getDefaultAdminAPIContext,
2020
redirectToHomePage,
21-
uuid,
2221
} from '../../../utils/common';
2322
import { waitForAllLoadersToDisappear } from '../../../utils/entity';
2423
import {
@@ -29,149 +28,153 @@ import {
2928
import { sidebarClick } from '../../../utils/sidebar';
3029
import { test } from '../../fixtures/pages';
3130

32-
// Create a table with '/' in the name to test encoding functionality
33-
const tableNameWithSlash = `pw-table-with/slash-${uuid()}`;
34-
const table = new TableClass(tableNameWithSlash);
35-
36-
test.beforeAll(async ({ browser }) => {
37-
const { apiContext, afterAction } = await getDefaultAdminAPIContext(browser);
38-
await table.create(apiContext);
39-
40-
await table.patch({
41-
apiContext,
42-
patchData: [
43-
{
44-
op: 'add',
45-
value: {
46-
type: 'domain',
47-
id: EntityDataClass.domain1.responseData.id,
31+
let table: TableClass;
32+
33+
test.describe.serial('Platform lineage', () => {
34+
test.beforeAll(async ({ browser }) => {
35+
table = new TableClass();
36+
37+
const { apiContext, afterAction } = await getDefaultAdminAPIContext(
38+
browser
39+
);
40+
await table.create(apiContext);
41+
42+
await table.patch({
43+
apiContext,
44+
patchData: [
45+
{
46+
op: 'add',
47+
value: {
48+
type: 'domain',
49+
id: EntityDataClass.domain1.responseData.id,
50+
},
51+
path: '/domains/0',
4852
},
49-
path: '/domains/0',
50-
},
51-
],
52-
});
53+
],
54+
});
5355

54-
await afterAction();
55-
});
56+
await afterAction();
57+
});
5658

57-
test.beforeEach(async ({ page }) => {
58-
await redirectToHomePage(page);
59-
await table.visitEntityPage(page);
60-
await visitLineageTab(page);
61-
await performZoomOut(page);
62-
});
59+
test.beforeEach(async ({ page }) => {
60+
await redirectToHomePage(page);
61+
await table.visitEntityPage(page);
62+
await visitLineageTab(page);
63+
await performZoomOut(page);
64+
});
6365

64-
test('Verify table search with special characters as handled', async ({
65-
page,
66-
}) => {
67-
await redirectToHomePage(page);
68-
const db = table.databaseResponseData.name;
66+
test('Verify table search with special characters as handled', async ({
67+
page,
68+
}) => {
69+
await redirectToHomePage(page);
70+
const db = table.databaseResponseData.name;
6971

70-
await sidebarClick(page, SidebarItem.LINEAGE);
72+
await sidebarClick(page, SidebarItem.LINEAGE);
7173

72-
await page.getByTestId('search-entity-select').waitFor();
73-
await page.getByTestId('search-entity-select').click();
74+
await page.getByTestId('search-entity-select').waitFor();
75+
await page.getByTestId('search-entity-select').click();
7476

75-
await page.fill(
76-
'[data-testid="search-entity-select"] .ant-select-selection-search-input',
77-
table.entity.name
78-
);
77+
await page.fill(
78+
'[data-testid="search-entity-select"] .ant-select-selection-search-input',
79+
table.entity.name
80+
);
7981

80-
await page.waitForRequest(
81-
(req) =>
82-
req.url().includes('/api/v1/search/query') &&
83-
req.url().includes('deleted=false')
84-
);
82+
await page.waitForRequest(
83+
(req) =>
84+
req.url().includes('/api/v1/search/query') &&
85+
req.url().includes('deleted=false')
86+
);
8587

86-
await page.locator('.ant-select-dropdown').waitFor();
88+
await page.locator('.ant-select-dropdown').waitFor();
8789

88-
const nodeFqn = get(table, 'entityResponseData.fullyQualifiedName');
89-
const dbFqn = get(
90-
table,
91-
'entityResponseData.database.fullyQualifiedName',
92-
''
93-
);
94-
await page
95-
.locator(`[data-testid="node-suggestion-${nodeFqn}"]`)
96-
.dispatchEvent('click');
90+
const nodeFqn = get(table, 'entityResponseData.fullyQualifiedName');
91+
const dbFqn = get(
92+
table,
93+
'entityResponseData.database.fullyQualifiedName',
94+
''
95+
);
96+
await page
97+
.locator(`[data-testid="node-suggestion-${nodeFqn}"]`)
98+
.dispatchEvent('click');
9799

98-
await page.waitForResponse('/api/v1/lineage/getLineage?*');
100+
await page.waitForResponse('/api/v1/lineage/getLineage?*');
99101

100-
await expect(page.locator('[data-testid="lineage-details"]')).toBeVisible();
102+
await expect(page.locator('[data-testid="lineage-details"]')).toBeVisible();
101103

102-
await expect(
103-
page.locator(`[data-testid="lineage-node-${nodeFqn}"]`)
104-
).toBeVisible();
104+
await expect(
105+
page.locator(`[data-testid="lineage-node-${nodeFqn}"]`)
106+
).toBeVisible();
105107

106-
await redirectToHomePage(page);
107-
await sidebarClick(page, SidebarItem.LINEAGE);
108-
await page.getByTestId('search-entity-select').waitFor();
109-
await page.click('[data-testid="search-entity-select"]');
108+
await redirectToHomePage(page);
109+
await sidebarClick(page, SidebarItem.LINEAGE);
110+
await page.getByTestId('search-entity-select').waitFor();
111+
await page.click('[data-testid="search-entity-select"]');
110112

111-
await page.fill(
112-
'[data-testid="search-entity-select"] .ant-select-selection-search-input',
113-
db
114-
);
115-
await page.getByTestId(`node-suggestion-${dbFqn}`).waitFor();
116-
await page.getByTestId(`node-suggestion-${dbFqn}`).dispatchEvent('click');
117-
await page.waitForResponse('/api/v1/lineage/getLineage?*');
113+
await page.fill(
114+
'[data-testid="search-entity-select"] .ant-select-selection-search-input',
115+
db
116+
);
117+
await page.getByTestId(`node-suggestion-${dbFqn}`).waitFor();
118+
await page.getByTestId(`node-suggestion-${dbFqn}`).dispatchEvent('click');
119+
await page.waitForResponse('/api/v1/lineage/getLineage?*');
118120

119-
await expect(page.getByTestId('lineage-details')).toBeVisible();
121+
await expect(page.getByTestId('lineage-details')).toBeVisible();
120122

121-
await clickLineageNode(page, dbFqn);
123+
await clickLineageNode(page, dbFqn);
122124

123-
await expect(
124-
page.locator('.lineage-entity-panel').getByTestId('entity-header-title')
125-
).toBeVisible();
126-
});
125+
await expect(
126+
page.locator('.lineage-entity-panel').getByTestId('entity-header-title')
127+
).toBeVisible();
128+
});
127129

128-
test('Verify service platform view', async ({ page }) => {
129-
await page.getByTestId('lineage-layer-btn').click();
130+
test('Verify service platform view', async ({ page }) => {
131+
await page.getByTestId('lineage-layer-btn').click();
130132

131-
const serviceBtn = page.getByTestId('lineage-layer-service-btn');
132-
await expect(serviceBtn).toBeVisible();
133+
const serviceBtn = page.getByTestId('lineage-layer-service-btn');
134+
await expect(serviceBtn).toBeVisible();
133135

134-
await serviceBtn.click();
135-
await page.keyboard.press('Escape');
136+
await serviceBtn.click();
137+
await page.keyboard.press('Escape');
136138

137-
await page.getByTestId('lineage-layer-btn').click();
138-
await expect(serviceBtn).toHaveClass(/Mui-selected/);
139-
});
139+
await page.getByTestId('lineage-layer-btn').click();
140+
await expect(serviceBtn).toHaveClass(/Mui-selected/);
141+
});
140142

141-
test('Verify domain platform view', async ({ page }) => {
142-
await page.getByTestId('lineage-layer-btn').click();
143+
test('Verify domain platform view', async ({ page }) => {
144+
await page.getByTestId('lineage-layer-btn').click();
143145

144-
const domainBtn = page.getByTestId('lineage-layer-domain-btn');
145-
await expect(domainBtn).toBeVisible();
146+
const domainBtn = page.getByTestId('lineage-layer-domain-btn');
147+
await expect(domainBtn).toBeVisible();
146148

147-
await domainBtn.click();
148-
await page.keyboard.press('Escape');
149+
await domainBtn.click();
150+
await page.keyboard.press('Escape');
149151

150-
await page.getByTestId('lineage-layer-btn').click();
151-
await expect(domainBtn).toHaveClass(/Mui-selected/);
152+
await page.getByTestId('lineage-layer-btn').click();
153+
await expect(domainBtn).toHaveClass(/Mui-selected/);
152154

153-
await page.keyboard.press('Escape');
155+
await page.keyboard.press('Escape');
154156

155-
await waitForAllLoadersToDisappear(page);
156-
});
157+
await waitForAllLoadersToDisappear(page);
158+
});
157159

158-
test('Verify platform view switching', async ({ page }) => {
159-
await page.getByTestId('lineage-layer-btn').click();
160+
test('Verify platform view switching', async ({ page }) => {
161+
await page.getByTestId('lineage-layer-btn').click();
160162

161-
const serviceBtn = page.getByTestId('lineage-layer-service-btn');
162-
const domainBtn = page.getByTestId('lineage-layer-domain-btn');
163+
const serviceBtn = page.getByTestId('lineage-layer-service-btn');
164+
const domainBtn = page.getByTestId('lineage-layer-domain-btn');
163165

164-
await serviceBtn.click();
165-
await page.keyboard.press('Escape');
166+
await serviceBtn.click();
167+
await page.keyboard.press('Escape');
166168

167-
await page.getByTestId('lineage-layer-btn').click();
168-
await expect(serviceBtn).toHaveClass(/Mui-selected/);
169-
await expect(domainBtn).not.toHaveClass(/Mui-selected/);
169+
await page.getByTestId('lineage-layer-btn').click();
170+
await expect(serviceBtn).toHaveClass(/Mui-selected/);
171+
await expect(domainBtn).not.toHaveClass(/Mui-selected/);
170172

171-
await domainBtn.click();
172-
await page.keyboard.press('Escape');
173+
await domainBtn.click();
174+
await page.keyboard.press('Escape');
173175

174-
await page.getByTestId('lineage-layer-btn').click();
175-
await expect(domainBtn).toHaveClass(/Mui-selected/);
176-
await expect(serviceBtn).not.toHaveClass(/Mui-selected/);
176+
await page.getByTestId('lineage-layer-btn').click();
177+
await expect(domainBtn).toHaveClass(/Mui-selected/);
178+
await expect(serviceBtn).not.toHaveClass(/Mui-selected/);
179+
});
177180
});

openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/UserDetails.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,19 @@ test.describe('User with different Roles', () => {
518518
.getByText('Application bot role', { exact: true })
519519
.click();
520520

521+
await adminPage.getByTestId('profile-edit-roles-select').click();
522+
523+
await adminPage.locator('.ant-select-dropdown').waitFor({
524+
state: 'hidden',
525+
});
526+
527+
const saveTeamsResponse = adminPage.waitForResponse(
528+
(response) =>
529+
response.url().includes('/api/v1/users/') &&
530+
response.request().method() === 'PATCH'
531+
);
521532
await adminPage.getByTestId('user-profile-edit-roles-save-button').click();
533+
await saveTeamsResponse;
522534

523535
await expect(adminPage.getByTestId('user-profile-roles')).toContainText(
524536
'Application bot role'

openmetadata-ui/src/main/resources/ui/playwright/utils/entity.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ export const visitEntityPage = async (data: {
7575
}
7676

7777
const waitForSearchResponse = page.waitForResponse(
78-
'/api/v1/search/query?q=*index=dataAsset*'
78+
(response) =>
79+
response.url().includes('/api/v1/search/query') &&
80+
response.url().includes('index=dataAsset')
7981
);
8082
await page.getByTestId('searchBox').fill(searchTerm);
8183
await waitForSearchResponse;
@@ -169,14 +171,20 @@ export const addOwnerWithoutValidation = async ({
169171
(await usersTab.getAttribute('aria-selected')) === 'true';
170172

171173
if (!isTabAlreadySelected) {
174+
// The call with size > 0 only fires after the tab click.
172175
const userListResponse = page.waitForResponse(
173-
'/api/v1/search/query?q=&index=user_search_index&*'
176+
(response) =>
177+
response.url().includes('/api/v1/search/query?q=&index=user') &&
178+
!response.url().includes('size=0') &&
179+
response.status() === 200
174180
);
175181
await usersTab.click();
182+
await expect(usersTab).toHaveAttribute('aria-selected', 'true');
176183
await userListResponse;
177184
}
178185
}
179-
await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
186+
187+
await waitForAllLoadersToDisappear(page);
180188

181189
const ownerSearchBar = await page
182190
.getByTestId(`owner-select-${lowerCase(type)}-search-bar`)

openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,10 +517,10 @@ export const AuthProvider = ({
517517
// Refresh the token and retry the requests in the queue
518518
tokenService.current
519519
.refreshToken()
520-
.then((token) => {
520+
.then(async (token) => {
521521
if (token) {
522522
// Retry the pending requests
523-
initializeAxiosInterceptors();
523+
await initializeAxiosInterceptors();
524524
pendingRequests.forEach(({ resolve, reject, config }) => {
525525
axiosClient.request(config).then(resolve).catch(reject);
526526
});

openmetadata-ui/src/main/resources/ui/src/utils/Auth/TokenService/TokenServiceUtil.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ class TokenService {
8787
this.setRefreshInProgress();
8888

8989
try {
90-
const token = await getOidcToken();
91-
const { isExpired, timeoutExpiry } = extractDetailsFromToken(token);
90+
const oldToken = await getOidcToken();
91+
const { isExpired, timeoutExpiry } = extractDetailsFromToken(oldToken);
9292

9393
// If token is expired or timeoutExpiry is less than 0 then try to silent signIn
9494
if (isExpired || timeoutExpiry <= 0) {
@@ -160,6 +160,21 @@ class TokenService {
160160
isTokenUpdateInProgress() {
161161
return localStorage.getItem(REFRESH_IN_PROGRESS_KEY) === 'true';
162162
}
163+
164+
private async waitForTokenPersistence(oldToken: string) {
165+
const maxAttempts = 20;
166+
const delayMs = 50;
167+
168+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
169+
await new Promise((resolve) => setTimeout(resolve, delayMs));
170+
171+
const currentToken = await getOidcToken();
172+
173+
if (currentToken && currentToken !== oldToken) {
174+
return;
175+
}
176+
}
177+
}
163178
}
164179

165180
export default TokenService;

0 commit comments

Comments
 (0)