Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*fix a11y tests #528

Merged
merged 2 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading