diff --git a/packages/react-charting/docs/TestPlans/GroupedVerticalBarChart/ComponentTests.md b/packages/react-charting/docs/TestPlans/GroupedVerticalBarChart/ComponentTests.md new file mode 100644 index 00000000000000..904dbbc513eca2 --- /dev/null +++ b/packages/react-charting/docs/TestPlans/GroupedVerticalBarChart/ComponentTests.md @@ -0,0 +1,62 @@ +**Grouped Vertical Bar Chart – Component test plan** + +**Sub-components: Bar, Legends, Callout, Labels** + +1. **Bar: Bar data, Bar color, bar label** +1. **Legends: show/hide legends, highlight the corresponding bar on legend hover** +1. **Callout: Default/custom callout** +1. **Labels: x-Axis labels default/rotated** + +| **Test steps** | **Validation** | **Tool used** | +| :-----------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: | :-----------: | +| Test 1: [Snapshot testing] | | | +| - With only data prop, string data on x-axis. | Renders GroupedVerticalBar chart correctly | Enzyme | +| - With HideLegend prop set to “true” | Should hide legends | Enzyme | +| - With HideTooltip prop set to “true” | Should hide the tooltip in chart | Enzyme | +| - With EnabledLegendsWrapLines set to “true” | Should enable the legends to wrap lines if there is not enough space to show all legends on a single line | Enzyme | +| - With ShowXAxisLablesTooltip set to “true” | Should truncate x axis labels and show tooltip on x axis labels | Enzyme | +| - With WrapXAxisLables set to “true” | Should wrap x axis label values | Enzyme | +| - With yAxisTickFormat set to “%d” |
Should render the y-axis ticks in the format specified
| Enzyme | +| - With hideLabels set to “true” | Should hide bar labels | RTL | +| - With yAxisTickCount | Should render y axis with specific tick count | RTL | +| Test 2: Basic props testing | | | +| - HideLegend prop set to “true” | Should not mount legend when hideLegend is true | Enzyme | +| - HideLegend prop set to “false” | Should mount legend when hideLegend is false | Enzyme | +| - HideTooltip prop set to “true” | Should not mount callout when hideTootip is true | Enzyme | +| - HideTooltip prop set to “false” | Should mount callout when hideTootip is false | Enzyme | +| - onRenderCalloutPerDataPoint is given | Should render onRenderCalloutPerDataPoint | Enzyme | +| - onRenderCalloutPerDataPoint is not given | Should not render onRenderCalloutPerDataPoint | Enzyme | +| Test 3: Render calling with respective to props | | | +| - No prop changes: Mount grouped vertical bar chart and then set the same props again | Render function should have been called twice | Enzyme | +| - Prop changes: Mount grouped vertical bar chart and then set some other prop | Render function should have been called twice | Enzyme | +| Test 4: Mouse events | | | +| - Mouse over on a bar | Should render callout correctly on mouseover | Enzyme | +| - Mouse move from one bar to other bar | Should render callout correctly on mouse move | Enzyme | +| - Mouse over on a bar with customized callout | Should render customized callout on mouseover | Enzyme | +| Test 6: [Sub-Component]: Bar | | | +| - Specify bar color | Should render bar with the specified color | RTL | +| - with custom accessibility data | Should render bars with custom accessibility data | RTL | +| Test 7: [Sub-Component]: Legends | | | +| - Hide legends | Should not show any rendered legends | RTL | +| - Hover mouse over bar legends | Should reduce the opacity of the other bars | RTL | +| - Mouse move from one Legend to another Legend | Should reset the opacity of the lines on mouse leave a bar legend | RTL | +| - Single mouse click on bar legends | Should select legend on single mouse click on respective legend | RTL | +| - Double mouse click on bar legends | Should deselect legend on double mouse click on respective legend | RTL | +| Test 8: [Sub-Component]: Callout | | | +| - Hover mouse over a bar | Should show the default callout over that bar | RTL | +| - Set isCalloutForStack is “true” and mouse over on a bar | Should show the default stacked callout over that bar | RTL | +| - Set isCalloutForStack is “false” and mouse over on a bar | Should show the single callout over that bar | RTL | +| - Specify custom callout and hover mouse over a bar | Should show the custom callout over that bar | RTL | +| Test 9: [Sub-Component]: x-axis labels | | | +| - Truncate x-axis labels | Should show the x-axis labels tooltip when hovered | RTL | +| - Rotate x-axis labels | Should rotate the x-axis labels by 45 degrees | RTL | +| - Set showXAxisLablestoolTip to “true” and mouse over on label | Should show XAxis labels tooltip when mouse over on label | RTL | +| Test 10: [Sub-Component]: Screen resolution | | | +| - Increase the screen resolution (zoom in) | Should remain unchanged on zoom in | RTL | +| - Decrease the screen resolution (zoom out) | Should remain unchanged on zoom out | RTL | +| Test 11: Theme changed to Dark Theme | Should reflect theme change | RTL | +| Test 10: Grouped vertical bar chart re-rendering | | | +| - Update chart data | Should re-render chart when data is updated | RTL | +| Test 11: Grouped vertical bar chart with empty/proper data | | | +| - Chart with Empty data | Should render chart with Empty chart are label | Enzyme | +| - Chart with proper data | Should not render chart with empty chart are label | Enzyme | diff --git a/packages/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChartRTL.test.tsx b/packages/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChartRTL.test.tsx index 60911e280ad241..4a10f9807d9d0d 100644 --- a/packages/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChartRTL.test.tsx +++ b/packages/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChartRTL.test.tsx @@ -1,13 +1,459 @@ import * as React from 'react'; -import { queryAllByAttribute, render, waitFor } from '@testing-library/react'; -import { chartPoints, emptyChartPoints } from './GroupedVerticalBarChart.test'; +import { screen, fireEvent, act } from '@testing-library/react'; +import { render, waitFor } from '@testing-library/react'; +import { emptyChartPoints } from './GroupedVerticalBarChart.test'; import { GroupedVerticalBarChart } from './index'; +import { DefaultPalette } from '@fluentui/react/lib/Styling'; +import { getByClass, getById, testWithWait, testWithoutWait } from '../../utilities/TestUtility.test'; +import { IGroupedVerticalBarChartData, IVSChartDataPoint } from '../../index'; +import { DarkTheme } from '@fluentui/theme-samples'; +import { ThemeProvider } from '@fluentui/react'; + +const accessibilityDataPoints: IGroupedVerticalBarChartData[] = [ + { + name: 'Metadata info multi lines text Completed', + series: [ + { + key: 'series1', + data: 33000, + color: DefaultPalette.blueLight, + legend: 'MetaData1', + xAxisCalloutData: '2020/04/30', + yAxisCalloutData: '33%', + callOutAccessibilityData: { + ariaLabel: 'Group series 1 of 4, Bar series 1 of 2 x-Axis 2020/04/30 MetaData1 33%', + }, + }, + { + key: 'series2', + data: 44000, + color: DefaultPalette.blue, + legend: 'MetaData4', + xAxisCalloutData: '2020/04/30', + yAxisCalloutData: '44%', + callOutAccessibilityData: { + ariaLabel: 'Bar series 2 of 2 x-Axis 2020/04/30 MetaData4 44%', + }, + }, + ], + stackCallOutAccessibilityData: { + ariaLabel: 'Group series 1 of 4 x-Axis 2020/04/30 MetaData1 33% MetaData4 44%', + }, + }, +]; + +const chartPoints = [ + { + name: 'Metadata info multi lines text Completed', + series: [ + { + key: 'series1', + data: 33000, + color: DefaultPalette.blueLight, + legend: 'MetaData1', + xAxisCalloutData: '2020/04/30', + yAxisCalloutData: '33%', + }, + { + key: 'series2', + data: 44000, + color: DefaultPalette.blue, + legend: 'MetaData4', + xAxisCalloutData: '2020/04/30', + yAxisCalloutData: '44%', + }, + ], + }, + { + name: 'Meta Data2', + series: [ + { + key: 'series1', + data: 33000, + color: DefaultPalette.blueLight, + legend: 'MetaData1', + xAxisCalloutData: '2020/05/30', + yAxisCalloutData: '33%', + }, + { + key: 'series2', + data: 3000, + color: DefaultPalette.blue, + legend: 'MetaData4', + xAxisCalloutData: '2020/05/30', + yAxisCalloutData: '3%', + }, + ], + }, + + { + name: 'Single line text ', + series: [ + { + key: 'series1', + data: 14000, + color: DefaultPalette.blueLight, + legend: 'MetaData1', + xAxisCalloutData: '2020/06/30', + yAxisCalloutData: '14%', + }, + { + key: 'series2', + data: 50000, + color: DefaultPalette.blue, + legend: 'MetaData4', + xAxisCalloutData: '2020/06/30', + yAxisCalloutData: '50%', + }, + ], + }, +]; + +describe('Grouped Vertical bar chart rendering', () => { + testWithoutWait( + 'Should render the grouped vertical bar chart with string x-axis data', + GroupedVerticalBarChart, + { data: chartPoints }, + container => { + // Assert + expect(container).toMatchSnapshot(); + }, + ); + + testWithWait( + 'Should render the vertical bar chart with string x-axis data with given container width and bar width', + GroupedVerticalBarChart, + { data: chartPoints, width: 1000, barWidth: 16 }, + container => { + // Assert + expect(container).toMatchSnapshot(); + }, + ); +}); + +describe('Grouped vertical bar chart - Subcomponent bar', () => { + testWithWait( + 'Should render the bars with the specified colors', + GroupedVerticalBarChart, + { data: chartPoints }, + container => { + // colors mentioned in the data points itself + // Assert + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + expect(bars[0].getAttribute('fill')).toEqual(DefaultPalette.blueLight); + expect(bars[1].getAttribute('fill')).toEqual(DefaultPalette.blue); + expect(bars[2].getAttribute('fill')).toEqual(DefaultPalette.blueLight); + expect(bars[3].getAttribute('fill')).toEqual(DefaultPalette.blue); + expect(bars[4].getAttribute('fill')).toEqual(DefaultPalette.blueLight); + expect(bars[5].getAttribute('fill')).toEqual(DefaultPalette.blue); + }, + ); + + testWithWait( + 'Should render the bars with labels hidden', + GroupedVerticalBarChart, + { data: chartPoints, hideLabels: true }, + container => { + // Assert + expect(getByClass(container, /barLabel/i)).toHaveLength(0); + }, + ); + + testWithWait( + 'Should render the with custom accessibility data', + GroupedVerticalBarChart, + { data: accessibilityDataPoints }, + container => { + // Assert + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + expect(bars[0]).toHaveAttribute( + 'aria-label', + 'Group series 1 of 4, Bar series 1 of 2 x-Axis 2020/04/30 MetaData1 33%', + ); + }, + ); +}); + +describe('Grouped vertical bar chart - Subcomponent Legends', () => { + testWithoutWait( + 'Should not show any rendered legends when hideLegend is true', + GroupedVerticalBarChart, + { data: chartPoints, hideLegend: true }, + container => { + // Assert + // Legends have 'rect' as a part of their classname + const legends = getByClass(container, /legend-/i); + expect(legends).toHaveLength(0); + }, + ); + + testWithoutWait( + 'Should reduce the opacity of the other bars on mouse over a bar legend', + GroupedVerticalBarChart, + { data: chartPoints }, + container => { + const legends = getByClass(container, /legend-/i); + fireEvent.mouseOver(legends[0]); + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + // Assert + expect(bars[0]).toHaveAttribute('opacity', ''); + expect(bars[1]).toHaveAttribute('opacity', '0.1'); + expect(bars[2]).toHaveAttribute('opacity', ''); + expect(bars[3]).toHaveAttribute('opacity', '0.1'); + expect(bars[4]).toHaveAttribute('opacity', ''); + expect(bars[5]).toHaveAttribute('opacity', '0.1'); + }, + ); + + testWithoutWait( + 'Should update the opacity of the other bars on mouse move from one bar legend to another bar legend', + GroupedVerticalBarChart, + { data: chartPoints }, + container => { + const legends = getByClass(container, /legend-/i); + fireEvent.mouseOver(legends[0]); + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + // Assert + expect(bars[0]).toHaveAttribute('opacity', ''); + expect(bars[1]).toHaveAttribute('opacity', '0.1'); + expect(bars[2]).toHaveAttribute('opacity', ''); + expect(bars[3]).toHaveAttribute('opacity', '0.1'); + expect(bars[4]).toHaveAttribute('opacity', ''); + expect(bars[5]).toHaveAttribute('opacity', '0.1'); + fireEvent.mouseOver(legends[1]); + const updatedBars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + // Assert + expect(updatedBars[0]).toHaveAttribute('opacity', '0.1'); + expect(updatedBars[1]).toHaveAttribute('opacity', ''); + expect(updatedBars[2]).toHaveAttribute('opacity', '0.1'); + expect(updatedBars[3]).toHaveAttribute('opacity', ''); + expect(updatedBars[4]).toHaveAttribute('opacity', '0.1'); + expect(updatedBars[5]).toHaveAttribute('opacity', ''); + }, + ); + + testWithWait( + 'Should select legend on single mouse click on legends', + GroupedVerticalBarChart, + { data: chartPoints }, + container => { + const legends = getByClass(container, /legend-/i); + fireEvent.click(legends![0]); + const legendsAfterClickEvent = screen.getAllByText( + (content, element) => element!.tagName.toLowerCase() === 'button', + ); + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + // Assert + expect(legendsAfterClickEvent[0]).toHaveAttribute('aria-selected', 'true'); + expect(legendsAfterClickEvent[1]).toHaveAttribute('aria-selected', 'false'); + expect(bars[0]).toHaveAttribute('opacity', ''); + expect(bars[1]).toHaveAttribute('opacity', '0.1'); + expect(bars[2]).toHaveAttribute('opacity', ''); + expect(bars[3]).toHaveAttribute('opacity', '0.1'); + expect(bars[4]).toHaveAttribute('opacity', ''); + expect(bars[5]).toHaveAttribute('opacity', '0.1'); + }, + ); + + testWithWait( + 'Should deselect legend on double mouse click on legends', + GroupedVerticalBarChart, + { data: chartPoints }, + container => { + const legends = getByClass(container, /legend-/i); + fireEvent.click(legends![0]); + fireEvent.click(legends![0]); + const legendsAfterClickEvent = screen.getAllByText( + (content, element) => element!.tagName.toLowerCase() === 'button', + ); + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + // Assert + expect(legendsAfterClickEvent[0]).toHaveAttribute('aria-selected', 'false'); + expect(legendsAfterClickEvent[1]).toHaveAttribute('aria-selected', 'false'); + expect(bars[0]).toHaveAttribute('opacity', ''); + expect(bars[1]).toHaveAttribute('opacity', ''); + expect(bars[2]).toHaveAttribute('opacity', ''); + expect(bars[3]).toHaveAttribute('opacity', ''); + expect(bars[4]).toHaveAttribute('opacity', ''); + expect(bars[5]).toHaveAttribute('opacity', ''); + }, + ); +}); + +describe('Grouped vertical bar chart - Subcomponent callout', () => { + testWithWait( + 'Should show the callout over the bar on mouse over', + GroupedVerticalBarChart, + { data: chartPoints, calloutProps: { doNotLayer: true } }, + container => { + // Arrange + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + fireEvent.mouseOver(bars[0]); + // Assert + expect(getById(container, /toolTipcallout/i)).toBeDefined(); + }, + ); + + testWithWait( + 'Should show the stacked callout over the bar on mouse over', + GroupedVerticalBarChart, + { data: chartPoints, isCalloutForStack: true, calloutProps: { doNotLayer: true } }, + container => { + // Arrange + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + expect(bars).toHaveLength(6); + fireEvent.mouseOver(bars[0]); + // Assert + expect(getByClass(container, /calloutlegendText/i)).toBeDefined(); + expect(getByClass(container, /calloutlegendText/i)).toHaveLength(2); + }, + ); + + testWithWait( + 'Should show the single callout over the bar on mouse over', + GroupedVerticalBarChart, + { data: chartPoints, isCalloutForStack: false, calloutProps: { doNotLayer: true } }, + container => { + // Arrange + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + expect(bars).toHaveLength(6); + fireEvent.mouseOver(bars[0]); + // Assert + expect(getByClass(container, /calloutlegendText/i)).toBeDefined(); + expect(getByClass(container, /calloutlegendText/i)).toHaveLength(1); + }, + ); + + testWithWait( + 'Should show the custom callout over the bar on mouse over', + GroupedVerticalBarChart, + { + data: chartPoints, + calloutProps: { doNotLayer: true }, + onRenderCalloutPerDataPoint: (props: IVSChartDataPoint) => + props ? ( +Custom Callout Content
+