datalens-ui/tests/suites/wizard/sort/sortPlaceholderActions.test.ts
2026-06-24 20:31:05 +05:00

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());
},
);
});