diff options
author | Wouter Admiraal <wouter.admiraal@sonarsource.com> | 2019-06-06 11:09:45 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-06-28 08:45:38 +0200 |
commit | 2ed3bdc4997ed05e5486940abc726dc008f6cd20 (patch) | |
tree | ebb39b5f14a17b14458d2ac750a72d2ae6c85f2d | |
parent | 9c3628f7f4d5745c010cb2f958129495fdcda632 (diff) | |
download | sonarqube-2ed3bdc4997ed05e5486940abc726dc008f6cd20.tar.gz sonarqube-2ed3bdc4997ed05e5486940abc726dc008f6cd20.zip |
SONAR-11773 Make issues 'See Rules Details' accessible
3 files changed, 52 insertions, 3 deletions
diff --git a/server/sonar-web/src/main/js/components/workspace/WorkspaceRuleViewer.tsx b/server/sonar-web/src/main/js/components/workspace/WorkspaceRuleViewer.tsx index c30aa9279d8..e418177f965 100644 --- a/server/sonar-web/src/main/js/components/workspace/WorkspaceRuleViewer.tsx +++ b/server/sonar-web/src/main/js/components/workspace/WorkspaceRuleViewer.tsx @@ -30,17 +30,34 @@ export interface Props extends T.Omit<WorkspaceHeaderProps, 'children' | 'onClos onLoad: (details: { key: string; name: string }) => void; } +interface State { + loading: boolean; +} + export default class WorkspaceRuleViewer extends React.PureComponent<Props> { + state: State = { loading: true }; + + componentDidUpdate(prevProps: Props) { + if (prevProps.rule.key !== this.props.rule.key) { + this.setState({ loading: true }); + } + } + handleClose = () => { this.props.onClose(this.props.rule.key); }; handleLoaded = (rule: { name: string }) => { this.props.onLoad({ key: this.props.rule.key, name: rule.name }); + // Allow time for the actual rendering, and the browser to pick it up. + setTimeout(() => { + this.setState({ loading: false }); + }, 1000); }; render() { const { rule } = this.props; + const { loading } = this.state; return ( <div className="workspace-viewer"> @@ -54,7 +71,11 @@ export default class WorkspaceRuleViewer extends React.PureComponent<Props> { <WorkspaceRuleTitle rule={rule} /> </WorkspaceHeader> - <div className="workspace-viewer-container" style={{ height: this.props.height }}> + <div + aria-busy={loading} + aria-live="polite" + className="workspace-viewer-container" + style={{ height: this.props.height }}> <WorkspaceRuleDetails onLoad={this.handleLoaded} organizationKey={rule.organization} diff --git a/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceRuleViewer-test.tsx b/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceRuleViewer-test.tsx index 9092b38f1ec..62d39d710e4 100644 --- a/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceRuleViewer-test.tsx +++ b/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceRuleViewer-test.tsx @@ -21,10 +21,35 @@ import * as React from 'react'; import { shallow } from 'enzyme'; import WorkspaceRuleViewer, { Props } from '../WorkspaceRuleViewer'; +jest.useFakeTimers(); + it('should render', () => { expect(shallowRender()).toMatchSnapshot(); }); +it('should correctly mark the content as busy loading (aria)', () => { + const rule = { key: 'foo', name: 'Foo', organization: 'org' }; + const wrapper = shallowRender({ rule }); + const instance = wrapper.instance(); + const container = () => wrapper.find('.workspace-viewer-container'); + + expect(container().prop('aria-busy')).toBe(true); + + instance.handleLoaded(rule); + jest.runAllTimers(); + wrapper.update(); + expect(container().prop('aria-busy')).toBe(false); + + const newRule = { key: 'bar', name: 'Bar', organization: 'org' }; + wrapper.setProps({ rule: newRule }).update(); + expect(container().prop('aria-busy')).toBe(true); + + instance.handleLoaded(newRule); + jest.runAllTimers(); + wrapper.update(); + expect(container().prop('aria-busy')).toBe(false); +}); + it('should close', () => { const onClose = jest.fn(); const wrapper = shallowRender({ onClose }); @@ -41,8 +66,8 @@ it('should call back after load', () => { }); function shallowRender(props?: Partial<Props>) { - const rule = { key: 'foo', organization: 'org' }; - return shallow( + const rule = { key: 'foo', name: 'Foo', organization: 'org' }; + return shallow<WorkspaceRuleViewer>( <WorkspaceRuleViewer height={300} onClose={jest.fn()} diff --git a/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceRuleViewer-test.tsx.snap b/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceRuleViewer-test.tsx.snap index 9af15132081..f2515a8cfca 100644 --- a/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceRuleViewer-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceRuleViewer-test.tsx.snap @@ -15,12 +15,15 @@ exports[`should render 1`] = ` rule={ Object { "key": "foo", + "name": "Foo", "organization": "org", } } /> </WorkspaceHeader> <div + aria-busy={true} + aria-live="polite" className="workspace-viewer-container" style={ Object { |