@neo4j-ndl/react-charts
Version:
React implementation of charts from Neo4j Design System
271 lines • 14.4 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.clickSeries = exports.expectAllLegendsNeutral = exports.expectLegendsDeselected = exports.expectLegendsSelected = exports.expectLegendSeriesToBeVisibleInChart = exports.expectLegendSeriesToBeHighlightedInChart = exports.expectSingleSeriesNotToBeBlurred = exports.expectChartElementVisible = exports.multiSeriesChart = exports.multiSeriesChartProps = exports.chartColorsAfterHighlighting = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
/**
*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
const base_1 = require("@neo4j-ndl/base");
const react_charts_1 = require("@neo4j-ndl/react-charts");
const experimental_ct_react_1 = require("@playwright/experimental-ct-react");
/**
* Convert hex color to rgb format
*
* @param hex color in hex code format
* @returns color in rgb format rgb(_, _, _)
*/
const convertHexToRGB = (hex) => {
hex = hex.replace(/^#/, '');
const red = parseInt(hex.substring(0, 2), 16);
const green = parseInt(hex.substring(2, 4), 16);
const blue = parseInt(hex.substring(4, 6), 16);
return `rgb(${red}, ${green}, ${blue})`;
};
exports.chartColorsAfterHighlighting = {
1: 'rgb(93,207,216)',
2: 'rgb(84,80,223)',
3: 'rgb(242,152,62)',
4: 'rgb(221,75,155)',
5: 'rgb(156,154,255)',
6: 'rgb(132,244,136)',
7: 'rgb(69,140,249)',
8: 'rgb(113,69,188)',
9: 'rgb(240,210,70)',
10: 'rgb(210,126,49)',
11: 'rgb(78,151,121)',
12: 'rgb(190,255,117)',
};
exports.multiSeriesChartProps = {
dataset: {
dimensions: ['day', 'first', 'second', 'third', 'fourth', 'fifth', 'sixth'],
source: [
['Monday', 20, 40, 60, 80, 100, 120],
['Tuesday', 30, 50, 70, 90, 110, 130],
['Wednesday', 25, 45, 65, 85, 105, 125],
['Thursday', 35, 55, 75, 95, 115, 135],
['Friday', 40, 60, 80, 100, 120, 140],
],
},
xAxis: {
type: 'category',
},
yAxis: {
type: 'value',
},
series: [
{
name: 'First Series',
type: 'line',
encode: { x: 'day', y: 'first' },
},
{
name: 'Second Series',
type: 'line',
encode: { x: 'day', y: 'second' },
},
{
name: 'Third Series',
type: 'line',
encode: { x: 'day', y: 'third' },
},
{
name: 'Fourth Series',
type: 'line',
encode: { x: 'day', y: 'fourth' },
},
{
name: 'Fifth Series',
type: 'line',
encode: { x: 'day', y: 'fifth' },
},
{
name: 'Sixth Series',
type: 'line',
encode: { x: 'day', y: 'sixth' },
},
],
legend: {
show: true,
wrappingType: 'wrapping',
},
option: {},
};
const multiSeriesChart = ({ chartProps, width = '100%', height = '400px', }) => ((0, jsx_runtime_1.jsx)("div", { style: { height, width }, className: "ndl-chart", children: (0, jsx_runtime_1.jsx)(react_charts_1.Chart, Object.assign({}, exports.multiSeriesChartProps, chartProps)) }));
exports.multiSeriesChart = multiSeriesChart;
const expectChartElementVisible = (page) => __awaiter(void 0, void 0, void 0, function* () {
yield (0, experimental_ct_react_1.expect)(page.locator('svg')).toBeVisible();
yield (0, experimental_ct_react_1.expect)(page.locator('.ndl-chart-legend')).toBeVisible();
});
exports.expectChartElementVisible = expectChartElementVisible;
const SELECTORS = {
CHECKMARK: '.ndl-chart-legend-item-square-checkmark',
DESELECTED: '.ndl-chart-legend-item-deselected',
seriesCheckmark: (name) => `[data-labelname="${name}"] .ndl-chart-legend-item-square-checkmark`,
seriesDeselected: (name) => `[data-labelname="${name}"].ndl-chart-legend-item-deselected`,
};
const getGraphPaletteColorFromSeriesIndex = (index) => {
const hexColor = base_1.tokens.categorical[index];
if (!hexColor) {
throw new Error(`Categorical palette index ${index} not found`);
}
return hexColor;
};
/**
* Checks so a single series is not blurred.
*/
const expectSingleSeriesNotToBeBlurred = (page, seriesName) => __awaiter(void 0, void 0, void 0, function* () {
const allChartSeries = exports.multiSeriesChartProps.series;
const seriesIndex = allChartSeries.findIndex((seriesItem) => seriesItem.name === seriesName) +
1;
const rgbSeriesColor = exports.chartColorsAfterHighlighting[seriesIndex];
const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(seriesIndex.toString());
// More flexible color matching - try both with and without spaces
const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');
const hexRgb = convertHexToRGB(hexSeriesColor);
const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');
const pathLocator = page
.locator(`path[stroke="${rgbSeriesColor}"]`)
.or(page.locator(`path[stroke="${rgbWithSpaces}"]`))
.or(page.locator(`path[stroke="${hexSeriesColor}"]`))
.or(page.locator(`path[stroke="${convertHexToRGB(hexSeriesColor)}"]`))
.or(page.locator(`path[stroke="${rgbWithoutSpaces}"]`));
// Wait for the element to be attached to the DOM before checking its attributes
yield (0, experimental_ct_react_1.expect)(pathLocator).toBeAttached({ timeout: 10000 });
yield (0, experimental_ct_react_1.expect)(pathLocator).not.toHaveAttribute('stroke-opacity');
});
exports.expectSingleSeriesNotToBeBlurred = expectSingleSeriesNotToBeBlurred;
/**
* Checks so that the seriesNamesToBeHighlighted are visible in the chart and that other series are blurred.
*/
const expectLegendSeriesToBeHighlightedInChart = (page, seriesNamesToBeHighlighted) => __awaiter(void 0, void 0, void 0, function* () {
const allChartSeries = exports.multiSeriesChartProps.series;
for (const name of seriesNamesToBeHighlighted) {
const highlightedSeriesIndex = allChartSeries.findIndex((seriesItem) => seriesItem.name === name) + 1;
const rgbSeriesColor = exports.chartColorsAfterHighlighting[highlightedSeriesIndex];
const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(highlightedSeriesIndex.toString());
const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');
const hexRgb = convertHexToRGB(hexSeriesColor);
const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');
const pathLocator = page
.locator(`path[stroke="${rgbSeriesColor}"]`)
.or(page.locator(`path[stroke="${rgbWithSpaces}"]`))
.or(page.locator(`path[stroke="${hexSeriesColor}"]`))
.or(page.locator(`path[stroke="${convertHexToRGB(hexSeriesColor)}"]`))
.or(page.locator(`path[stroke="${rgbWithoutSpaces}"]`));
yield (0, experimental_ct_react_1.expect)(pathLocator).not.toHaveAttribute('stroke-opacity');
}
const seriesToBeBlurred = allChartSeries.filter((series) => !seriesNamesToBeHighlighted.includes(series.name));
for (const series of seriesToBeBlurred) {
const blurredSeriesIndex = allChartSeries.findIndex((seriesItem) => seriesItem.name === series.name) + 1;
const rgbSeriesColor = exports.chartColorsAfterHighlighting[blurredSeriesIndex];
const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(blurredSeriesIndex.toString());
const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');
const hexRgb = convertHexToRGB(hexSeriesColor);
const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');
const pathLocator = page
.locator(`path[stroke="${rgbSeriesColor}"]`)
.or(page.locator(`path[stroke="${rgbWithSpaces}"]`))
.or(page.locator(`path[stroke="${hexSeriesColor}"]`))
.or(page.locator(`path[stroke="${convertHexToRGB(hexSeriesColor)}"]`))
.or(page.locator(`path[stroke="${rgbWithoutSpaces}"]`));
yield (0, experimental_ct_react_1.expect)(pathLocator).toHaveAttribute('stroke-opacity');
}
});
exports.expectLegendSeriesToBeHighlightedInChart = expectLegendSeriesToBeHighlightedInChart;
/**
* Identifies if the series are visible / not visible in the chart by checking for a path with the series color (lacks other unique identifiers)
* Apache Echarts displays the path color in both hex, rgb and a slightly adjusted rgb when highlighted, therefor we need to check for all three when looking for the series in the chart.
*/
const expectLegendSeriesToBeVisibleInChart = (page, seriesNamesToBeVisible) => __awaiter(void 0, void 0, void 0, function* () {
const allChartSeries = exports.multiSeriesChartProps.series;
// Check so that the series that should be visible are present in the chart
for (const name of seriesNamesToBeVisible) {
const visibleSeriesIndex = allChartSeries.findIndex((series) => series.name === name) + 1;
const rgbSeriesColor = exports.chartColorsAfterHighlighting[visibleSeriesIndex];
const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(visibleSeriesIndex.toString());
const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');
const hexRgb = convertHexToRGB(hexSeriesColor);
const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');
yield (0, experimental_ct_react_1.expect)(page
.locator(`path[stroke="${rgbSeriesColor}"]`)
.or(page.locator(`path[stroke="${rgbWithSpaces}"]`))
.or(page.locator(`path[stroke="${hexSeriesColor}"]`))
.or(page.locator(`path[stroke="${convertHexToRGB(hexSeriesColor)}"]`))
.or(page.locator(`path[stroke="${rgbWithoutSpaces}"]`))).toBeVisible({ timeout: 10000 });
}
// Check so that the other series are not present in the chart
const hiddenSeries = exports.multiSeriesChartProps.series.filter((series) => !seriesNamesToBeVisible.includes(series.name));
for (const hiddenSeriesItem of hiddenSeries) {
const hiddenSeriesIndex = allChartSeries.findIndex((allChartSeriesItem) => hiddenSeriesItem.name === allChartSeriesItem.name) + 1;
const rgbSeriesColor = exports.chartColorsAfterHighlighting[hiddenSeriesIndex];
const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(hiddenSeriesIndex.toString());
const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');
const hexRgb = convertHexToRGB(hexSeriesColor);
const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');
yield (0, experimental_ct_react_1.expect)(page
.locator(`path[stroke="${rgbSeriesColor}"]`)
.or(page.locator(`path[stroke="${rgbWithSpaces}"]`))
.or(page.locator(`path[stroke="${hexSeriesColor}"]`))
.or(page.locator(`path[stroke="${convertHexToRGB(hexSeriesColor)}"]`))
.or(page.locator(`path[stroke="${rgbWithoutSpaces}"]`))).not.toBeVisible();
}
});
exports.expectLegendSeriesToBeVisibleInChart = expectLegendSeriesToBeVisibleInChart;
// Check so legends are selected -> has checkmark and no strike-through classes
const expectLegendsSelected = (page, seriesNames) => __awaiter(void 0, void 0, void 0, function* () {
for (const name of seriesNames) {
yield (0, experimental_ct_react_1.expect)(page.locator(SELECTORS.seriesCheckmark(name))).toBeVisible();
yield (0, experimental_ct_react_1.expect)(page.locator(SELECTORS.seriesDeselected(name))).not.toBeVisible();
}
});
exports.expectLegendsSelected = expectLegendsSelected;
// Check so legends are deselected -> has strike-through and no checkmark classes
const expectLegendsDeselected = (page, seriesNames) => __awaiter(void 0, void 0, void 0, function* () {
for (const name of seriesNames) {
yield (0, experimental_ct_react_1.expect)(page.locator(SELECTORS.seriesDeselected(name))).toBeVisible();
yield (0, experimental_ct_react_1.expect)(page.locator(SELECTORS.seriesCheckmark(name))).not.toBeVisible();
}
});
exports.expectLegendsDeselected = expectLegendsDeselected;
// Check so all legends are neutral -> no checkmark and no strike-through classes
const expectAllLegendsNeutral = (page) => __awaiter(void 0, void 0, void 0, function* () {
yield (0, experimental_ct_react_1.expect)(page.locator(SELECTORS.CHECKMARK)).not.toBeVisible();
yield (0, experimental_ct_react_1.expect)(page.locator(SELECTORS.DESELECTED)).not.toBeVisible();
});
exports.expectAllLegendsNeutral = expectAllLegendsNeutral;
/**
* Clicks the series legend item and hover the chart to make sure no blur effect exists on other series in the chart.
* This is needed to make sure the series has the correct color when looking for them in the chart in later steps.
*/
const clickSeries = (page, seriesName) => __awaiter(void 0, void 0, void 0, function* () {
yield page.locator(`[data-labelname="${seriesName}"]`).click();
yield page.hover('.ndl-chart');
});
exports.clickSeries = clickSeries;
//# sourceMappingURL=chart-test-utils.js.map