2024-06-18 11:38:46 +05:30
|
|
|
|
/*
|
|
|
|
|
* Copyright 2024 Collate.
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
import { expect, Page } from '@playwright/test';
|
2024-07-30 15:05:56 +05:30
|
|
|
|
import { get, isUndefined } from 'lodash';
|
2024-06-18 11:38:46 +05:30
|
|
|
|
import { SidebarItem } from '../constant/sidebar';
|
|
|
|
|
import { GLOSSARY_TERM_PATCH_PAYLOAD } from '../constant/version';
|
2024-07-16 17:20:36 +05:30
|
|
|
|
import { DashboardClass } from '../support/entity/DashboardClass';
|
2024-06-18 11:38:46 +05:30
|
|
|
|
import { EntityTypeEndpoint } from '../support/entity/Entity.interface';
|
2024-07-16 17:20:36 +05:30
|
|
|
|
import { TableClass } from '../support/entity/TableClass';
|
|
|
|
|
import { TopicClass } from '../support/entity/TopicClass';
|
2024-07-30 15:05:56 +05:30
|
|
|
|
import { Glossary } from '../support/glossary/Glossary';
|
2024-06-24 17:41:28 +05:30
|
|
|
|
import {
|
2024-07-30 15:05:56 +05:30
|
|
|
|
GlossaryData,
|
2024-06-24 17:41:28 +05:30
|
|
|
|
GlossaryTermData,
|
2024-07-30 15:05:56 +05:30
|
|
|
|
} from '../support/glossary/Glossary.interface';
|
|
|
|
|
import { GlossaryTerm } from '../support/glossary/GlossaryTerm';
|
2024-06-24 17:41:28 +05:30
|
|
|
|
import {
|
2024-08-29 11:38:31 +05:30
|
|
|
|
clickOutside,
|
2024-06-24 17:41:28 +05:30
|
|
|
|
getApiContext,
|
|
|
|
|
INVALID_NAMES,
|
|
|
|
|
NAME_MAX_LENGTH_VALIDATION_ERROR,
|
|
|
|
|
NAME_VALIDATION_ERROR,
|
|
|
|
|
redirectToHomePage,
|
2024-08-29 11:38:31 +05:30
|
|
|
|
toastNotification,
|
2024-06-24 17:41:28 +05:30
|
|
|
|
} from './common';
|
2024-07-29 23:06:39 -07:00
|
|
|
|
import { addMultiOwner } from './entity';
|
2024-06-18 11:38:46 +05:30
|
|
|
|
import { sidebarClick } from './sidebar';
|
2024-08-29 11:38:31 +05:30
|
|
|
|
import { TaskDetails, TASK_OPEN_FETCH_LINK } from './task';
|
2024-06-18 11:38:46 +05:30
|
|
|
|
|
2024-06-24 17:41:28 +05:30
|
|
|
|
export const descriptionBox =
|
|
|
|
|
'.toastui-editor-md-container > .toastui-editor > .ProseMirror';
|
|
|
|
|
|
|
|
|
|
export const checkDisplayName = async (page: Page, displayName: string) => {
|
|
|
|
|
await expect(page.getByTestId('entity-header-display-name')).toHaveText(
|
|
|
|
|
displayName
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const selectActiveGlossary = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
glossaryName: string
|
|
|
|
|
) => {
|
|
|
|
|
const menuItem = page.getByRole('menuitem', { name: glossaryName });
|
|
|
|
|
const isSelected = await menuItem.evaluate((element) => {
|
|
|
|
|
return element.classList.contains('ant-menu-item-selected');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!isSelected) {
|
|
|
|
|
const glossaryResponse = page.waitForResponse('/api/v1/glossaryTerms*');
|
|
|
|
|
await menuItem.click();
|
|
|
|
|
await glossaryResponse;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-07-01 20:27:34 +05:30
|
|
|
|
export const selectActiveGlossaryTerm = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
glossaryTermName: string
|
|
|
|
|
) => {
|
|
|
|
|
await page.getByTestId(glossaryTermName).click();
|
|
|
|
|
|
2024-07-29 23:06:39 -07:00
|
|
|
|
await expect(
|
2024-07-01 20:27:34 +05:30
|
|
|
|
page.locator('[data-testid="entity-header-display-name"]')
|
|
|
|
|
).toContainText(glossaryTermName);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const goToAssetsTab = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
displayName: string,
|
2024-08-13 18:43:03 +05:30
|
|
|
|
count = 0
|
2024-07-01 20:27:34 +05:30
|
|
|
|
) => {
|
|
|
|
|
await selectActiveGlossaryTerm(page, displayName);
|
|
|
|
|
await page.getByTestId('assets').click();
|
|
|
|
|
await page.waitForSelector('.ant-tabs-tab-active:has-text("Assets")');
|
|
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
|
page.getByTestId('assets').getByTestId('filter-count')
|
2024-08-13 18:43:03 +05:30
|
|
|
|
).toContainText(`${count}`);
|
2024-07-01 20:27:34 +05:30
|
|
|
|
};
|
|
|
|
|
|
2024-06-18 11:38:46 +05:30
|
|
|
|
export const removeReviewer = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
endpoint: EntityTypeEndpoint
|
|
|
|
|
) => {
|
|
|
|
|
const patchResponse = page.waitForResponse(`/api/v1/${endpoint}/*`);
|
|
|
|
|
|
|
|
|
|
await page.click('[data-testid="edit-reviewer-button"]');
|
|
|
|
|
|
|
|
|
|
await page.click('[data-testid="clear-all-button"]');
|
|
|
|
|
|
|
|
|
|
await page.click('[data-testid="selectable-list-update-btn"]');
|
|
|
|
|
|
|
|
|
|
await patchResponse;
|
|
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
|
page.locator('[data-testid="glossary-reviewer"] [data-testid="Add"]')
|
|
|
|
|
).toBeVisible();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Create a glossary and two glossary terms, then link them with a related term relationship
|
|
|
|
|
export const setupGlossaryAndTerms = async (page: Page) => {
|
|
|
|
|
const glossary = new Glossary();
|
2024-06-24 17:41:28 +05:30
|
|
|
|
const term1 = new GlossaryTerm(glossary);
|
|
|
|
|
const term2 = new GlossaryTerm(glossary);
|
2024-06-18 11:38:46 +05:30
|
|
|
|
|
|
|
|
|
// Get API context for performing operations
|
|
|
|
|
const { apiContext, afterAction } = await getApiContext(page);
|
|
|
|
|
|
|
|
|
|
// Create glossary and terms
|
|
|
|
|
await glossary.create(apiContext);
|
|
|
|
|
await term1.create(apiContext);
|
|
|
|
|
await term2.create(apiContext);
|
|
|
|
|
|
|
|
|
|
// Prepare the payload for linking term2 as a related term to term1
|
|
|
|
|
const relatedTermLink = {
|
|
|
|
|
op: 'add',
|
|
|
|
|
path: '/relatedTerms/0',
|
|
|
|
|
value: {
|
|
|
|
|
id: term1.responseData.id,
|
|
|
|
|
type: 'glossaryTerm',
|
|
|
|
|
displayName: term1.responseData.displayName,
|
|
|
|
|
name: term1.responseData.name,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Update term2 to include term1 as a related term
|
|
|
|
|
await term2.patch(apiContext, [
|
|
|
|
|
...GLOSSARY_TERM_PATCH_PAYLOAD,
|
|
|
|
|
relatedTermLink,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const cleanup = async () => {
|
|
|
|
|
await glossary.delete(apiContext);
|
|
|
|
|
await afterAction();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return { glossary, term1, term2, cleanup };
|
|
|
|
|
};
|
2024-06-24 17:41:28 +05:30
|
|
|
|
|
|
|
|
|
export const validateForm = async (page) => {
|
|
|
|
|
// Error messages
|
|
|
|
|
await expect(page.locator('#name_help')).toHaveText('Name is required');
|
|
|
|
|
await expect(page.locator('#description_help')).toHaveText(
|
|
|
|
|
'Description is required'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Max length validation
|
|
|
|
|
await page.locator('[data-testid="name"]').type(INVALID_NAMES.MAX_LENGTH);
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('#name_help')).toHaveText(
|
|
|
|
|
NAME_MAX_LENGTH_VALIDATION_ERROR
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// With special char validation
|
|
|
|
|
await page.locator('[data-testid="name"]').clear();
|
|
|
|
|
await page
|
|
|
|
|
.locator('[data-testid="name"]')
|
|
|
|
|
.type(INVALID_NAMES.WITH_SPECIAL_CHARS);
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('#name_help')).toHaveText(NAME_VALIDATION_ERROR);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const addTeamAsReviewer = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
teamName: string,
|
|
|
|
|
activatorBtnDataTestId: string,
|
|
|
|
|
dataTestId?: string,
|
|
|
|
|
isSelectableInsideForm = false
|
|
|
|
|
) => {
|
|
|
|
|
const teamsResponse = page.waitForResponse(
|
|
|
|
|
'/api/v1/search/query?q=*&from=0&size=*&index=team_search_index&sort_field=displayName.keyword&sort_order=asc'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const teamsSearchResponse = page.waitForResponse(
|
|
|
|
|
`api/v1/search/query?q=*${encodeURI(teamName)}*`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await page.click(`[data-testid="${activatorBtnDataTestId}"]`);
|
|
|
|
|
|
|
|
|
|
await expect(page.locator("[data-testid='select-owner-tabs']")).toBeVisible();
|
|
|
|
|
|
|
|
|
|
await teamsResponse;
|
|
|
|
|
|
|
|
|
|
await page.fill('[data-testid="owner-select-teams-search-bar"]', teamName);
|
|
|
|
|
await teamsSearchResponse;
|
|
|
|
|
|
2024-08-13 18:43:03 +05:30
|
|
|
|
const ownerItem = page.locator(`.ant-popover [title="${teamName}"]`);
|
2024-06-24 17:41:28 +05:30
|
|
|
|
|
2024-08-13 18:43:03 +05:30
|
|
|
|
if (isSelectableInsideForm) {
|
|
|
|
|
await ownerItem.click();
|
|
|
|
|
} else {
|
|
|
|
|
const patchRequest = page.waitForRequest(
|
|
|
|
|
(request) => request.method() === 'PATCH'
|
|
|
|
|
);
|
|
|
|
|
await ownerItem.click();
|
|
|
|
|
await patchRequest;
|
2024-06-24 17:41:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
|
page.locator(`[data-testid=${dataTestId ?? 'owner-link'}]`)
|
|
|
|
|
).toContainText(teamName);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const createGlossary = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
glossaryData: GlossaryData,
|
|
|
|
|
bValidateForm: boolean
|
|
|
|
|
) => {
|
|
|
|
|
// Click on the "Add Glossary" button
|
|
|
|
|
await page.click('[data-testid="add-glossary"]');
|
|
|
|
|
|
|
|
|
|
// Validate redirection to the add glossary page
|
|
|
|
|
await page.waitForSelector('[data-testid="form-heading"]');
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('[data-testid="form-heading"]')).toHaveText(
|
|
|
|
|
'Add Glossary'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Perform glossary creation steps
|
|
|
|
|
await page.click('[data-testid="save-glossary"]');
|
|
|
|
|
|
|
|
|
|
if (bValidateForm) {
|
|
|
|
|
await validateForm(page);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await page.fill('[data-testid="name"]', glossaryData.name);
|
|
|
|
|
|
|
|
|
|
await page.fill(descriptionBox, glossaryData.description);
|
|
|
|
|
|
2024-07-05 14:06:27 +05:30
|
|
|
|
await expect(
|
|
|
|
|
page.locator('[data-testid="form-item-alert"]')
|
|
|
|
|
).not.toBeVisible();
|
|
|
|
|
|
2024-06-24 17:41:28 +05:30
|
|
|
|
if (glossaryData.mutuallyExclusive) {
|
|
|
|
|
await page.click('[data-testid="mutually-exclusive-button"]');
|
2024-07-05 14:06:27 +05:30
|
|
|
|
|
|
|
|
|
await expect(page.locator('[data-testid="form-item-alert"]')).toBeVisible();
|
2024-06-24 17:41:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (glossaryData.tags && glossaryData.tags.length > 0) {
|
|
|
|
|
const tagsResponse = page.waitForResponse('/api/v1/search/query');
|
|
|
|
|
|
|
|
|
|
// Add tag
|
|
|
|
|
await page.click('[data-testid="tag-selector"]');
|
|
|
|
|
await page.fill(
|
|
|
|
|
'[data-testid="tag-selector"] input[type="search"]',
|
|
|
|
|
glossaryData.tags[0]
|
|
|
|
|
);
|
|
|
|
|
await tagsResponse;
|
|
|
|
|
await page.click(`[data-testid="tag-${glossaryData.tags[0]}"]`);
|
|
|
|
|
await page.click('[data-testid="right-panel"]');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (glossaryData.reviewers.length > 0) {
|
|
|
|
|
// Add reviewer
|
|
|
|
|
if (glossaryData.reviewers[0].type === 'user') {
|
|
|
|
|
await addMultiOwner({
|
|
|
|
|
page,
|
|
|
|
|
ownerNames: glossaryData.reviewers.map((reviewer) => reviewer.name),
|
|
|
|
|
activatorBtnDataTestId: 'add-reviewers',
|
|
|
|
|
resultTestId: 'reviewers-container',
|
|
|
|
|
endpoint: EntityTypeEndpoint.Glossary,
|
|
|
|
|
isSelectableInsideForm: true,
|
2024-08-13 18:43:03 +05:30
|
|
|
|
type: 'Users',
|
2024-06-24 17:41:28 +05:30
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
await addTeamAsReviewer(
|
|
|
|
|
page,
|
|
|
|
|
glossaryData.reviewers[0].name,
|
|
|
|
|
'add-reviewers',
|
|
|
|
|
'reviewers-container',
|
|
|
|
|
true
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const glossaryResponse = page.waitForResponse('/api/v1/glossaries');
|
|
|
|
|
await page.click('[data-testid="save-glossary"]');
|
|
|
|
|
await glossaryResponse;
|
|
|
|
|
|
|
|
|
|
await expect(page).toHaveURL(/\/glossary\//);
|
|
|
|
|
|
|
|
|
|
await checkDisplayName(page, glossaryData.name);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const verifyGlossaryDetails = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
glossaryDetails: GlossaryData
|
|
|
|
|
) => {
|
|
|
|
|
await page
|
|
|
|
|
.getByRole('menuitem', { name: glossaryDetails.name })
|
|
|
|
|
.locator('span')
|
|
|
|
|
.click();
|
|
|
|
|
|
|
|
|
|
await checkDisplayName(page, glossaryDetails.name);
|
|
|
|
|
|
|
|
|
|
const viewerContainerText = await page.textContent(
|
|
|
|
|
'[data-testid="viewer-container"]'
|
|
|
|
|
);
|
|
|
|
|
|
2024-07-29 23:06:39 -07:00
|
|
|
|
await expect(viewerContainerText).toContain(glossaryDetails.description);
|
2024-06-24 17:41:28 +05:30
|
|
|
|
|
|
|
|
|
// Owner
|
2024-07-29 23:06:39 -07:00
|
|
|
|
if (glossaryDetails.owners.length > 0) {
|
|
|
|
|
for (const owner of glossaryDetails.owners) {
|
|
|
|
|
await expect(
|
|
|
|
|
page
|
|
|
|
|
.getByTestId('glossary-right-panel-owner-link')
|
|
|
|
|
.getByTestId('owner-label')
|
|
|
|
|
).toContainText(owner.name);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-24 17:41:28 +05:30
|
|
|
|
|
|
|
|
|
// Reviewer
|
|
|
|
|
if (glossaryDetails.reviewers.length > 0) {
|
|
|
|
|
for (const reviewer of glossaryDetails.reviewers) {
|
2024-07-29 23:06:39 -07:00
|
|
|
|
await expect(
|
|
|
|
|
page.getByTestId('glossary-reviewer').getByTestId('owner-link')
|
|
|
|
|
).toContainText(reviewer.name);
|
2024-06-24 17:41:28 +05:30
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Tags
|
|
|
|
|
if (glossaryDetails.tags && glossaryDetails.tags.length > 0) {
|
|
|
|
|
const tagVisibility = await page.isVisible(
|
|
|
|
|
`[data-testid="tag-${glossaryDetails.tags[0]}"]`
|
|
|
|
|
);
|
|
|
|
|
|
2024-07-29 23:06:39 -07:00
|
|
|
|
await expect(tagVisibility).toBe(true);
|
2024-06-24 17:41:28 +05:30
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const deleteGlossary = async (page: Page, glossary: GlossaryData) => {
|
|
|
|
|
await page
|
|
|
|
|
.getByRole('menuitem', { name: glossary.displayName })
|
|
|
|
|
.locator('span')
|
|
|
|
|
.click();
|
|
|
|
|
|
|
|
|
|
await page.click('[data-testid="manage-button"]');
|
|
|
|
|
await page.click('[data-testid="delete-button"]');
|
|
|
|
|
|
|
|
|
|
await page.waitForSelector('[data-testid="delete-confirmation-modal"]');
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('[role="dialog"]')).toBeVisible();
|
|
|
|
|
await expect(page.locator('[data-testid="modal-header"]')).toBeVisible();
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('[data-testid="modal-header"]')).toContainText(
|
|
|
|
|
glossary.displayName
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await page.fill('[data-testid="confirmation-text-input"]', 'DELETE');
|
|
|
|
|
|
2024-08-13 18:43:03 +05:30
|
|
|
|
const deleteGlossary = page.waitForResponse(
|
2024-06-24 17:41:28 +05:30
|
|
|
|
(response) =>
|
|
|
|
|
response.url().includes('/api/v1/glossaries/') &&
|
|
|
|
|
response.request().method() === 'DELETE' &&
|
|
|
|
|
response.status() === 200
|
|
|
|
|
);
|
|
|
|
|
|
2024-08-13 18:43:03 +05:30
|
|
|
|
await page.click('[data-testid="confirm-button"]');
|
|
|
|
|
|
|
|
|
|
// Wait for the API response and verify the status code
|
|
|
|
|
await deleteGlossary;
|
|
|
|
|
|
2024-06-24 17:41:28 +05:30
|
|
|
|
// Display toast notification
|
|
|
|
|
await expect(page.locator('.toast-notification')).toHaveText(
|
|
|
|
|
'"Glossary" deleted successfully!'
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const fillGlossaryTermDetails = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
term: GlossaryTermData,
|
|
|
|
|
validateCreateForm = true
|
|
|
|
|
) => {
|
|
|
|
|
await page.click('[data-testid="add-new-tag-button-header"]');
|
|
|
|
|
|
|
|
|
|
await page.waitForSelector('[role="dialog"].edit-glossary-modal');
|
|
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
|
page.locator('[role="dialog"].edit-glossary-modal')
|
|
|
|
|
).toBeVisible();
|
|
|
|
|
await expect(page.locator('.ant-modal-title')).toContainText(
|
|
|
|
|
'Add Glossary Term'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Validation should work
|
|
|
|
|
await page.click('[data-testid="save-glossary-term"]');
|
|
|
|
|
|
|
|
|
|
if (validateCreateForm) {
|
|
|
|
|
await validateForm(page);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('[data-testid="name"]')).toBeVisible();
|
|
|
|
|
|
|
|
|
|
await page.locator('[data-testid="name"]').fill(term.name);
|
|
|
|
|
|
|
|
|
|
await expect(page.locator(descriptionBox)).toBeVisible();
|
|
|
|
|
|
|
|
|
|
await page.locator(descriptionBox).fill(term.description);
|
|
|
|
|
|
|
|
|
|
const synonyms = (term.synonyms ?? '').split(',');
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('[data-testid="synonyms"]')).toBeVisible();
|
|
|
|
|
|
|
|
|
|
for (const synonym of synonyms) {
|
|
|
|
|
if (synonym === '') {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
await page
|
|
|
|
|
.locator('[data-testid="synonyms"] input[type="search"]')
|
|
|
|
|
.fill(`${synonym}`);
|
|
|
|
|
await page
|
|
|
|
|
.locator('[data-testid="synonyms"] input[type="search"]')
|
|
|
|
|
.press('Enter');
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 14:06:27 +05:30
|
|
|
|
await expect(
|
|
|
|
|
page.locator('[data-testid="form-item-alert"]')
|
|
|
|
|
).not.toBeVisible();
|
|
|
|
|
|
2024-06-24 17:41:28 +05:30
|
|
|
|
if (term.mutuallyExclusive) {
|
|
|
|
|
await page.click('[data-testid="mutually-exclusive-button"]');
|
2024-07-05 14:06:27 +05:30
|
|
|
|
|
|
|
|
|
await expect(page.locator('[data-testid="form-item-alert"]')).toBeVisible();
|
2024-06-24 17:41:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('[data-testid="add-reference"]')).toBeVisible();
|
|
|
|
|
|
|
|
|
|
await page.click('[data-testid="add-reference"]');
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('#name-0')).toBeVisible();
|
|
|
|
|
|
|
|
|
|
await page.locator('#name-0').fill('test');
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('#url-0')).toBeVisible();
|
|
|
|
|
|
|
|
|
|
await page.locator('#url-0').fill('https://test.com');
|
|
|
|
|
|
|
|
|
|
if (term.icon) {
|
|
|
|
|
await page.locator('[data-testid="icon-url"]').fill(term.icon);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (term.color) {
|
|
|
|
|
await page.locator('[data-testid="color-color-input"]').fill(term.color);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-30 15:05:56 +05:30
|
|
|
|
if (!isUndefined(term.owners)) {
|
2024-06-24 17:41:28 +05:30
|
|
|
|
await addMultiOwner({
|
|
|
|
|
page,
|
2024-07-30 15:05:56 +05:30
|
|
|
|
ownerNames: term.owners.map((owner) => owner.name),
|
2024-06-24 17:41:28 +05:30
|
|
|
|
activatorBtnDataTestId: 'add-owner',
|
|
|
|
|
resultTestId: 'owner-container',
|
|
|
|
|
endpoint: EntityTypeEndpoint.GlossaryTerm,
|
|
|
|
|
isSelectableInsideForm: true,
|
2024-08-13 18:43:03 +05:30
|
|
|
|
type: 'Users',
|
2024-06-24 17:41:28 +05:30
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const validateGlossaryTermTask = async (page: Page, term: GlossaryTermData) => {
|
|
|
|
|
await page.click('[data-testid="activity_feed"]');
|
2024-08-15 07:59:50 +05:30
|
|
|
|
const taskFeeds = page.waitForResponse(TASK_OPEN_FETCH_LINK);
|
2024-06-24 17:41:28 +05:30
|
|
|
|
await page
|
|
|
|
|
.getByTestId('global-setting-left-panel')
|
|
|
|
|
.getByText('Tasks')
|
|
|
|
|
.click();
|
|
|
|
|
|
|
|
|
|
await taskFeeds;
|
|
|
|
|
|
|
|
|
|
const taskFeedCards = page.locator('[data-testid="task-feed-card"]');
|
|
|
|
|
|
|
|
|
|
// Filter to find the specific card that contains the text
|
|
|
|
|
const cardWithText = taskFeedCards.filter({
|
|
|
|
|
has: page.locator('[data-testid="entity-link"]', {
|
|
|
|
|
hasText: term.name,
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await expect(cardWithText).toHaveCount(1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const approveGlossaryTermTask = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
term: GlossaryTermData
|
|
|
|
|
) => {
|
|
|
|
|
await validateGlossaryTermTask(page, term);
|
|
|
|
|
const taskResolve = page.waitForResponse('/api/v1/feed/tasks/*/resolve');
|
2024-07-22 12:45:07 +05:30
|
|
|
|
await page.getByRole('button', { name: 'Approve' }).click();
|
2024-06-24 17:41:28 +05:30
|
|
|
|
await taskResolve;
|
|
|
|
|
|
|
|
|
|
// Display toast notification
|
|
|
|
|
await expect(page.locator('.Toastify__toast-body')).toHaveText(
|
|
|
|
|
/Task resolved successfully/
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const validateGlossaryTerm = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
term: GlossaryTermData,
|
|
|
|
|
status: 'Draft' | 'Approved'
|
|
|
|
|
) => {
|
|
|
|
|
// eslint-disable-next-line no-useless-escape
|
|
|
|
|
const escapedFqn = term.fullyQualifiedName.replace(/\"/g, '\\"');
|
|
|
|
|
const termSelector = `[data-row-key="${escapedFqn}"]`;
|
|
|
|
|
const statusSelector = `[data-testid="${escapedFqn}-status"]`;
|
|
|
|
|
|
|
|
|
|
await expect(page.locator(termSelector)).toContainText(term.name);
|
|
|
|
|
await expect(page.locator(statusSelector)).toContainText(status);
|
|
|
|
|
|
|
|
|
|
if (status === 'Draft') {
|
|
|
|
|
await validateGlossaryTermTask(page, term);
|
|
|
|
|
await page.click('[data-testid="terms"]');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const createGlossaryTerm = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
term: GlossaryTermData,
|
|
|
|
|
status: 'Draft' | 'Approved',
|
|
|
|
|
validateCreateForm = true
|
|
|
|
|
) => {
|
|
|
|
|
await fillGlossaryTermDetails(page, term, validateCreateForm);
|
|
|
|
|
const glossaryTermResponse = page.waitForResponse('/api/v1/glossaryTerms');
|
|
|
|
|
await page.click('[data-testid="save-glossary-term"]');
|
|
|
|
|
await glossaryTermResponse;
|
|
|
|
|
await validateGlossaryTerm(page, term, status);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const createGlossaryTerms = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
glossary: GlossaryData
|
|
|
|
|
) => {
|
|
|
|
|
await selectActiveGlossary(page, glossary.name);
|
|
|
|
|
|
|
|
|
|
const termStatus = glossary.reviewers.length > 0 ? 'Draft' : 'Approved';
|
|
|
|
|
|
|
|
|
|
for (const term of glossary.terms) {
|
|
|
|
|
await createGlossaryTerm(page, term.data, termStatus, false);
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-07-16 17:20:36 +05:30
|
|
|
|
|
|
|
|
|
export const checkAssetsCount = async (page: Page, assetsCount: number) => {
|
|
|
|
|
await expect(
|
|
|
|
|
page.locator('[data-testid="assets"] [data-testid="filter-count"]')
|
|
|
|
|
).toHaveText(assetsCount.toString());
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const addAssetToGlossaryTerm = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
assets: (TableClass | TopicClass | DashboardClass)[],
|
|
|
|
|
hasExistingAssets = false
|
|
|
|
|
) => {
|
|
|
|
|
if (!hasExistingAssets) {
|
|
|
|
|
await page.waitForSelector(
|
|
|
|
|
'text=Adding a new Asset is easy, just give it a spin!'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await page.click('[data-testid="glossary-term-add-button-menu"]');
|
|
|
|
|
await page.getByRole('menuitem', { name: 'Assets' }).click();
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('[role="dialog"].ant-modal')).toBeVisible();
|
|
|
|
|
await expect(
|
|
|
|
|
page.locator('[data-testid="asset-selection-modal"] .ant-modal-title')
|
|
|
|
|
).toContainText('Add Assets');
|
|
|
|
|
|
|
|
|
|
for (const asset of assets) {
|
|
|
|
|
const entityFqn = get(asset, 'entityResponseData.fullyQualifiedName');
|
|
|
|
|
const entityName = get(asset, 'entityResponseData.name');
|
|
|
|
|
const searchRes = page.waitForResponse('/api/v1/search/query*');
|
|
|
|
|
|
|
|
|
|
await page
|
|
|
|
|
.locator(
|
|
|
|
|
'[data-testid="asset-selection-modal"] [data-testid="searchbar"]'
|
|
|
|
|
)
|
|
|
|
|
.fill(entityName);
|
|
|
|
|
|
|
|
|
|
await searchRes;
|
|
|
|
|
await page.click(
|
|
|
|
|
`[data-testid="table-data-card_${entityFqn}"] input[type="checkbox"]`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await page.click('[data-testid="save-btn"]');
|
|
|
|
|
await checkAssetsCount(page, assets.length);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const updateNameForGlossaryTerm = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
name: string,
|
|
|
|
|
endPoint: string
|
|
|
|
|
) => {
|
|
|
|
|
await page.click('[data-testid="manage-button"]');
|
|
|
|
|
await page.click('[data-testid="rename-button"]');
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('#name')).toBeVisible();
|
|
|
|
|
|
|
|
|
|
await page.fill('#name', name);
|
|
|
|
|
const updateNameResponsePromise = page.waitForResponse(
|
|
|
|
|
`/api/v1/${endPoint}/*`
|
|
|
|
|
);
|
|
|
|
|
await page.click('[data-testid="save-button"]');
|
|
|
|
|
const updateNameResponse = await updateNameResponsePromise;
|
|
|
|
|
const data = await updateNameResponse.json();
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('[data-testid="entity-header-name"]')).toHaveText(
|
|
|
|
|
name
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const verifyGlossaryTermAssets = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
glossary: GlossaryData,
|
|
|
|
|
glossaryTermData: GlossaryTermData,
|
|
|
|
|
assetsLength: number
|
|
|
|
|
) => {
|
|
|
|
|
await page.click('[data-testid="overview"]');
|
|
|
|
|
await redirectToHomePage(page);
|
|
|
|
|
await sidebarClick(page, SidebarItem.GLOSSARY);
|
|
|
|
|
await selectActiveGlossary(page, glossary.displayName);
|
2024-08-13 18:43:03 +05:30
|
|
|
|
await goToAssetsTab(page, glossaryTermData.displayName, assetsLength);
|
2024-07-16 17:20:36 +05:30
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const renameGlossaryTerm = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
glossaryTerm: GlossaryTerm,
|
|
|
|
|
glossaryNewName: string
|
|
|
|
|
) => {
|
|
|
|
|
const data = await updateNameForGlossaryTerm(
|
|
|
|
|
page,
|
|
|
|
|
glossaryNewName,
|
|
|
|
|
EntityTypeEndpoint.GlossaryTerm
|
|
|
|
|
);
|
|
|
|
|
await glossaryTerm.rename(data.name, data.fullyQualifiedName);
|
|
|
|
|
};
|
2024-08-29 11:38:31 +05:30
|
|
|
|
|
|
|
|
|
export const dragAndDropTerm = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
dragElement: string,
|
|
|
|
|
dropTarget: string
|
|
|
|
|
) => {
|
|
|
|
|
await page.getByRole('cell', { name: dragElement }).hover();
|
|
|
|
|
await page.mouse.down();
|
|
|
|
|
await page.getByRole('cell', { name: dropTarget }).hover();
|
|
|
|
|
await page.mouse.up();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const confirmationDragAndDropGlossary = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
dragElement: string,
|
|
|
|
|
dropElement: string,
|
|
|
|
|
isHeader = false
|
|
|
|
|
) => {
|
|
|
|
|
await expect(
|
|
|
|
|
page.locator('[data-testid="confirmation-modal"] .ant-modal-body')
|
|
|
|
|
).toContainText(
|
|
|
|
|
`Click on Confirm if you’d like to move ${
|
|
|
|
|
isHeader
|
|
|
|
|
? `${dragElement} under ${dropElement} .`
|
|
|
|
|
: `${dragElement} term under ${dropElement} term.`
|
|
|
|
|
}`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const patchGlossaryTermResponse = page.waitForResponse(
|
|
|
|
|
'/api/v1/glossaryTerms/*'
|
|
|
|
|
);
|
|
|
|
|
await page.getByRole('button', { name: 'Confirm' }).click();
|
|
|
|
|
await patchGlossaryTermResponse;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const changeTermHierarchyFromModal = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
dragElement: string,
|
|
|
|
|
dropElement: string
|
|
|
|
|
) => {
|
|
|
|
|
await selectActiveGlossaryTerm(page, dragElement);
|
|
|
|
|
await page.getByTestId('manage-button').click();
|
|
|
|
|
await page.getByTestId('change-parent-button').click();
|
|
|
|
|
await page
|
|
|
|
|
.locator('[data-testid="change-parent-select"] > .ant-select-selector')
|
|
|
|
|
.click();
|
|
|
|
|
await page.getByTitle(dropElement).click();
|
|
|
|
|
const saveRes = page.waitForResponse('/api/v1/glossaryTerms/*');
|
|
|
|
|
await page.getByRole('button', { name: 'Submit' }).click();
|
|
|
|
|
await saveRes;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const deleteGlossaryOrGlossaryTerm = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
entityName: string,
|
|
|
|
|
isGlossaryTerm = false
|
|
|
|
|
) => {
|
|
|
|
|
await page.click('[data-testid="manage-button"]');
|
|
|
|
|
await page.click('[data-testid="delete-button"]');
|
|
|
|
|
|
|
|
|
|
await expect(page.locator('[role="dialog"]')).toBeVisible();
|
|
|
|
|
await expect(page.locator('[data-testid="modal-header"]')).toContainText(
|
|
|
|
|
entityName
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await page.fill('[data-testid="confirmation-text-input"]', 'DELETE');
|
|
|
|
|
|
|
|
|
|
const endpoint = isGlossaryTerm
|
|
|
|
|
? '/api/v1/glossaryTerms/*'
|
|
|
|
|
: '/api/v1/glossaries/*';
|
|
|
|
|
const deleteRes = page.waitForResponse(endpoint);
|
|
|
|
|
await page.click('[data-testid="confirm-button"]');
|
|
|
|
|
await deleteRes;
|
|
|
|
|
|
|
|
|
|
if (isGlossaryTerm) {
|
|
|
|
|
await toastNotification(page, /"Glossary Term" deleted successfully!/);
|
|
|
|
|
} else {
|
|
|
|
|
await toastNotification(page, /"Glossary" deleted successfully!/);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const addSynonyms = async (page: Page, synonyms: string[]) => {
|
|
|
|
|
await page.getByTestId('synonym-add-button').click();
|
|
|
|
|
await page.locator('.ant-select-selection-overflow').click();
|
|
|
|
|
|
|
|
|
|
for (const synonym of synonyms) {
|
|
|
|
|
await page.locator('#synonyms-select').fill(synonym);
|
|
|
|
|
await page.locator('#synonyms-select').press('Enter');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const saveRes = page.waitForResponse('/api/v1/glossaryTerms/*');
|
|
|
|
|
await page.getByTestId('save-synonym-btn').click();
|
|
|
|
|
await saveRes;
|
|
|
|
|
|
|
|
|
|
for (const synonym of synonyms) {
|
|
|
|
|
await expect(page.getByTestId(synonym)).toBeVisible();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const addReferences = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
references: { name: string; url: string }[]
|
|
|
|
|
) => {
|
|
|
|
|
await page.getByTestId('term-references-add-button').click();
|
|
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
|
page.getByTestId('glossary-term-references-modal').getByText('References')
|
|
|
|
|
).toBeVisible();
|
|
|
|
|
|
|
|
|
|
for (const [index, value] of references.entries()) {
|
|
|
|
|
await page.locator(`#references_${index}_name`).fill(value.name);
|
|
|
|
|
await page.locator(`#references_${index}_endpoint`).fill(value.url);
|
|
|
|
|
if (index < references.length - 1) {
|
|
|
|
|
await page.getByTestId('add-references-button').click();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const saveRes = page.waitForResponse('/api/v1/glossaryTerms/*');
|
|
|
|
|
await page.getByTestId('save-btn').click();
|
|
|
|
|
await saveRes;
|
|
|
|
|
|
|
|
|
|
for (const reference of references) {
|
|
|
|
|
await expect(
|
|
|
|
|
page.getByTestId(`reference-link-${reference.name}`)
|
|
|
|
|
).toBeVisible();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const addRelatedTerms = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
relatedTerms: GlossaryTerm[]
|
|
|
|
|
) => {
|
|
|
|
|
await page.getByTestId('related-term-add-button').click();
|
|
|
|
|
for (const term of relatedTerms) {
|
|
|
|
|
const entityName = get(term, 'responseData.name');
|
|
|
|
|
const entityFqn = get(term, 'responseData.fullyQualifiedName');
|
|
|
|
|
await page.locator('#tagsForm_tags').fill(entityName);
|
|
|
|
|
await page.getByTestId(`tag-${entityFqn}`).click();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const saveRes = page.waitForResponse('/api/v1/glossaryTerms/*');
|
|
|
|
|
await page.getByTestId('saveAssociatedTag').click();
|
|
|
|
|
await saveRes;
|
|
|
|
|
|
|
|
|
|
for (const term of relatedTerms) {
|
|
|
|
|
const entityName = get(term, 'responseData.displayName');
|
|
|
|
|
|
|
|
|
|
await expect(page.getByTestId(entityName)).toBeVisible();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const assignTagToGlossaryTerm = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
tag: string,
|
|
|
|
|
action: 'Add' | 'Edit' = 'Add',
|
|
|
|
|
parentTestId = 'entity-right-panel'
|
|
|
|
|
) => {
|
|
|
|
|
await page
|
|
|
|
|
.getByTestId(parentTestId)
|
|
|
|
|
.getByTestId('tags-container')
|
|
|
|
|
.getByTestId(action === 'Add' ? 'add-tag' : 'edit-button')
|
|
|
|
|
.click();
|
|
|
|
|
|
|
|
|
|
const searchTags = page.waitForResponse(
|
|
|
|
|
`/api/v1/search/query?q=*${encodeURIComponent(tag)}*`
|
|
|
|
|
);
|
|
|
|
|
await page.locator('#tagsForm_tags').fill(tag);
|
|
|
|
|
await searchTags;
|
|
|
|
|
await page.getByTestId(`tag-${tag}`).click();
|
|
|
|
|
|
|
|
|
|
await expect(page.getByTestId('saveAssociatedTag')).toBeEnabled();
|
|
|
|
|
|
|
|
|
|
await page.getByTestId('saveAssociatedTag').click();
|
|
|
|
|
|
|
|
|
|
await expect(page.getByRole('heading')).toContainText(
|
|
|
|
|
'Would you like to proceed with updating the tags?'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const validateRes = page.waitForResponse('/api/v1/glossaryTerms/*');
|
|
|
|
|
await page.getByRole('button', { name: 'Yes, confirm' }).click();
|
|
|
|
|
await validateRes;
|
|
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
|
page
|
|
|
|
|
.getByTestId(parentTestId)
|
|
|
|
|
.getByTestId('tags-container')
|
|
|
|
|
.getByTestId(`tag-${tag}`)
|
|
|
|
|
).toBeVisible();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const createDescriptionTaskForGlossary = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
value: TaskDetails,
|
|
|
|
|
entity: Glossary | GlossaryTerm,
|
|
|
|
|
isGlossary = true,
|
|
|
|
|
addDescription = true
|
|
|
|
|
) => {
|
|
|
|
|
const entityType = isGlossary ? 'glossary' : 'glossaryTerm';
|
|
|
|
|
const entityName = get(entity, 'responseData.displayName');
|
|
|
|
|
|
|
|
|
|
expect(await page.locator('#title').inputValue()).toBe(
|
|
|
|
|
`${
|
|
|
|
|
addDescription ? 'Update' : 'Request'
|
|
|
|
|
} description for ${entityType} ${entityName}`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (isUndefined(value.assignee)) {
|
|
|
|
|
expect(
|
|
|
|
|
await page
|
|
|
|
|
.locator('[data-testid="select-assignee"] > .ant-select-selector')
|
|
|
|
|
.innerText()
|
|
|
|
|
).toBe(value.assignee);
|
|
|
|
|
|
|
|
|
|
expect(
|
|
|
|
|
await page
|
|
|
|
|
.locator('[data-testid="select-assignee"] > .ant-select-selector input')
|
|
|
|
|
.isDisabled()
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
const assigneeField = page.locator(
|
|
|
|
|
'[data-testid="select-assignee"] > .ant-select-selector #assignees'
|
|
|
|
|
);
|
|
|
|
|
await assigneeField.click();
|
|
|
|
|
|
|
|
|
|
const userSearchResponse = page.waitForResponse(
|
|
|
|
|
`/api/v1/search/suggest?q=${value.assignee}&index=user_search_index%2Cteam_search_index`
|
|
|
|
|
);
|
|
|
|
|
await assigneeField.fill(value.assignee);
|
|
|
|
|
await userSearchResponse;
|
|
|
|
|
|
|
|
|
|
// select value from dropdown
|
|
|
|
|
const dropdownValue = page.getByTestId(value.assignee);
|
|
|
|
|
await dropdownValue.hover();
|
|
|
|
|
await dropdownValue.click();
|
|
|
|
|
await clickOutside(page);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addDescription) {
|
|
|
|
|
await page
|
|
|
|
|
.locator(descriptionBox)
|
|
|
|
|
.fill(value.description ?? 'Updated description');
|
|
|
|
|
}
|
|
|
|
|
await page.click('button[type="submit"]');
|
|
|
|
|
|
|
|
|
|
await toastNotification(page, /Task created successfully./);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const createTagTaskForGlossary = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
value: TaskDetails,
|
|
|
|
|
entity: Glossary | GlossaryTerm,
|
|
|
|
|
isGlossary = true,
|
|
|
|
|
addTag = true
|
|
|
|
|
) => {
|
|
|
|
|
const entityType = isGlossary ? 'glossary' : 'glossaryTerm';
|
|
|
|
|
const entityName = get(entity, 'responseData.displayName');
|
|
|
|
|
|
|
|
|
|
expect(await page.locator('#title').inputValue()).toBe(
|
|
|
|
|
`Request tags for ${entityType} ${entityName}`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (isUndefined(value.assignee)) {
|
|
|
|
|
expect(
|
|
|
|
|
await page
|
|
|
|
|
.locator('[data-testid="select-assignee"] > .ant-select-selector')
|
|
|
|
|
.innerText()
|
|
|
|
|
).toBe(value.assignee);
|
|
|
|
|
|
|
|
|
|
expect(
|
|
|
|
|
await page
|
|
|
|
|
.locator('[data-testid="select-assignee"] > .ant-select-selector input')
|
|
|
|
|
.isDisabled()
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
// select assignee
|
|
|
|
|
const assigneeField = page.locator(
|
|
|
|
|
'[data-testid="select-assignee"] > .ant-select-selector #assignees'
|
|
|
|
|
);
|
|
|
|
|
await assigneeField.click();
|
|
|
|
|
const userSearchResponse = page.waitForResponse(
|
|
|
|
|
`/api/v1/search/suggest?q=${value.assignee}&index=user_search_index%2Cteam_search_index`
|
|
|
|
|
);
|
|
|
|
|
await assigneeField.fill(value.assignee);
|
|
|
|
|
await userSearchResponse;
|
|
|
|
|
|
|
|
|
|
// select value from dropdown
|
|
|
|
|
const dropdownValue = page.getByTestId(value.assignee);
|
|
|
|
|
await dropdownValue.hover();
|
|
|
|
|
await dropdownValue.click();
|
|
|
|
|
await clickOutside(page);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addTag) {
|
|
|
|
|
// select tags
|
|
|
|
|
const suggestTags = page.locator(
|
|
|
|
|
'[data-testid="tag-selector"] > .ant-select-selector .ant-select-selection-search-input'
|
|
|
|
|
);
|
|
|
|
|
await suggestTags.click();
|
|
|
|
|
|
|
|
|
|
const querySearchResponse = page.waitForResponse(
|
|
|
|
|
`/api/v1/search/query?q=*${value.tag}*&index=tag_search_index&*`
|
|
|
|
|
);
|
|
|
|
|
await suggestTags.fill(value.tag ?? '');
|
|
|
|
|
|
|
|
|
|
await querySearchResponse;
|
|
|
|
|
|
|
|
|
|
// select value from dropdown
|
|
|
|
|
const dropdownValue = page.getByTestId(`tag-${value.tag ?? ''}`);
|
|
|
|
|
await dropdownValue.hover();
|
|
|
|
|
await dropdownValue.click();
|
|
|
|
|
await clickOutside(page);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await page.click('button[type="submit"]');
|
|
|
|
|
|
|
|
|
|
await toastNotification(page, /Task created successfully./);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const approveTagsTask = async (
|
|
|
|
|
page: Page,
|
|
|
|
|
value: TaskDetails,
|
|
|
|
|
entity: Glossary | GlossaryTerm
|
|
|
|
|
) => {
|
|
|
|
|
await redirectToHomePage(page);
|
|
|
|
|
await sidebarClick(page, SidebarItem.GLOSSARY);
|
|
|
|
|
await selectActiveGlossary(page, entity.data.displayName);
|
|
|
|
|
|
|
|
|
|
await page.click('[data-testid="activity_feed"]');
|
|
|
|
|
|
|
|
|
|
const taskFeeds = page.waitForResponse(TASK_OPEN_FETCH_LINK);
|
|
|
|
|
await page
|
|
|
|
|
.getByTestId('global-setting-left-panel')
|
|
|
|
|
.getByText('Tasks')
|
|
|
|
|
.click();
|
|
|
|
|
|
|
|
|
|
await taskFeeds;
|
|
|
|
|
|
|
|
|
|
const taskResolve = page.waitForResponse('/api/v1/feed/tasks/*/resolve');
|
|
|
|
|
await page.click('.ant-btn-compact-first-item:has-text("Accept Suggestion")');
|
|
|
|
|
await taskResolve;
|
|
|
|
|
|
|
|
|
|
await redirectToHomePage(page);
|
|
|
|
|
await sidebarClick(page, SidebarItem.GLOSSARY);
|
|
|
|
|
await selectActiveGlossary(page, entity.data.displayName);
|
|
|
|
|
|
|
|
|
|
const tagVisibility = await page.isVisible(
|
|
|
|
|
`[data-testid="tag-${value.tag}"]`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await expect(tagVisibility).toBe(true);
|
|
|
|
|
};
|