408 lines
14 KiB
TypeScript
408 lines
14 KiB
TypeScript
import {Page, expect} from '@playwright/test';
|
|
import {dateTimeUtc} from '@gravity-ui/date-utils';
|
|
|
|
import {WizardVisualizationId} from '../../../page-objects/common/Visualization';
|
|
import {PlaceholderName} from '../../../page-objects/wizard/SectionVisualization';
|
|
import WizardPage from '../../../page-objects/wizard/WizardPage';
|
|
import {getXAxisValues, openTestPage, waitForCondition} from '../../../utils';
|
|
import {RobotChartsWizardUrls} from '../../../utils/constants';
|
|
import datalensTest from '../../../utils/playwright/globalTestDefinition';
|
|
import {COMMON_CHARTKIT_SELECTORS} from '../../../page-objects/constants/chartkit';
|
|
import {CommonUrls} from '../../../page-objects/constants/common-urls';
|
|
|
|
const checkXAxisValuesOrder = async (wizardPage: WizardPage, expectedValues: string[]) => {
|
|
let xAxisValues: (string | null)[] = [];
|
|
await wizardPage.chartkit.waitUntilLoaderExists();
|
|
|
|
await waitForCondition(async () => {
|
|
xAxisValues = await getXAxisValues(wizardPage.page);
|
|
|
|
return xAxisValues.join(',') === expectedValues.join(',');
|
|
}).catch(() => {
|
|
throw new Error(
|
|
`Expected order [${expectedValues.join(',')}], current order [${xAxisValues.join(
|
|
',',
|
|
)}]`,
|
|
);
|
|
});
|
|
};
|
|
|
|
const formatAxisValues = (values: Array<number | string>, isDateTimeAxis: boolean) =>
|
|
values
|
|
.map((value) => (isDateTimeAxis ? dateTimeUtc({input: value}).format('DD.MM.YYYY') : value))
|
|
.map(String);
|
|
|
|
const getApiRunXAxisValues = async (responseData: any): Promise<string[]> => {
|
|
const chartData = responseData?.data;
|
|
const highchartsConfig = JSON.parse(responseData.highchartsConfig ?? '{}');
|
|
|
|
const isDateTime =
|
|
chartData.xAxis?.type === 'datetime' || highchartsConfig?.xAxis?.type === 'datetime';
|
|
|
|
const categories = chartData.categories ?? chartData.xAxis?.categories;
|
|
const data = chartData.graphs?.[0] ?? chartData.series?.data?.[0];
|
|
|
|
const apiValues = categories
|
|
? categories.map(String)
|
|
: formatAxisValues(
|
|
data.data.map(({x}: {x: number}) => x),
|
|
isDateTime,
|
|
);
|
|
|
|
const isBarChart = data.type === 'bar-x' || highchartsConfig?.chart?.type === 'column';
|
|
const isReversed = chartData.xAxis?.order === 'reverse' || highchartsConfig?.xAxis?.reversed;
|
|
const needReverse = isReversed && !isBarChart;
|
|
|
|
return needReverse ? [...apiValues].reverse() : apiValues;
|
|
};
|
|
|
|
const checkApiRunXAxisValuesOrderAfterAction = async (
|
|
wizardPage: WizardPage,
|
|
expectedValues: string[],
|
|
action: () => Promise<void>,
|
|
) => {
|
|
const apiRunResponse = wizardPage.page.waitForRequest(
|
|
(request) => new URL(request.url()).pathname === CommonUrls.ApiRun,
|
|
);
|
|
|
|
await action();
|
|
|
|
const responseData = await (await (await apiRunResponse).response())?.json();
|
|
|
|
await wizardPage.chartkit.waitUntilLoaderExists();
|
|
|
|
const xAxisValues = await getApiRunXAxisValues(responseData);
|
|
|
|
expect(xAxisValues).toEqual(expectedValues);
|
|
};
|
|
|
|
const expectedNumericValues = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'];
|
|
|
|
const expectedValuesAfterNumericSort = [
|
|
'12',
|
|
'9',
|
|
'11',
|
|
'10',
|
|
'3',
|
|
'5',
|
|
'8',
|
|
'6',
|
|
'7',
|
|
'4',
|
|
'2',
|
|
'1',
|
|
];
|
|
|
|
const expectedValuesAfterChangeNumericSort = [
|
|
'1',
|
|
'2',
|
|
'4',
|
|
'7',
|
|
'6',
|
|
'8',
|
|
'5',
|
|
'3',
|
|
'10',
|
|
'11',
|
|
'9',
|
|
'12',
|
|
];
|
|
|
|
const expectedDateValues = [
|
|
'01.12.2017',
|
|
'02.12.2017',
|
|
'03.12.2017',
|
|
'04.12.2017',
|
|
'05.12.2017',
|
|
'06.12.2017',
|
|
'07.12.2017',
|
|
];
|
|
|
|
const expectedDateValuesAfterChangeSort = [
|
|
'07.12.2017',
|
|
'04.12.2017',
|
|
'02.12.2017',
|
|
'06.12.2017',
|
|
'03.12.2017',
|
|
'05.12.2017',
|
|
'01.12.2017',
|
|
];
|
|
|
|
const expectedDateValuesAfterSort = [
|
|
'01.12.2017',
|
|
'05.12.2017',
|
|
'03.12.2017',
|
|
'06.12.2017',
|
|
'02.12.2017',
|
|
'04.12.2017',
|
|
'07.12.2017',
|
|
];
|
|
|
|
datalensTest.describe('Wizard - Sort', () => {
|
|
datalensTest.beforeEach(async ({page}: {page: Page}) => {
|
|
await openTestPage(page, RobotChartsWizardUrls.WizardForDatasetSampleCh);
|
|
});
|
|
|
|
datalensTest(
|
|
'When you click on the sorting icon, the order changes along the X axis (ascending/descending)',
|
|
async ({page}: {page: Page}) => {
|
|
const wizardPage = new WizardPage({page});
|
|
|
|
await wizardPage.setVisualization(WizardVisualizationId.Line);
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.X, 'Category');
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Y, 'Profit');
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Sort, 'Category');
|
|
|
|
const expectedValues = ['Technology', 'Office Supplies', 'Furniture'];
|
|
|
|
await checkXAxisValuesOrder(wizardPage, expectedValues);
|
|
|
|
await wizardPage.sectionVisualization.clickOnSortIcon();
|
|
|
|
const expectedValuesAfterSort = ['Furniture', 'Office Supplies', 'Technology'];
|
|
|
|
await checkXAxisValuesOrder(wizardPage, expectedValuesAfterSort);
|
|
},
|
|
);
|
|
|
|
datalensTest(
|
|
'Sorting works if there is a field with the number type in section X',
|
|
async ({page}: {page: Page}) => {
|
|
const wizardPage = new WizardPage({page});
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.X, 'Month');
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Y, 'Profit');
|
|
|
|
await checkXAxisValuesOrder(wizardPage, expectedNumericValues);
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Sort, 'Profit');
|
|
|
|
await checkXAxisValuesOrder(wizardPage, expectedValuesAfterNumericSort);
|
|
|
|
await wizardPage.sectionVisualization.clickOnSortIcon();
|
|
|
|
await checkXAxisValuesOrder(wizardPage, expectedValuesAfterChangeNumericSort);
|
|
},
|
|
);
|
|
|
|
datalensTest(
|
|
'Sorting works if there is a field with the number type in section X and there is the same field in colors as in X',
|
|
async ({page}: {page: Page}) => {
|
|
const wizardPage = new WizardPage({page});
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.X, 'Month');
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Y, 'Profit');
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Colors, 'Month');
|
|
|
|
await checkXAxisValuesOrder(wizardPage, expectedNumericValues);
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Sort, 'Profit');
|
|
|
|
await checkXAxisValuesOrder(wizardPage, expectedValuesAfterNumericSort);
|
|
|
|
await wizardPage.sectionVisualization.clickOnSortIcon();
|
|
|
|
await checkXAxisValuesOrder(wizardPage, expectedValuesAfterChangeNumericSort);
|
|
},
|
|
);
|
|
|
|
datalensTest(
|
|
'Sorting works if there is a field with the Date type in section X',
|
|
async ({page}: {page: Page}) => {
|
|
const wizardPage = new WizardPage({page});
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.X, 'DATE');
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Y, 'Profit');
|
|
|
|
// There are too many dates in the dataset.
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Filters, 'DATE');
|
|
|
|
await wizardPage.filterEditor.selectRangeDate(['01.12.2017', '07.12.2017']);
|
|
|
|
await checkApiRunXAxisValuesOrderAfterAction(
|
|
wizardPage,
|
|
expectedDateValues,
|
|
async () => {
|
|
await wizardPage.filterEditor.apply();
|
|
},
|
|
);
|
|
|
|
await checkApiRunXAxisValuesOrderAfterAction(
|
|
wizardPage,
|
|
expectedDateValuesAfterSort,
|
|
async () => {
|
|
await wizardPage.sectionVisualization.addFieldByClick(
|
|
PlaceholderName.Sort,
|
|
'Profit',
|
|
);
|
|
},
|
|
);
|
|
|
|
await checkApiRunXAxisValuesOrderAfterAction(
|
|
wizardPage,
|
|
expectedDateValuesAfterChangeSort,
|
|
async () => {
|
|
await wizardPage.sectionVisualization.clickOnSortIcon();
|
|
},
|
|
);
|
|
},
|
|
);
|
|
|
|
datalensTest(
|
|
'Sorting works if there is a field with the number type in section X, and the same field in the Sorting',
|
|
async ({page}: {page: Page}) => {
|
|
const wizardPage = new WizardPage({page});
|
|
|
|
await wizardPage.setVisualization(WizardVisualizationId.Line);
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.X, 'Month');
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Y, 'Profit');
|
|
|
|
await checkApiRunXAxisValuesOrderAfterAction(
|
|
wizardPage,
|
|
[...expectedNumericValues].reverse(),
|
|
async () => {
|
|
await wizardPage.sectionVisualization.addFieldByClick(
|
|
PlaceholderName.Sort,
|
|
'Month',
|
|
);
|
|
},
|
|
);
|
|
|
|
await checkApiRunXAxisValuesOrderAfterAction(
|
|
wizardPage,
|
|
expectedNumericValues,
|
|
async () => {
|
|
await wizardPage.sectionVisualization.clickOnSortIcon();
|
|
},
|
|
);
|
|
|
|
await wizardPage.sectionVisualization.removeFieldByClick(PlaceholderName.Sort, 'Month');
|
|
|
|
await wizardPage.setVisualization(WizardVisualizationId.Column);
|
|
|
|
await checkApiRunXAxisValuesOrderAfterAction(
|
|
wizardPage,
|
|
[...expectedNumericValues].reverse(),
|
|
async () => {
|
|
await wizardPage.sectionVisualization.addFieldByClick(
|
|
PlaceholderName.Sort,
|
|
'Month',
|
|
);
|
|
},
|
|
);
|
|
|
|
await checkApiRunXAxisValuesOrderAfterAction(
|
|
wizardPage,
|
|
expectedNumericValues,
|
|
async () => {
|
|
await wizardPage.sectionVisualization.clickOnSortIcon();
|
|
},
|
|
);
|
|
},
|
|
);
|
|
|
|
datalensTest(
|
|
'Sorting works if we sort by the same field that lies in the Color section when the number type lies there',
|
|
async ({page}) => {
|
|
const wizardPage = new WizardPage({page});
|
|
|
|
await wizardPage.setVisualization(WizardVisualizationId.Area);
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.X, 'Category');
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Y, 'Profit');
|
|
|
|
const formula = `FLOAT(ROUND([Month]/123, 2))`;
|
|
const name = 'FloatColor';
|
|
|
|
await wizardPage.createNewFieldWithFormula(name, formula);
|
|
|
|
const expectedValues = [
|
|
'0.1',
|
|
'0.09',
|
|
'0.08',
|
|
'0.07',
|
|
'0.06',
|
|
'0.05',
|
|
'0.04',
|
|
'0.03',
|
|
'0.02',
|
|
'0.01',
|
|
];
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Colors, name);
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Sort, name);
|
|
|
|
let legendItemsTexts: string[] = [];
|
|
|
|
await waitForCondition(async () => {
|
|
const legendItems = await wizardPage.page.$$(
|
|
COMMON_CHARTKIT_SELECTORS.chartLegendItem,
|
|
);
|
|
|
|
if (!legendItems?.length) {
|
|
return false;
|
|
}
|
|
|
|
legendItemsTexts = (await Promise.all(
|
|
legendItems.map((item) => item.textContent()),
|
|
)) as string[];
|
|
|
|
return legendItemsTexts.join(',') === expectedValues.join(',');
|
|
}).catch(() => {
|
|
throw new Error(
|
|
`Expected order [${expectedValues.join(
|
|
',',
|
|
)}], current order [${legendItemsTexts.join(',')}]`,
|
|
);
|
|
});
|
|
},
|
|
);
|
|
|
|
datalensTest(
|
|
'Sorting works if we sort by the same field that lies in the Color section when there is an Indicator',
|
|
async ({page}) => {
|
|
const wizardPage = new WizardPage({page});
|
|
|
|
await wizardPage.setVisualization(WizardVisualizationId.Column);
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.X, 'Month');
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Y, 'Sales');
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Colors, 'Profit');
|
|
|
|
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Sort, 'Profit');
|
|
|
|
const expectedSortedCategories = [
|
|
'12',
|
|
'9',
|
|
'11',
|
|
'10',
|
|
'3',
|
|
'5',
|
|
'8',
|
|
'6',
|
|
'7',
|
|
'4',
|
|
'2',
|
|
'1',
|
|
];
|
|
|
|
await checkXAxisValuesOrder(wizardPage, expectedSortedCategories);
|
|
|
|
await wizardPage.sectionVisualization.clickOnSortIcon();
|
|
|
|
await checkXAxisValuesOrder(wizardPage, [...expectedSortedCategories].reverse());
|
|
},
|
|
);
|
|
});
|