UNPKG

@neo4j-ndl/react-charts

Version:

React implementation of charts from Neo4j Design System

259 lines 12.8 kB
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()); }); }; import { jsx as _jsx } from "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/>. */ import { tokens } from '@neo4j-ndl/base'; import { Chart } from '@neo4j-ndl/react-charts'; import { expect } from '@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})`; }; export const 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)', }; export const 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: {}, }; export const multiSeriesChart = ({ chartProps, width = '100%', height = '400px', }) => (_jsx("div", { style: { height, width }, className: "ndl-chart", children: _jsx(Chart, Object.assign({}, multiSeriesChartProps, chartProps)) })); export const expectChartElementVisible = (page) => __awaiter(void 0, void 0, void 0, function* () { yield expect(page.locator('svg')).toBeVisible(); yield expect(page.locator('.ndl-chart-legend')).toBeVisible(); }); 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 = tokens.categorical[index]; if (!hexColor) { throw new Error(`Categorical palette index ${index} not found`); } return hexColor; }; /** * Checks so a single series is not blurred. */ export const expectSingleSeriesNotToBeBlurred = (page, seriesName) => __awaiter(void 0, void 0, void 0, function* () { const allChartSeries = multiSeriesChartProps.series; const seriesIndex = allChartSeries.findIndex((seriesItem) => seriesItem.name === seriesName) + 1; const rgbSeriesColor = 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 expect(pathLocator).toBeAttached({ timeout: 10000 }); yield expect(pathLocator).not.toHaveAttribute('stroke-opacity'); }); /** * Checks so that the seriesNamesToBeHighlighted are visible in the chart and that other series are blurred. */ export const expectLegendSeriesToBeHighlightedInChart = (page, seriesNamesToBeHighlighted) => __awaiter(void 0, void 0, void 0, function* () { const allChartSeries = multiSeriesChartProps.series; for (const name of seriesNamesToBeHighlighted) { const highlightedSeriesIndex = allChartSeries.findIndex((seriesItem) => seriesItem.name === name) + 1; const rgbSeriesColor = 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 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 = 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 expect(pathLocator).toHaveAttribute('stroke-opacity'); } }); /** * 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. */ export const expectLegendSeriesToBeVisibleInChart = (page, seriesNamesToBeVisible) => __awaiter(void 0, void 0, void 0, function* () { const allChartSeries = 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 = chartColorsAfterHighlighting[visibleSeriesIndex]; const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(visibleSeriesIndex.toString()); const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', '); const hexRgb = convertHexToRGB(hexSeriesColor); const rgbWithoutSpaces = hexRgb.replace(/, /g, ','); yield 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 = 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 = chartColorsAfterHighlighting[hiddenSeriesIndex]; const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(hiddenSeriesIndex.toString()); const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', '); const hexRgb = convertHexToRGB(hexSeriesColor); const rgbWithoutSpaces = hexRgb.replace(/, /g, ','); yield 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(); } }); // Check so legends are selected -> has checkmark and no strike-through classes export const expectLegendsSelected = (page, seriesNames) => __awaiter(void 0, void 0, void 0, function* () { for (const name of seriesNames) { yield expect(page.locator(SELECTORS.seriesCheckmark(name))).toBeVisible(); yield expect(page.locator(SELECTORS.seriesDeselected(name))).not.toBeVisible(); } }); // Check so legends are deselected -> has strike-through and no checkmark classes export const expectLegendsDeselected = (page, seriesNames) => __awaiter(void 0, void 0, void 0, function* () { for (const name of seriesNames) { yield expect(page.locator(SELECTORS.seriesDeselected(name))).toBeVisible(); yield expect(page.locator(SELECTORS.seriesCheckmark(name))).not.toBeVisible(); } }); // Check so all legends are neutral -> no checkmark and no strike-through classes export const expectAllLegendsNeutral = (page) => __awaiter(void 0, void 0, void 0, function* () { yield expect(page.locator(SELECTORS.CHECKMARK)).not.toBeVisible(); yield expect(page.locator(SELECTORS.DESELECTED)).not.toBeVisible(); }); /** * 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. */ export const clickSeries = (page, seriesName) => __awaiter(void 0, void 0, void 0, function* () { yield page.locator(`[data-labelname="${seriesName}"]`).click(); yield page.hover('.ndl-chart'); }); //# sourceMappingURL=chart-test-utils.js.map