261 lines
8.5 KiB
TypeScript
261 lines
8.5 KiB
TypeScript
import {
|
|
ActionPanelQA,
|
|
ConnectionsActionPanelControls,
|
|
ConnectionsBaseQA,
|
|
ConnectionsFormQA,
|
|
ConnectionsS3BaseQA,
|
|
ConnectionsYadocsQA,
|
|
DialogCreateWorkbookEntryQa,
|
|
EntryDialogQA,
|
|
SharedEntriesBaseQa,
|
|
} from '../../../src/shared/constants';
|
|
import {ActionPanelEntryContextMenuQa} from '../../../src/shared/constants/qa/action-panel';
|
|
import {v1 as uuidv1} from 'uuid';
|
|
|
|
import {slct, waitForCondition} from '../../utils';
|
|
import {BasePage} from '../BasePage';
|
|
import type {BasePageProps} from '../BasePage';
|
|
import type {ConsoleMessage, Request, FileChooser} from '@playwright/test';
|
|
import Revisions from '../common/Revisions';
|
|
import XLSX from '@datalens-tech/xlsx';
|
|
import {CSV_FILE, XLSX_FILE} from '../../constants/mock-data';
|
|
import os from 'os';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
|
|
type ConnectionsPageProps = BasePageProps;
|
|
type FillInputArgs = {name: string; value: string};
|
|
type FillFormInputArgs = {id: 'input'} & FillInputArgs;
|
|
|
|
class ConnectionsPage extends BasePage {
|
|
revisions: Revisions;
|
|
|
|
private createQlChartButtonSelector = slct(
|
|
ConnectionsActionPanelControls.CREATE_QL_CHART_BUTTON,
|
|
);
|
|
|
|
private createDatasetButtonSelector = slct(
|
|
ConnectionsActionPanelControls.CREATE_DATASET_BUTTON,
|
|
);
|
|
|
|
constructor({page}: ConnectionsPageProps) {
|
|
super({page});
|
|
this.revisions = new Revisions(page);
|
|
}
|
|
|
|
async checkIsReadonlyState() {
|
|
await this.page.waitForSelector(slct(SharedEntriesBaseQa.OpenOriginalBtn));
|
|
}
|
|
|
|
async createQlChart() {
|
|
await this.page.click(this.createQlChartButtonSelector);
|
|
}
|
|
|
|
async createDataset() {
|
|
await this.page.click(this.createDatasetButtonSelector);
|
|
}
|
|
|
|
async fillCreateConnectionInFolder({name}: {name: string}) {
|
|
const textInput = this.page.locator(slct(EntryDialogQA.PathSelect)).locator('input');
|
|
// type connection name
|
|
await textInput.fill(name);
|
|
|
|
// create connection
|
|
await this.page.locator(slct(EntryDialogQA.Apply)).click();
|
|
try {
|
|
await this.page.waitForURL(() => this.page.url().includes(name));
|
|
} catch {
|
|
throw new Error("Connection wasn't created");
|
|
}
|
|
}
|
|
|
|
async createConnectionInFolder({name = uuidv1()}: {name?: string} = {}) {
|
|
// open creation dialog
|
|
await this.page.locator(slct(ConnectionsBaseQA.SUBMIT_ACTION_BUTTON)).click();
|
|
|
|
await this.fillCreateConnectionInFolder({name});
|
|
}
|
|
|
|
async createConnectionInWorkbookOrCollection({
|
|
name = uuidv1(),
|
|
collectionId,
|
|
}: {name?: string; collectionId?: string} = {}) {
|
|
const formSubmit = await this.page.waitForSelector(
|
|
slct(ConnectionsBaseQA.SUBMIT_ACTION_BUTTON),
|
|
);
|
|
// open creation dialog
|
|
await formSubmit.click();
|
|
const textInput = this.page
|
|
.locator(slct(DialogCreateWorkbookEntryQa.Input))
|
|
.locator('input');
|
|
// clear input
|
|
await textInput.press('Meta+A');
|
|
await textInput.press('Backspace');
|
|
// type connection 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("Connection wasn't created");
|
|
}
|
|
}
|
|
|
|
async checkClientValidationErrors() {
|
|
let hasValidationErrors = false;
|
|
const onConsoleLog = (msg: ConsoleMessage) => {
|
|
if (msg.text().includes('Validation errors')) {
|
|
hasValidationErrors = true;
|
|
}
|
|
};
|
|
this.page.on('console', onConsoleLog);
|
|
const formSubmit = await this.page.waitForSelector(
|
|
slct(ConnectionsBaseQA.SUBMIT_ACTION_BUTTON),
|
|
);
|
|
await formSubmit.click();
|
|
await waitForCondition(async () => {
|
|
return hasValidationErrors;
|
|
});
|
|
this.page.off('console', onConsoleLog);
|
|
}
|
|
|
|
getFieldSelector(name: string) {
|
|
return `conn-input-${name}`;
|
|
}
|
|
|
|
async fillInput({name, value}: {name: string; value: string}) {
|
|
const selector = this.getFieldSelector(name);
|
|
const input = await this.page.waitForSelector(slct(selector));
|
|
// focus input
|
|
await input.click();
|
|
await input.type(value);
|
|
}
|
|
|
|
async fillForm(args: FillFormInputArgs[]) {
|
|
for (const control of args) {
|
|
const {id, name, value} = control;
|
|
switch (id) {
|
|
case 'input': {
|
|
await this.fillInput({name, value});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async fillAndSubmitAddYadocDialog(fileUrl: string) {
|
|
const fileInput = await this.page.waitForSelector(
|
|
`${slct(ConnectionsYadocsQA.ADD_DOCUMENT_DIALOG_INPUT)} input`,
|
|
);
|
|
await fileInput.click();
|
|
await fileInput.fill(fileUrl);
|
|
const addFileDialogSubmitButton = await this.page.waitForSelector(
|
|
slct(ConnectionsYadocsQA.ADD_DOCUMENT_DIALOG_SUBMIT_BUTTON),
|
|
);
|
|
await addFileDialogSubmitButton.click();
|
|
}
|
|
|
|
async applyS3SourceDialogAndForSourcesUpdating() {
|
|
const updateFileSourceRequests: Request[] = [];
|
|
this.page.on('request', (request) => {
|
|
if (request.url().includes('updateFileSource')) {
|
|
updateFileSourceRequests.push(request);
|
|
}
|
|
});
|
|
const submitButton = await this.page.waitForSelector(
|
|
slct(ConnectionsS3BaseQA.S3_SOURCE_DIALOG_SUBMIT_BUTTON),
|
|
);
|
|
await submitButton.click();
|
|
await Promise.all(
|
|
updateFileSourceRequests.map(async (request) => {
|
|
const response = await request.response();
|
|
expect(response?.status()).toBe(200);
|
|
}),
|
|
);
|
|
}
|
|
|
|
async saveUpdatedConnection() {
|
|
await this.page.locator(slct(ConnectionsBaseQA.SUBMIT_ACTION_BUTTON)).click();
|
|
}
|
|
|
|
async removeConnection() {
|
|
const moreButton = this.page.locator(slct(ActionPanelQA.MoreBtn));
|
|
expect(moreButton).toBeVisible();
|
|
await moreButton.click();
|
|
|
|
const menuItemRemove = this.page
|
|
.locator(slct(ActionPanelEntryContextMenuQa.Menu))
|
|
.locator(slct(ActionPanelEntryContextMenuQa.Remove));
|
|
expect(menuItemRemove).toBeVisible();
|
|
await menuItemRemove.click();
|
|
|
|
const applyButton = this.page.locator(slct(EntryDialogQA.Apply));
|
|
expect(applyButton).toBeVisible();
|
|
|
|
await applyButton.click();
|
|
}
|
|
|
|
async disableAutoCreateDashInBillingConnection() {
|
|
const checkbox = await this.page.waitForSelector(
|
|
slct(ConnectionsFormQA.AUTO_CREATE_DASH_CHECKBOX),
|
|
);
|
|
await checkbox.click();
|
|
}
|
|
|
|
async uploadCsvFile({
|
|
fileName = `${uuidv1()}.csv`,
|
|
file = CSV_FILE,
|
|
}: {fileName?: string; file?: string[][]} = {}) {
|
|
// make file
|
|
os.tmpdir();
|
|
const csvFile = path.join(os.tmpdir(), fileName);
|
|
fs.writeFileSync(csvFile, file.map((row) => row.join(',')).join('\n'));
|
|
|
|
await this.uploadS3File(csvFile);
|
|
|
|
return {fileName, file};
|
|
}
|
|
|
|
async uploadXlsxFile({
|
|
fileName = `${uuidv1()}.xlsx`,
|
|
sheets = XLSX_FILE,
|
|
}: {fileName?: string; sheets?: Record<string, string[][]>} = {}) {
|
|
// make file
|
|
const workbook = XLSX.utils.book_new();
|
|
|
|
for (const [sheetName, data] of Object.entries(sheets)) {
|
|
const worksheet = XLSX.utils.aoa_to_sheet(data);
|
|
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
|
|
}
|
|
const xlsxFile = path.join(os.tmpdir(), fileName);
|
|
XLSX.writeFile(workbook, xlsxFile);
|
|
|
|
await this.uploadS3File(xlsxFile);
|
|
return {fileName, sheets};
|
|
}
|
|
|
|
private async uploadS3File(file: string) {
|
|
const onFileChoose = (fileChooser: FileChooser) => {
|
|
fileChooser.setFiles([file]);
|
|
};
|
|
this.page.on('filechooser', onFileChoose);
|
|
await this.page.click(slct(ConnectionsBaseQA.S3_UPLOAD_BUTTON));
|
|
this.page.off('filechooser', onFileChoose);
|
|
}
|
|
}
|
|
|
|
export default ConnectionsPage;
|