Skip to content

Commit

Permalink
*fix a11y tests (#528)
Browse files Browse the repository at this point in the history
* *fix a11y tests

* *fix a11y tests
  • Loading branch information
Sodik authored Nov 14, 2023
1 parent b2ce6e5 commit 91ef0da
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 87 deletions.
4 changes: 2 additions & 2 deletions packages/test-helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
},
"dependencies": {
"@hazelcast/services": "^1.3.1",
"@types/jest-axe": "^3.5.3",
"jest-axe": "^5.0.1"
"@types/jest-axe": "^3.5.8",
"jest-axe": "^8.0.0"
},
"devDependencies": {
"@types/enzyme": "^3.10.12",
Expand Down
3 changes: 0 additions & 3 deletions packages/ui/__tests__/Checkbox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ describe('Checkbox', () => {
onChange,
onBlur,
checked: true,
'aria-checked': 'true',
'aria-invalid': false,
'aria-required': true,
'aria-describedby': undefined,
Expand All @@ -73,7 +72,6 @@ describe('Checkbox', () => {
onChange,
onBlur,
checked: true,
'aria-checked': 'true',
'aria-invalid': true,
'aria-required': undefined,
'aria-describedby': undefined,
Expand All @@ -89,7 +87,6 @@ describe('Checkbox', () => {

expect(wrapper.find(Check).exists()).toBeFalsy()
expect(wrapper.find(Minus).exists()).toBeTruthy()
expect(wrapper.find('input').props()).toHaveProperty('aria-checked', 'mixed')
})

it('Checkbox is passed a disabled property, input contains disabled property', async () => {
Expand Down
26 changes: 20 additions & 6 deletions packages/ui/__tests__/Table/Cell.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { mountAndCheckA11Y } from '@hazelcast/test-helpers'
import React from 'react'
import React, { PropsWithChildren } from 'react'
import { AlertTriangle } from 'react-feather'
import { useUID } from 'react-uid'

Expand All @@ -12,6 +12,12 @@ import styles from '../../src/Table/Cell.module.scss'
jest.mock('react-uid')
const useUIDMock = useUID as jest.Mock<ReturnType<typeof useUID>>

const Wrapper = (props: PropsWithChildren<object>) => (
<div role="table">
<div role="row">{props.children}</div>
</div>
)

describe('CellWarning', () => {
const iconId = 'iconId'

Expand Down Expand Up @@ -54,13 +60,14 @@ describe('CellWarning', () => {
describe('Cell', () => {
const cellPropsBase: CellProps = {
align: 'left',
role: 'cell',
}

const expectedPropsBase = {
'data-test': 'table-cell',
className: `${styles.td} ${styles.alignLeft}`,
style: undefined,
role: undefined,
role: 'cell',
'aria-colspan': undefined,
'aria-sort': undefined,
onClick: undefined,
Expand All @@ -85,27 +92,34 @@ describe('Cell', () => {
{ ...expectedPropsBase, className: `${styles.td} ${styles.alignRight}` },
],
[
{ ...cellPropsBase, colSpan: 1, style: { width: 40 }, className: 'testClassName', role: '' },
{ ...cellPropsBase, colSpan: 1, style: { width: 40 }, className: 'testClassName' },
{
...expectedPropsBase,
className: `${styles.td} ${styles.alignLeft} testClassName`,
style: { width: 40 },
'aria-colspan': 1,
role: '',
},
],
]

it.each(data)('returns div with correct props for given Cell props', async (cellProps, expectedProps) => {
const wrapper = await mountAndCheckA11Y(<Cell {...cellProps}>Cell</Cell>)
const wrapper = await mountAndCheckA11Y(
<Wrapper>
<Cell {...cellProps}>Cell</Cell>
</Wrapper>,
)

expect(wrapper.findDataTest('table-cell').props()).toEqual(expectedProps)
})

it('renders CellWarning when warning prop is defined', async () => {
const warning = 'testWarning'

const wrapper = await mountAndCheckA11Y(<Cell {...cellPropsBase} warning={warning} />)
const wrapper = await mountAndCheckA11Y(
<Wrapper>
<Cell {...cellPropsBase} warning={warning} />
</Wrapper>,
)

expect(wrapper.find(CellWarning).props()).toEqual<CellWarningProps>({
warning: warning,
Expand Down
69 changes: 49 additions & 20 deletions packages/ui/__tests__/Table/Header.test.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
import { mountAndCheckA11Y } from '@hazelcast/test-helpers'
import React from 'react'
import React, { ReactNode } from 'react'
import { ChevronDown, ChevronUp } from 'react-feather'
import { mountAndCheckA11Y } from '@hazelcast/test-helpers'

import { Icon, IconProps } from '../../src/Icon'
import { Header, HeaderProps } from '../../src/Table/Header'

import styles from '../../src/Table/Header.module.scss'

const Wrapper = ({ children, ...props }: { children: (props: Partial<HeaderProps>) => ReactNode } & object) => (
<div role="table">
<div role="row">{children(props)}</div>
</div>
)

const headerPropsBase: HeaderProps = {
index: 0,
align: 'left',
role: 'columnheader',
canSort: false,
isSorted: false,
isSortedDesc: false,
canResize: false,
isResizing: false,
getResizerProps: jest.fn() as HeaderProps['getResizerProps'],
isLastHeader: false,
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const expectedContainerProps: Record<string, any> = {
'data-test': 'table-header-container',
className: styles.container,
style: undefined,
role: undefined,
role: 'columnheader',
'aria-colspan': undefined,
'aria-sort': undefined,
children: expect.anything(),
Expand Down Expand Up @@ -78,12 +84,11 @@ describe('Header', () => {
{ ...expectedContentProps, className: `${styles.th} ${styles.alignRight}` },
],
[
{ ...headerPropsBase, colSpan: 1, style: { width: 40 }, className: 'testClassName', onClick, role: '' },
{ ...headerPropsBase, colSpan: 1, style: { width: 40 }, className: 'testClassName', onClick },
{
...expectedContainerProps,
className: `${styles.container} testClassName`,
style: { width: 40 },
role: '',
'aria-colspan': 1,
},
{ ...expectedContentProps, role: 'button', tabIndex: 0, onClick, onKeyPress: expect.anything() },
Expand All @@ -93,7 +98,7 @@ describe('Header', () => {
it.each(data)(
'returns div with correct props for given Header props',
async (headerProps, expectedContainerProps, expectedContentProps) => {
const wrapper = await mountAndCheckA11Y(<Header {...headerProps}>Header</Header>)
const wrapper = await mountAndCheckA11Y(<Wrapper>{() => <Header {...headerProps}>Header</Header>}</Wrapper>)

expect(wrapper.findDataTest('table-header-container').props()).toEqual(expectedContainerProps)
expect(wrapper.findDataTest('table-header-content').props()).toEqual(expectedContentProps)
Expand All @@ -102,9 +107,13 @@ describe('Header', () => {

it('renders ChevronDown Icon when sorting in descending order', async () => {
const wrapper = await mountAndCheckA11Y(
<Header {...headerPropsBase} canSort isSorted isSortedDesc>
Header
</Header>,
<Wrapper>
{() => (
<Header {...headerPropsBase} canSort isSorted isSortedDesc>
Header
</Header>
)}
</Wrapper>,
)

expect(wrapper.find(Icon).props()).toEqual<IconProps>({
Expand All @@ -117,9 +126,13 @@ describe('Header', () => {

it('renders ChevronUp Icon when sorting in ascending order', async () => {
const wrapper = await mountAndCheckA11Y(
<Header {...headerPropsBase} canSort isSorted isSortedDesc={false}>
Header
</Header>,
<Wrapper>
{() => (
<Header {...headerPropsBase} canSort isSorted isSortedDesc={false}>
Header
</Header>
)}
</Wrapper>,
)

expect(wrapper.find(Icon).props()).toEqual<IconProps>({
Expand All @@ -136,9 +149,13 @@ describe('Header', () => {
})

const wrapper = await mountAndCheckA11Y(
<Header {...headerPropsBase} canResize getResizerProps={getResizerProps}>
Header
</Header>,
<Wrapper>
{(props) => (
<Header {...headerPropsBase} canResize getResizerProps={getResizerProps} {...props}>
Header
</Header>
)}
</Wrapper>,
)

expect(wrapper.findDataTest('table-header-column-resizer-container').props()).toEqual({
Expand All @@ -156,7 +173,15 @@ describe('Header', () => {
})

it('draggable attribute', async () => {
const wrapper = await mountAndCheckA11Y(<Header {...headerPropsBase}>Header</Header>)
const wrapper = await mountAndCheckA11Y(
<Wrapper>
{(props) => (
<Header {...headerPropsBase} {...props}>
Header
</Header>
)}
</Wrapper>,
)

expect(wrapper.findDataTest('table-header-content').prop('draggable')).toBeFalsy()

Expand Down Expand Up @@ -187,9 +212,13 @@ describe('Header', () => {
const onDrop = jest.fn()
const setData = jest.fn()
const wrapper = await mountAndCheckA11Y(
<Header {...headerPropsBase} onDragStart={onDragStart} onDrop={onDrop}>
Header
</Header>,
<Wrapper>
{() => (
<Header {...headerPropsBase} onDragStart={onDragStart} onDrop={onDrop}>
Header
</Header>
)}
</Wrapper>,
)

expect(onDragStart).toBeCalledTimes(0)
Expand Down
49 changes: 35 additions & 14 deletions packages/ui/__tests__/Table/Row.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,36 @@ describe('Row', () => {
},
],
[
{ ariaRowIndex: 1, onClick: jest.fn(), style: { width: 40 }, className: 'testClassName', role: '', children: 'Row' },
{
ariaRowIndex: 1,
onClick: jest.fn(),
style: { width: 40 },
className: 'testClassName',
role: 'row',
children: <div role="cell">Row</div>,
},
{
'data-test': rowDataTest,
className: `${styles.row} ${styles.clickable} testClassName`,
role: '',
role: 'row',
'aria-rowindex': 1,
tabIndex: 0,

onClick: expect.anything(),

onKeyPress: expect.anything(),
style: { width: 40 },
children: 'Row',
children: <div role="cell">Row</div>,
},
],
]

it.each(rowData)('returns <div> with correct props for given Row props', async (cellProps, expectedDivProps) => {
const wrapper = await mountAndCheckA11Y(<Row {...cellProps} />)
const wrapper = await mountAndCheckA11Y(
<div role={cellProps.role === 'row' ? 'table' : undefined}>
<Row {...cellProps} />
</div>,
)

expect(wrapper.findDataTest(rowDataTest).props()).toEqual(expectedDivProps)
})
Expand All @@ -64,11 +75,18 @@ describe('Row', () => {
{ className: styles.link, id: '1', style: undefined, href: 'testHref', children: 'Row' },
],
[
{ ariaRowIndex: 1, href: 'testHref', style: { width: 40 }, className: 'testClassName', role: '', children: 'Row' },
{
ariaRowIndex: 1,
href: 'testHref',
style: { width: 40 },
className: 'testClassName',
role: 'row',
children: 'Row',
},
{
'data-test': rowDataTest,
className: `${styles.linkRow} testClassName`,
role: '',
role: 'row',
'aria-rowindex': 1,
'aria-owns': '2',
children: expect.anything(),
Expand All @@ -77,7 +95,8 @@ describe('Row', () => {
],
]

it.each(linkRowData)(
// Blocked by https://github.com/w3c/html-aria/issues/473
it.skip.each(linkRowData)(
'returns <div> with <a> child, both with correct props for given Row props',
async (cellProps, expectedOuterDivProps, expectedInnerAnchorProps) => {
const wrapper = await mountAndCheckA11Y(<LinkRow {...cellProps} />)
Expand Down Expand Up @@ -123,30 +142,32 @@ const expectedHeaderRowElementProps: AnyProps = {
'data-test': headerRowDataTest,
className: styles.headerRow,
style: undefined,
role: undefined,
role: 'row',
'aria-rowindex': undefined,
children: undefined,
children: expect.anything(),
}

describe('HeaderRow', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const data: [PropsWithChildren<HeaderRowProps>, AnyProps][] = [
[{}, expectedHeaderRowElementProps],
[{ role: 'row', children: <div role="cell" /> }, expectedHeaderRowElementProps],
[
{ ariaRowIndex: 1, style: { width: 40 }, className: 'testClassName', role: '', children: 'Header Row' },
{ ariaRowIndex: 1, role: 'row', style: { width: 40 }, className: 'testClassName', children: <div role="cell">Header Row</div> },
{
...expectedHeaderRowElementProps,
className: `${styles.headerRow} testClassName`,
style: { width: 40 },
role: '',
'aria-rowindex': 1,
children: 'Header Row',
},
],
]

it.each(data)('returns <div> with correct props for given HeaderRow props', async (cellProps, expectedElementProps) => {
const wrapper = await mountAndCheckA11Y(<HeaderRow {...cellProps} />)
const wrapper = await mountAndCheckA11Y(
<div role="table">
<HeaderRow {...cellProps} />
</div>,
)

expect(wrapper.findDataTest(headerRowDataTest).props()).toEqual(expectedElementProps)
})
Expand Down
9 changes: 4 additions & 5 deletions packages/ui/__tests__/Table/Table.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,13 @@ describe('Table', () => {
})
})

const cellRowGroup = table.findDataTest('table-cell-row-group')
expect(cellRowGroup.props()).toMatchObject({
'data-test': 'table-cell-row-group',
role: 'rowgroup',
const tableContent = table.findDataTest('table-content')
expect(tableContent.props()).toMatchObject({
'data-test': 'table-content',
className: 'content',
})

const cellRows = cellRowGroup.find(Row)
const cellRows = tableContent.find(Row)
cellRows.forEach((cellRow, i: number) => {
expect(cellRow.props()).toMatchObject<PropsWithChildren<RowProps>>({
// 1 for header row, 1 because we're indexing from 0
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"babel-loader": "^9.1.2",
"doiuse": "^4.4.1",
"enzyme": "^3.11.0",
"jest-axe": "^5.0.1",
"jest-axe": "^8.0.0",
"loki": "^0.32.0",
"postcss": "^8.4.23",
"postcss-cli": "^9.1.0",
Expand Down
Loading

0 comments on commit 91ef0da

Please sign in to comment.