295 lines
10 KiB
TypeScript
295 lines
10 KiB
TypeScript
import {Page, Response, expect} from '@playwright/test';
|
|
import {v1 as uuidv1} from 'uuid';
|
|
import {
|
|
DialogCreateWorkbookEntryQa,
|
|
EntryDialogQA,
|
|
} from '../../../src/shared/constants/qa/components';
|
|
import {
|
|
DatasetPanelQA,
|
|
DatasetActionQA,
|
|
DatasetSourcesTableQa,
|
|
DatasetSourcesLeftPanelQA,
|
|
} from '../../../src/shared/constants/qa/datasets';
|
|
import {
|
|
CollectionFiltersQa,
|
|
DialogCollectionStructureQa,
|
|
SharedEntriesBaseQa,
|
|
SharedEntriesPermissionsDialogQa,
|
|
ValueOf,
|
|
DATASET_TAB,
|
|
} from '../../../src/shared';
|
|
|
|
import {deleteEntity, slct} from '../../utils';
|
|
import {BasePage, BasePageProps} from '../BasePage';
|
|
import DialogParameter from '../common/DialogParameter';
|
|
import Revisions from '../common/Revisions';
|
|
|
|
import DatasetTabSection from './DatasetTabSection';
|
|
import DatasetConnectionSection, {SetConnectionProps} from './DatasetConnectionSection';
|
|
import DatasetFieldsTable from './DatasetFieldsTable';
|
|
import {VALIDATE_DATASET_URL} from './constants';
|
|
import {NavigationMinimalPopup} from '../workbook/NavigationMinimalPopup';
|
|
|
|
export interface DatasetPageProps extends BasePageProps {}
|
|
|
|
export const waitForBiValidateDatasetResponses = (page: Page, timeout: number): Promise<void> => {
|
|
return new Promise((resolve: any) => {
|
|
const timerId = setTimeout(() => {
|
|
page.off('response', onResponse);
|
|
resolve();
|
|
}, timeout);
|
|
|
|
async function onResponse(response: Response) {
|
|
if (!response.url().match('validateDataset')) {
|
|
return;
|
|
}
|
|
|
|
const request = await response.request();
|
|
const requestData = JSON.parse(request.postData() || '');
|
|
|
|
// When the page loads, the validation request with empty updates initially goes away
|
|
// We are only interested in the one that leaves after the avatar is deleted
|
|
if (!requestData.data.updates.length) {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(timerId);
|
|
|
|
if (response.status() !== 200) {
|
|
throw new Error(
|
|
'After deleting the avatar, the dataset validation returned an error',
|
|
);
|
|
}
|
|
|
|
resolve();
|
|
}
|
|
|
|
page.on('response', onResponse);
|
|
});
|
|
};
|
|
|
|
class DatasetPage extends BasePage {
|
|
datasetTabSection: DatasetTabSection;
|
|
datasetConnectionSection: DatasetConnectionSection;
|
|
datasetFieldsTable: DatasetFieldsTable;
|
|
workbookNavigationMinimal: NavigationMinimalPopup;
|
|
dialogParameter: DialogParameter;
|
|
revisions: Revisions;
|
|
|
|
constructor({page}: DatasetPageProps) {
|
|
super({page});
|
|
this.workbookNavigationMinimal = new NavigationMinimalPopup(page);
|
|
this.datasetConnectionSection = new DatasetConnectionSection(page);
|
|
this.datasetFieldsTable = new DatasetFieldsTable(page);
|
|
this.datasetTabSection = new DatasetTabSection(page);
|
|
this.dialogParameter = new DialogParameter(page);
|
|
this.revisions = new Revisions(page);
|
|
}
|
|
|
|
async addAvatarByDragAndDrop(sourceTitle?: string) {
|
|
const selector = sourceTitle
|
|
? `${slct(DatasetSourcesTableQa.Source)} span >> text=${sourceTitle}`
|
|
: slct(DatasetSourcesTableQa.Source);
|
|
|
|
const source = await this.page.$(selector);
|
|
|
|
if (!source) {
|
|
throw new Error("Couldn't find the table");
|
|
}
|
|
|
|
const targetSelector = slct('ds-relations-map');
|
|
const target = await this.page.$(targetSelector);
|
|
|
|
if (!target) {
|
|
throw new Error("Couldn't find an area to drag");
|
|
}
|
|
|
|
await this.page.dragAndDrop(selector, targetSelector);
|
|
}
|
|
|
|
async openTab(tab: ValueOf<typeof DATASET_TAB>) {
|
|
await this.page.click(`.dataset-panel input[value=${tab}]`);
|
|
}
|
|
|
|
async createDatasetInWorkbookOrCollection({
|
|
name = uuidv1(),
|
|
collectionId,
|
|
}: {name?: string; collectionId?: string} = {}) {
|
|
const dsCreateBtn = this.page.locator(slct(DatasetActionQA.CreateButton));
|
|
await dsCreateBtn.click();
|
|
|
|
const textInput = this.page
|
|
.locator(slct(DialogCreateWorkbookEntryQa.Input))
|
|
.locator('input');
|
|
// clear input
|
|
await textInput.press('Meta+A');
|
|
await textInput.press('Backspace');
|
|
// type dataset name
|
|
await textInput.fill(name);
|
|
const dialogApplyButton = await this.page.waitForSelector(
|
|
slct(DialogCreateWorkbookEntryQa.ApplyButton),
|
|
);
|
|
// create connection
|
|
await dialogApplyButton.click();
|
|
try {
|
|
if (collectionId) {
|
|
await this.page.waitForURL(() => {
|
|
return this.page.url().endsWith(collectionId);
|
|
});
|
|
} else {
|
|
await this.page.waitForURL(() => {
|
|
return this.page.url().includes(name);
|
|
});
|
|
}
|
|
return name;
|
|
} catch {
|
|
throw new Error("Dataset wasn't created");
|
|
}
|
|
}
|
|
|
|
async createDatasetInFolder({name = uuidv1()}: {name?: string} = {}) {
|
|
// open creation dialog
|
|
await this.page.locator(slct(DatasetActionQA.CreateButton)).click();
|
|
// type dataset name
|
|
await this.page.locator(slct(EntryDialogQA.PathSelect)).locator('input').fill(name);
|
|
const dialogApplyButton = await this.page.waitForSelector(slct(EntryDialogQA.Apply));
|
|
// create dataset
|
|
await dialogApplyButton.click();
|
|
try {
|
|
await this.page.waitForURL(() => this.page.url().includes(name));
|
|
} catch {
|
|
throw new Error("Dataset wasn't created");
|
|
}
|
|
}
|
|
|
|
async deleteEntry() {
|
|
await deleteEntity(this.page);
|
|
}
|
|
|
|
async getCurrentTabName() {
|
|
const input = await this.page.waitForSelector(
|
|
`${slct(DatasetPanelQA.TabRadio)} input[aria-checked="true"]`,
|
|
);
|
|
|
|
return await input.inputValue();
|
|
}
|
|
|
|
async setConnectionDelegation({
|
|
delegation = true,
|
|
}: {
|
|
delegation?: boolean;
|
|
} = {}) {
|
|
if (delegation) {
|
|
const delegateBtn = await this.page.waitForSelector(
|
|
slct(SharedEntriesPermissionsDialogQa.DelegateBtn),
|
|
);
|
|
await delegateBtn.click();
|
|
} else {
|
|
const delegateBtn = await this.page.waitForSelector(
|
|
slct(SharedEntriesPermissionsDialogQa.NotDelegateBtn),
|
|
);
|
|
await delegateBtn.click();
|
|
}
|
|
|
|
const delegationApplyBtn = this.page.locator(
|
|
slct(SharedEntriesPermissionsDialogQa.ApplyBtn),
|
|
);
|
|
await delegationApplyBtn.click();
|
|
}
|
|
|
|
async saveSharedDataset({name, collectionId}: {name?: string; collectionId: string}) {
|
|
await this.page.waitForSelector(slct(DatasetSourcesTableQa.Source));
|
|
|
|
await this.addAvatarByDragAndDrop();
|
|
|
|
const dsName = await this.createDatasetInWorkbookOrCollection({
|
|
collectionId,
|
|
name,
|
|
});
|
|
|
|
return dsName;
|
|
}
|
|
|
|
async setConnectionInWorkbookDataset({method, connectionName}: SetConnectionProps) {
|
|
await this.datasetConnectionSection.openConnectionSelectViaMethod(method);
|
|
await this.workbookNavigationMinimal.fillInput(connectionName);
|
|
await this.workbookNavigationMinimal.selectListItem({innerText: connectionName});
|
|
}
|
|
|
|
async setSharedConnection({connectionName, method}: SetConnectionProps) {
|
|
await this.datasetConnectionSection.openConnectionSelectViaMethod(method);
|
|
await this.page.waitForSelector(slct(CollectionFiltersQa.SearchInput));
|
|
const search = this.page.locator(slct(CollectionFiltersQa.SearchInput)).locator('input');
|
|
await search.press('Meta+A');
|
|
await search.press('Backspace');
|
|
await search.fill(connectionName);
|
|
await this.waitForSuccessfulResponse('/getCollectionBreadcrumbs');
|
|
|
|
await this.page.waitForSelector(slct(DialogCollectionStructureQa.ListItem));
|
|
|
|
const sharedConn = this.page
|
|
.locator(slct(DialogCollectionStructureQa.ListItem))
|
|
.filter({hasText: connectionName});
|
|
await sharedConn.click();
|
|
}
|
|
|
|
async checkIsReadonlyState() {
|
|
await this.page.waitForSelector(slct(SharedEntriesBaseQa.OpenOriginalBtn));
|
|
}
|
|
|
|
async scrollSourcesList({scrollHeight = 99999}: {scrollHeight?: number} = {}) {
|
|
const sourcesList = await this.page.waitForSelector(
|
|
slct(DatasetSourcesLeftPanelQA.SourcesList),
|
|
);
|
|
await this.page.waitForSelector(slct(DatasetSourcesTableQa.Source));
|
|
await sourcesList.hover();
|
|
await this.page.mouse.wheel(0, scrollHeight);
|
|
}
|
|
|
|
async changeDbName({namePattern}: {namePattern?: string} = {}) {
|
|
const select = await this.page.waitForSelector(
|
|
slct(DatasetSourcesLeftPanelQA.SelectSourcesDbName),
|
|
);
|
|
await this.page.waitForFunction(
|
|
async (element) => {
|
|
return !(element as HTMLSelectElement).disabled;
|
|
},
|
|
select,
|
|
{polling: 500},
|
|
);
|
|
|
|
const disabled = await select.isDisabled();
|
|
expect(disabled).toBe(false);
|
|
await select.click();
|
|
await this.page.waitForSelector(slct('select-popup'));
|
|
const popup = this.page.locator(slct('select-popup'));
|
|
const option = popup.locator('[role="option"]', {hasText: namePattern});
|
|
await option.click();
|
|
}
|
|
|
|
async renameFirstField({value}: {value?: string} = {}) {
|
|
const fieldInput = this.datasetFieldsTable.getFieldNameInput();
|
|
const originalValue = await fieldInput.inputValue();
|
|
const newValue = value || `${originalValue}_modified`;
|
|
|
|
await fieldInput.fill(newValue);
|
|
const validatePromise = this.waitForSuccessfulResponse(VALIDATE_DATASET_URL);
|
|
await this.page.keyboard.press('Enter');
|
|
await validatePromise;
|
|
|
|
return {newValue, originalValue};
|
|
}
|
|
|
|
async saveUpdatedDataset() {
|
|
const getEntrySuccessfulPromise = this.waitForSuccessfulResponse(
|
|
'/gateway/root/us/getEntryMeta',
|
|
);
|
|
const saveBtn = await this.page.locator(slct(DatasetActionQA.CreateButton));
|
|
await expect(saveBtn).toBeEnabled();
|
|
await saveBtn.click();
|
|
await getEntrySuccessfulPromise;
|
|
}
|
|
}
|
|
|
|
export default DatasetPage;
|