Skip to content

Commit

Permalink
test(*): add a11y tests and some a11y fix
Browse files Browse the repository at this point in the history
  • Loading branch information
guanpu committed Mar 6, 2019
1 parent 7a6842a commit 5d0ef06
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 27 deletions.
11 changes: 11 additions & 0 deletions docs/grid/index.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@

This grid system provides response rules for almost all mainstream resolution scenes such as 320, 480, 720, 990, 1200, and 1500. The responsive grids are implemented using a 24-column and a 5-point to meet 2, 3, 4, 5, and 6 ratio layouts. The fixed grid uses a 20px width as the unit, it is recommended to use 9, 10, 12, 14, 16, 18, 24, but all from 1 to 30 are also available. You can also customize the fixed grid columns according to your requirements. The breakpoint are: xss(320px), xs(480px), s(720px), m(990px), l(1200px), xl(1500px). Based on the Flex implementation, IE9 is compatible with `display:table;`, but IE9 only supports basic responsive layouts (see API and DEMO for details).

### Accessibility

Though we have build-in support of a11y by adding `<Row>` and `<Col>` with `role="row"` and `role="gridcell"` respectively, in order to achieve more a11y compliance, developers are also expected to add `role="grid"` in the outer wrapper element, as this:

````
<div role="grid">
<Row><Col span={6}>1</Col><Col span={6}>2</Col><Col span={6}>3</Col><Col span={6}>4</Col></Row>
<Row><Col span={6} offset={6}>1</Col><Col span={6} offset={6}>2</Col></Row>
</div>
````

## API

### Grid.Row
Expand Down
11 changes: 11 additions & 0 deletions docs/grid/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@
响应式断点阈值为:xss(320px), xs(480px), s(720px), m(990px), l(1200px), xl(1500px)。<br />
基于Flex实现,对 IE9 通过 `display:table;` 兼容实现,但 IE9 仅支持基本的响应式布局(详情请参考 API 和 DEMO 的说明)。

### 无障碍

默认 `<Row>``<Col>` 会加上 `role="row"``role="gridcell"`, 但是为了完美的无障碍实现, 开发者还应该在外部容器加上 `role="grid"`。示例代码如下:

````
<div role="grid">
<Row><Col span={6}>1</Col><Col span={6}>2</Col><Col span={6}>3</Col><Col span={6}>4</Col></Row>
<Row><Col span={6} offset={6}>1</Col><Col span={6} offset={6}>2</Col></Row>
</div>
````

## API

### Grid.Row
Expand Down
5 changes: 4 additions & 1 deletion src/radio/radio-group.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,17 @@ class RadioGroup extends Component {
const checked = this.state.value === child.props.value;
const tabIndex =
(index === 0 && !this.state.value) || checked ? 0 : -1;
const childrtl =
child.props.rtl === undefined ? rtl : child.props.rtl;
return React.cloneElement(
child,
child.props.tabIndex === undefined
? {
checked,
tabIndex,
rtl: childrtl,
}
: { checked }
: { checked, rtl: childrtl }
);
}
);
Expand Down
6 changes: 5 additions & 1 deletion src/tab/tabs/nav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,11 @@ class Nav extends React.Component {
{tabList}
</Animate>
) : (
<ul className={navCls} ref={this.navRefHandler}>
<ul
role="tablist"
className={navCls}
ref={this.navRefHandler}
>
{tabList}
</ul>
)}
Expand Down
58 changes: 58 additions & 0 deletions test/checkbox/a11y-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Checkbox from '../../src/checkbox/index';
import { unmount, testReact } from '../util/a11y/validate';

Enzyme.configure({ adapter: new Adapter() });

/* eslint-disable no-undef, react/jsx-filename-extension */
describe('Checkbox A11y', () => {
let wrapper;

afterEach(() => {
if (wrapper) {
wrapper.unmount();
wrapper = null;
}
unmount();
});

it('should not have any violations for grouped checkbox with children', async () => {
wrapper = await testReact(
<Checkbox.Group value={['pear', 'watermelon']}>
<Checkbox id="apple" value="apple" className="apple">
苹果
</Checkbox>
<Checkbox id="pear" value="pear">
梨子
</Checkbox>
<Checkbox id="watermelon" value="watermelon">
西瓜
</Checkbox>
</Checkbox.Group>
);
return wrapper;
});

it('should not have any violations for grouped checkbox with datasource', async () => {
const list = [
{
value: 'apple',
label: '苹果',
},
{
value: 'pear',
label: '梨',
},
{
value: 'orange',
label: '橙子',
},
];
wrapper = await testReact(
<Checkbox.Group value={['pear']} dataSource={list} />
);
return wrapper;
});
});
47 changes: 47 additions & 0 deletions test/grid/a11y-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import assert from 'power-assert';
import Grid from '../../src/grid';
import { unmount, testReact } from '../util/a11y/validate';

/* eslint-disable react/jsx-filename-extension */
/* global describe it beforeEach afterEach */

const { Row, Col } = Grid;

Enzyme.configure({ adapter: new Adapter() });

describe('Row a11y', () => {
let wrapper;

afterEach(() => {
if (wrapper) {
wrapper.unmount();
wrapper = null;
}
unmount();
});

it('should not have any violations', async () => {
wrapper = await testReact(
<div role="grid">
<Row>
<Col span={6}>1</Col>
<Col span={6}>2</Col>
<Col span={6}>3</Col>
<Col span={6}>4</Col>
</Row>
<Row>
<Col span={6} offset={6}>
1
</Col>
<Col span={6} offset={6}>
2
</Col>
</Row>
</div>
);
return wrapper;
});
});
68 changes: 43 additions & 25 deletions test/radio/a11y-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,47 +36,65 @@ describe('Radio A11y', () => {
unmount();
});

it.skip('should not have any violations for different states', async () => {
it('should not have any violations for different states', async () => {
wrapper = await testReact(
<div>
<Radio defaultChecked>test 1</Radio>&nbsp;
<Radio checked>test 1</Radio>&nbsp;
<Radio disabled>test 1</Radio>&nbsp;
<Radio checked disabled>
<Radio defaultChecked label="test1">
test 1
</Radio>
&nbsp;
<Radio checked label="test2">
test 1
</Radio>
&nbsp;
<Radio disabled label="test3">
test 1
</Radio>
&nbsp;
<Radio checked disabled label="test4">
test 1
</Radio>
&nbsp;
<Radio />
</div>
);
return wrapper;
});

it.skip('should not have any violations for various label methods', async () => {
it('should not have any violations for Radio Group with children', async () => {
wrapper = await testReact(
<div>
<Radio id="apple">Apple</Radio>&nbsp;
<Radio id="banana" />
<label htmlFor="banana" className="next-radio-label">
Banana
</label>
&nbsp;
<Radio id="apple2" label="Apple" className="testClassname" />
</div>
<Radio.Group value="watermelon">
<Radio id="apple" value="apple" disabled>
苹果
</Radio>
<Radio id="pear" value="pear">
梨子
</Radio>
<Radio id="watermelon" value="watermelon">
西瓜
</Radio>
</Radio.Group>
);
return wrapper;
});

it.skip('should not have any violations for group', async () => {
it('should not have any violations for Radio Group with datasource', async () => {
const list = [
{
value: 'apple',
label: '苹果',
disabled: true,
},
{
value: 'pear',
label: '梨',
},
{
value: 'orange',
label: '橙子',
},
];
wrapper = await testReact(
<div>
<Radio.Group
dataSource={list}
shape="button"
size="small"
value="apple"
/>
</div>
<Radio.Group value={'apple'} dataSource={list} />
);
return wrapper;
});
Expand Down
58 changes: 58 additions & 0 deletions test/range/a11y-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ReactTestUtils from 'react-dom/test-utils';
import Enzyme, { mount, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import simulateEvent from 'simulate-event';
import assert from 'power-assert';
import sinon from 'sinon';
import Range from '../../src/range/index';
import { unmount, testReact } from '../util/a11y/validate';

/* eslint-disable react/no-multi-comp */
Enzyme.configure({ adapter: new Adapter() });

describe('Range A11y', () => {
let wrapper;

afterEach(() => {
if (wrapper) {
wrapper.unmount();
wrapper = null;
}
unmount();
});
it('should not have any violations for range without tips', async () => {
wrapper = await testReact(
<div>
<Range
defaultValue={10}
hasTip={false}
tooltipVisible={false}
/>
</div>
);
return wrapper;
});

/**
* TODO: 'aria-expanded' is added by 'Overlay' by default which conflicts with `role = slider` with respect to a11y standards.
* To fix this will require structural change, ignore temporarily.
*/
it.skip('should not have any violations for range with tips', async () => {
wrapper = await testReact(
<div>
<Range
defaultValue={512}
hasTip={true}
tooltipVisible={true}
min={0}
max={1024}
step={128}
marks={[0, 1024]}
/>
</div>
);
return wrapper;
});
});
30 changes: 30 additions & 0 deletions test/switch/a11y-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import sinon from 'sinon';
import assert from 'power-assert';
import Switch from '../../src/switch/index';
import { unmount, testReact } from '../util/a11y/validate';

Enzyme.configure({ adapter: new Adapter() });

describe('Switch A11y', () => {
let wrapper;

afterEach(() => {
if (wrapper) {
wrapper.unmount();
wrapper = null;
}
unmount();
});
it('should not have any violations for different states', async () => {
wrapper = await testReact(
<div>
<Switch checked />
<Switch defaultChecked={false} size="small" />
</div>
);
return wrapper;
});
});
35 changes: 35 additions & 0 deletions test/tab/a11y-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import Enzyme, { mount, render } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Tab from '../../src/tab/index';
import '../../src/tab/style.js';
import { unmount, testReact } from '../util/a11y/validate';

Enzyme.configure({ adapter: new Adapter() });

describe('Tab a11y', () => {
let wrapper;

afterEach(() => {
if (wrapper) {
wrapper.unmount();
wrapper = null;
}
unmount();
});
it('should not have any violations for tab with children', async () => {
wrapper = await testReact(
<Tab>
<Tab.Item title="foo" />
</Tab>
);
return wrapper;
});
it('should not have any violations for tab with datasource', async () => {
const panes = [1, 2, 3, 4, 5].map((item, index) => (
<Tab.Item title={`item ${item}`} key={index} />
));
wrapper = await testReact(<Tab animation={false}>{panes}</Tab>);
return wrapper;
});
});

0 comments on commit 5d0ef06

Please sign in to comment.