Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
fac67f0
fix(ui): correct Governance form and graph theming
shah-harshit Oct 7, 2026
f044437
fix(ui): preserve relation palettes across graph rendering paths
shah-harshit Oct 7, 2026
3ace220
refactor(ui): remove obsolete SVG color fallback
shah-harshit Oct 7, 2026
092e981
fix(ui): validate selected task assignees instead of search text
shah-harshit Oct 7, 2026
b0c1c8c
refactor(ui): drop dead Task styles and legacy classes
shah-harshit Oct 7, 2026
f10cb2b
test(ui): target core task form controls in Playwright
shah-harshit Oct 7, 2026
ea1134f
chore(playwright): auto-refresh impact-map.generated.json
github-actions[bot] Oct 7, 2026
127a56c
fix(ui): prune stale lint suppressions and resolve Sonar issues
shah-harshit Oct 7, 2026
4e3a615
test(ui): lower no-wait-for-selector suppression ratchet to 14
shah-harshit Oct 7, 2026
9c9ea48
test(ui): target core assignee and schema field controls in remaining…
shah-harshit Oct 8, 2026
73daca2
chore(playwright): auto-refresh impact-map.generated.json
github-actions[bot] Oct 8, 2026
0bcad5e
Merge remote-tracking branch 'origin/main' into fix/governance-dark-t…
shah-harshit Oct 8, 2026
85b3607
chore(playwright): auto-refresh impact-map.generated.json
github-actions[bot] Oct 8, 2026
5760615
test(ui): clear the selected assignee before reassigning an incident
shah-harshit Oct 8, 2026
b71edf0
test(ui): choose the incident root cause from the core Select
shah-harshit Oct 8, 2026
826d6c0
Merge remote-tracking branch 'origin/main' into fix/governance-dark-t…
shah-harshit Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/playwright/impact-map.generated.json
Original file line number Diff line number Diff line change
Expand Up @@ -8247,6 +8247,8 @@
],
"specs": [
"playwright/e2e/Features/AccessControlSettings.spec.ts",
"playwright/e2e/Features/IncidentManager.spec.ts",
"playwright/e2e/Features/Tasks/TaskAssigneeManagement.spec.ts",
"playwright/e2e/Pages/CustomProperties.spec.ts"
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@
},
"playwright/e2e/Features/IncidentManager.spec.ts": {
"om-playwright/no-positional-locator": {
"count": 10
"count": 9
}
},
"playwright/e2e/Features/IngestionListNameSorting.spec.ts": {
Expand Down Expand Up @@ -352,7 +352,7 @@
},
"playwright/e2e/Features/Tasks/TaskCustomFormWorkflow.spec.ts": {
"om-playwright/no-positional-locator": {
"count": 6
"count": 4
}
},
"playwright/e2e/Features/Tasks/TaskDashboardEntity.spec.ts": {
Expand Down Expand Up @@ -598,9 +598,6 @@
"playwright/e2e/Pages/TasksUIFlow.spec.ts": {
"om-playwright/no-positional-locator": {
"count": 5
},
"playwright/no-wait-for-selector": {
"count": 4
}
},
"playwright/e2e/Pages/TestSuite.spec.ts": {
Expand Down Expand Up @@ -770,7 +767,7 @@
},
"playwright/utils/incidentManager.ts": {
"om-playwright/no-positional-locator": {
"count": 8
"count": 7
}
},
"playwright/utils/lineage.ts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,19 @@
) => {
const reassignModal = await openIncidentReassignModal(page, testCaseName);
const assigneeSelect = reassignModal.getByTestId('select-assignee');
const assigneeSelector = assigneeSelect.locator('.ant-select-selector');
const assigneeInput = assigneeSelect.getByRole('combobox');
const assigneeOption = page.getByTestId(assignee.name.toLowerCase());

await expect(assigneeSelector).toBeVisible();
await assigneeSelector.click();
// Single-select core Autocomplete hides its input while an item is selected.
const selectedAssignee = assigneeSelect.getByTestId(
'autocomplete-selected-item'
);
if (await selectedAssignee.isVisible()) {
await selectedAssignee.getByRole('button').click();
}

await expect(assigneeInput).toBeVisible();
await assigneeInput.click();
await assigneeInput.fill(assignee.displayName);
await expect(assigneeOption).toBeVisible({ timeout: ACTION_TIMEOUT });

Expand Down Expand Up @@ -600,7 +607,7 @@
const testCasePageUrl = `/test-case/${encodeURIComponent(
testCase.fullyQualifiedName
)}/test-case-results`;
actorPage = await browser.newPage();

Check warning on line 610 in openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/IncidentManager.spec.ts

View workflow job for this annotation

GitHub Actions / checkstyle

Prefer the `page` fixture (test.use({ storageState })) over browser.newPage() + manual login for single-user admin tests. For multi-user tests that need a second non-admin page, this warning is expected — no action needed
await user1.signIn(actorPage);
const testCaseResponse = actorPage.waitForResponse(
'/api/v1/dataQuality/testCases/name/*?fields=*'
Expand Down Expand Up @@ -733,7 +740,7 @@
*/
await test.step('Resolve incident', async () => {
const currentUrl = actorPage.url();
actorPage = await browser.newPage();

Check warning on line 743 in openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/IncidentManager.spec.ts

View workflow job for this annotation

GitHub Actions / checkstyle

Prefer the `page` fixture (test.use({ storageState })) over browser.newPage() + manual login for single-user admin tests. For multi-user tests that need a second non-admin page, this warning is expected — no action needed
await user3.signIn(actorPage);
const testCaseResponse = actorPage.waitForResponse(
'/api/v1/dataQuality/testCases/name/*?fields=*'
Expand All @@ -745,15 +752,14 @@
await openIncidentTaskTab(actorPage, true);
const resolveModal = await openIncidentResolveDialog(actorPage);
const resolveTextareas = resolveModal.locator('textarea');
const resolveReasonSelect = resolveModal
.locator('.ant-select-selector')
.first();
const resolveReasonSelect = resolveModal.getByRole('button', {
name: /Root Cause/i,
});
const textareaCount = await resolveTextareas.count();

if (await resolveReasonSelect.isVisible().catch(() => false)) {
await resolveReasonSelect.click();
await actorPage.keyboard.press('ArrowDown');
await actorPage.keyboard.press('Enter');
await actorPage.getByRole('option', { name: 'MissingData' }).click();
await resolveTextareas.first().fill('test');
} else if (textareaCount >= 2) {
await resolveTextareas.nth(0).fill('Missing Data');
Expand Down Expand Up @@ -1126,7 +1132,7 @@
await afterAction();
}

await page.click('[data-testid="select-assignee"]');
await page.click('[data-testid="select-assignee"] input');
const assigneeOption = page.locator(
`[data-testid="${assigneeTestCase.username}"]`
);
Expand All @@ -1152,7 +1158,8 @@
);
await page
.getByTestId('select-assignee')
.getByLabel('close-circle')
.getByTestId('autocomplete-selected-item')
.getByRole('button')
.click();
await nonAssigneeFilterRes;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ test.describe('Task Assignee Management', () => {

const existingAssigneeRemoveButton = page
.locator(
'[data-testid="select-assignee"] .ant-select-selection-item-remove'
'[data-testid="select-assignee"] [data-testid="autocomplete-selected-item"] button'
)
.first();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ test.describe('Task Creation - Request Description', () => {
await expect(page.getByTestId('form-container')).toBeVisible();

// Verify title contains description request info
const titleField = page.locator('#title');
const titleField = page.getByTestId('title').locator('input');
await expect(titleField).toBeVisible();
const titleValue = await titleField.inputValue();
expect(titleValue.toLowerCase()).toContain('description');
Expand Down Expand Up @@ -144,7 +144,7 @@ test.describe('Task Creation - Request Description', () => {
await expect(page.getByTestId('form-container')).toBeVisible();

// Verify this is a column-level task by checking the about field references a column
const titleField = page.locator('#title');
const titleField = page.getByTestId('title').locator('input');
const titleValue = await titleField.inputValue();
expect(titleValue.toLowerCase()).toContain('description');

Expand Down Expand Up @@ -175,9 +175,7 @@ test.describe('Task Creation - Request Description', () => {
await expect(page.getByTestId('form-container')).toBeVisible();

// Assignee field - search and select user
const assigneeInput = page.locator(
'[data-testid="select-assignee"] .ant-select-selector input'
);
const assigneeInput = page.locator('[data-testid="select-assignee"] input');
await assigneeInput.click();

// Search for user
Expand Down Expand Up @@ -217,7 +215,7 @@ test.describe('Task Creation - Request Description', () => {
await submitBtn.click();

// Should show validation error for assignee field
const assigneeError = page.locator('.ant-form-item-explain-error');
const assigneeError = page.getByTestId('assignees').getByText(/required/i);
await expect(assigneeError).toBeVisible();
});
});
Expand Down Expand Up @@ -274,7 +272,7 @@ test.describe('Task Creation - Request Tags', () => {
await expect(page.getByTestId('form-container')).toBeVisible();

// Verify title contains tag info
const titleField = page.locator('#title');
const titleField = page.getByTestId('title').locator('input');
const titleValue = await titleField.inputValue();
expect(titleValue.toLowerCase()).toContain('tag');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,16 +474,12 @@ test.describe.serial(

const visibleModal = page.getByRole('dialog').first();
await expect(visibleModal).toBeVisible();
const proposedTextField = visibleModal
.locator('.ant-form-item')
.filter({ hasText: 'Proposed Text' })
.getByRole('textbox')
.first();
const reviewNotesField = visibleModal
.locator('.ant-form-item')
.filter({ hasText: 'Review Notes' })
.getByRole('textbox')
.first();
const proposedTextField = visibleModal.getByRole('textbox', {
name: /Proposed Text/,
});
const reviewNotesField = visibleModal.getByRole('textbox', {
name: /Review Notes/,
});

await proposedTextField.fill(updatedDescription);
await reviewNotesField.fill(updatedReviewNotes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ test('Classification Page', async ({ page }) => {

await page.click('[data-testid="request-entity-tags"]');

await page.click('[data-testid="select-assignee"]');
await page.click('[data-testid="select-assignee"] input');
const assigneeResponse = page.waitForResponse(
'/api/v1/search/query?q=*&index=user*team*'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ const createDescriptionTaskViaUI = async (
) => {
await page.getByTestId('request-description').click();

await page.waitForSelector('#title', { state: 'visible' });
await expect(page.getByTestId('title').locator('input')).toBeVisible();

expect(await page.locator('#title').inputValue()).toContain(
`description for ${entityType}`
);
expect(
await page.getByTestId('title').locator('input').inputValue()
).toContain(`description for ${entityType}`);

await selectAssignee(page, assigneeName);

Expand All @@ -84,11 +84,11 @@ const createTagTaskViaUI = async (
) => {
await page.getByTestId('request-entity-tags').click();

await page.waitForSelector('#title', { state: 'visible' });
await expect(page.getByTestId('title').locator('input')).toBeVisible();

expect(await page.locator('#title').inputValue()).toContain(
`tags for ${entityType}`
);
expect(
await page.getByTestId('title').locator('input').inputValue()
).toContain(`tags for ${entityType}`);

await selectAssignee(page, assigneeName);
await addTagSuggestion({
Expand Down Expand Up @@ -326,9 +326,11 @@ test.describe('Task Workflow - Table Column Tasks', () => {
});

await test.step('Fill task form and submit', async () => {
await page.waitForSelector('#title', { state: 'visible' });
await expect(page.getByTestId('title').locator('input')).toBeVisible();

expect(await page.locator('#title').inputValue()).toContain('columns');
expect(
await page.getByTestId('title').locator('input').inputValue()
).toContain('columns');

await selectAssignee(page, userName);

Expand Down Expand Up @@ -375,9 +377,11 @@ test.describe('Task Workflow - Table Column Tasks', () => {
});

await test.step('Fill tag task form and submit', async () => {
await page.waitForSelector('#title', { state: 'visible' });
await expect(page.getByTestId('title').locator('input')).toBeVisible();

expect(await page.locator('#title').inputValue()).toContain('columns');
expect(
await page.getByTestId('title').locator('input').inputValue()
).toContain('columns');

await selectAssignee(page, userName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ test('the suppressions baseline matches its recorded state exactly', () => {
// DomainFilterQueryFilter, ActivityFeed, and SearchExport; the core
// Popover/Dropdown migration also removed a positional locator.
// Removing the S3 sample-data storage tests and scoping
// ChangeSummaryBadge's button lookup remove three more positional locators.
'om-playwright/no-positional-locator': 602,
// ChangeSummaryBadge's button lookup remove three more positional locators;
// the core assignee/schema-field selectors in the task and incident specs
// remove three more.
'om-playwright/no-positional-locator': 598,
'om-playwright/require-assertion-per-test': 1,
'playwright/no-skipped-test': 2,
'playwright/no-wait-for-selector': 18,
'playwright/no-wait-for-selector': 14,
};

assert.deepStrictEqual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1280,26 +1280,22 @@ export const createDescriptionTaskForGlossary = async (
const entityType = isGlossary ? 'glossary' : 'glossaryTerm';
const entityName = get(entity, 'responseData.displayName');

await expect(page.locator('#title')).toHaveValue(
await expect(page.getByTestId('title').locator('input')).toHaveValue(
`${
addDescription ? 'Update' : 'Request'
} description for ${entityType} ${entityName}`
);

if (isUndefined(value.assignee)) {
await expect(
page.locator('[data-testid="select-assignee"] > .ant-select-selector')
).toHaveText(value.assignee ?? '');
await expect(page.getByTestId('select-assignee')).toContainText(
value.assignee ?? ''
);

await expect(
page.locator(
'[data-testid="select-assignee"] > .ant-select-selector input'
)
page.locator('[data-testid="select-assignee"] input')
).toBeDisabled();
} else {
const assigneeField = page.locator(
'[data-testid="select-assignee"] > .ant-select-selector #assignees'
);
const assigneeField = page.locator('[data-testid="select-assignee"] input');
await assigneeField.click();

const userSearchResponse = page.waitForResponse(
Expand Down Expand Up @@ -1336,25 +1332,21 @@ export const createTagTaskForGlossary = async (
const entityType = isGlossary ? 'glossary' : 'glossaryTerm';
const entityName = get(entity, 'responseData.displayName');

await expect(page.locator('#title')).toHaveValue(
await expect(page.getByTestId('title').locator('input')).toHaveValue(
`Request tags for ${entityType} ${entityName}`
);

if (isUndefined(value.assignee)) {
await expect(
page.locator('[data-testid="select-assignee"] > .ant-select-selector')
).toHaveText(value.assignee ?? '');
await expect(page.getByTestId('select-assignee')).toContainText(
value.assignee ?? ''
);

await expect(
page.locator(
'[data-testid="select-assignee"] > .ant-select-selector input'
)
page.locator('[data-testid="select-assignee"] input')
).toBeDisabled();
} else {
// select assignee
const assigneeField = page.locator(
'[data-testid="select-assignee"] > .ant-select-selector #assignees'
);
const assigneeField = page.locator('[data-testid="select-assignee"] input');
await assigneeField.click();
const userSearchResponse = page.waitForResponse(
`/api/v1/search/query?q=*${value.assignee}**&index=user%2Cteam*`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,17 +189,25 @@ export const addAssigneeFromPopoverWidget = async (data: {

const assigneeModal = page.locator('.ant-modal-content').last();
const assigneeSelect = assigneeModal.getByTestId('select-assignee');
const assigneeSelector = assigneeSelect.locator('.ant-select-selector');
const assigneeInput = assigneeSelect.locator('input').last();
const assigneeInput = assigneeSelect.locator('input');
const assigneeOption = page.getByTestId(user.name).first();
const normalizedAssigneeOption = page
.getByTestId(user.name.toLowerCase())
.first();

await expect(assigneeModal).toBeVisible();
await expect(assigneeSelector).toBeVisible();

await assigneeSelector.click();
// Single-select core Autocomplete hides its input while an item is selected.
const selectedAssignee = assigneeSelect.getByTestId(
'autocomplete-selected-item'
);
if (await selectedAssignee.isVisible()) {
await selectedAssignee.getByRole('button').click();
}

await expect(assigneeInput).toBeVisible();

await assigneeInput.click();
await assigneeInput.fill(user.displayName);

if (await assigneeOption.isVisible().catch(() => false)) {
Expand Down
Loading
Loading