From d73733d99e2250d840f35e16044e8de69bdc9b6c Mon Sep 17 00:00:00 2001 From: Donald Pipowitch Date: Tue, 19 Nov 2019 10:10:10 +0100 Subject: [PATCH 1/3] addon-a11y: allow manual run --- addons/a11y/README.md | 2 + addons/a11y/src/components/A11YPanel.test.js | 45 ++-- addons/a11y/src/components/A11YPanel.tsx | 194 ++++++++++-------- .../__snapshots__/A11YPanel.test.js.snap | 145 +++++++++++++ addons/a11y/src/constants.ts | 3 +- addons/a11y/src/index.ts | 8 +- lib/components/src/icon/icon.tsx | 4 +- 7 files changed, 293 insertions(+), 108 deletions(-) diff --git a/addons/a11y/README.md b/addons/a11y/README.md index aa141c5c94c1..f4d086fb9f1d 100755 --- a/addons/a11y/README.md +++ b/addons/a11y/README.md @@ -69,6 +69,8 @@ export default { config: {}, // axe-core optionsParameter (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#options-parameter) options: {}, + // optional flag to prevent the automatic check + manual: true, }, }, }; diff --git a/addons/a11y/src/components/A11YPanel.test.js b/addons/a11y/src/components/A11YPanel.test.js index 2f84b31afd39..9947bcc52f90 100644 --- a/addons/a11y/src/components/A11YPanel.test.js +++ b/addons/a11y/src/components/A11YPanel.test.js @@ -2,8 +2,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { ThemeProvider, themes, convert } from '@storybook/theming'; -import { STORY_RENDERED } from '@storybook/core-events'; -import { ScrollArea } from '@storybook/components'; import { A11YPanel } from './A11YPanel'; import { EVENTS } from '../constants'; @@ -63,7 +61,7 @@ function ThemedA11YPanel(props) { } describe('A11YPanel', () => { - it('should register STORY_RENDERED, RESULT and ERROR updater on mount', () => { + it('should register event listener on mount', () => { // given const api = createApi(); expect(api.on).not.toHaveBeenCalled(); @@ -73,12 +71,12 @@ describe('A11YPanel', () => { // then expect(api.on.mock.calls.length).toBe(3); - expect(api.on.mock.calls[0][0]).toBe(STORY_RENDERED); - expect(api.on.mock.calls[1][0]).toBe(EVENTS.RESULT); - expect(api.on.mock.calls[2][0]).toBe(EVENTS.ERROR); + expect(api.on.mock.calls[0][0]).toBe(EVENTS.RESULT); + expect(api.on.mock.calls[1][0]).toBe(EVENTS.ERROR); + expect(api.on.mock.calls[2][0]).toBe(EVENTS.MANUAL); }); - it('should request a run on tab activation', () => { + it('should show initial state on tab activation', () => { // given const api = createApi(); @@ -90,11 +88,10 @@ describe('A11YPanel', () => { wrapper.update(); // then - expect(api.emit).toHaveBeenCalledWith(EVENTS.REQUEST); - expect(wrapper.find(ScrollArea).length).toBe(0); + expect(wrapper.find(A11YPanel)).toMatchSnapshot(); }); - it('should deregister STORY_RENDERED, RESULT and ERROR updater on unmount', () => { + it('should deregister event listener on unmount', () => { // given const api = createApi(); const wrapper = mount(); @@ -105,9 +102,25 @@ describe('A11YPanel', () => { // then expect(api.off.mock.calls.length).toBe(3); - expect(api.off.mock.calls[0][0]).toBe(STORY_RENDERED); - expect(api.off.mock.calls[1][0]).toBe(EVENTS.RESULT); - expect(api.off.mock.calls[2][0]).toBe(EVENTS.ERROR); + expect(api.off.mock.calls[0][0]).toBe(EVENTS.RESULT); + expect(api.off.mock.calls[1][0]).toBe(EVENTS.ERROR); + expect(api.off.mock.calls[2][0]).toBe(EVENTS.MANUAL); + }); + + it('should show manual state depending on config', () => { + // given + const api = createApi(); + + const wrapper = mount(); + expect(api.emit).not.toHaveBeenCalled(); + + // when + wrapper.setProps({ active: true }); + api.emit(EVENTS.MANUAL, true); + wrapper.update(); + + // then + expect(wrapper.find(A11YPanel)).toMatchSnapshot(); }); it('should update run result', () => { @@ -141,7 +154,7 @@ describe('A11YPanel', () => { // given const api = createApi(); const wrapper = mount(); - const request = api.on.mock.calls.find(([event]) => event === STORY_RENDERED)[1]; + const request = api.on.mock.calls.find(([event]) => event === EVENTS.MANUAL)[1]; expect( wrapper @@ -170,7 +183,7 @@ describe('A11YPanel', () => { // given const api = createApi(); mount(); - const request = api.on.mock.calls.find(([event]) => event === STORY_RENDERED)[1]; + const request = api.on.mock.calls.find(([event]) => event === EVENTS.MANUAL)[1]; expect(api.emit).not.toHaveBeenCalled(); // when @@ -197,7 +210,7 @@ describe('A11YPanel', () => { // given const api = createApi(); const wrapper = mount(); - const request = api.on.mock.calls.find(([event]) => event === STORY_RENDERED)[1]; + const request = api.on.mock.calls.find(([event]) => event === EVENTS.MANUAL)[1]; // when request(); diff --git a/addons/a11y/src/components/A11YPanel.tsx b/addons/a11y/src/components/A11YPanel.tsx index 194acca7be6d..89d916a71f57 100644 --- a/addons/a11y/src/components/A11YPanel.tsx +++ b/addons/a11y/src/components/A11YPanel.tsx @@ -1,8 +1,8 @@ +/* eslint-disable react/destructuring-assignment,default-case,consistent-return,no-case-declarations */ import React, { Component, Fragment } from 'react'; import { styled } from '@storybook/theming'; -import { STORY_RENDERED } from '@storybook/core-events'; import { ActionBar, Icons, ScrollArea } from '@storybook/components'; import { AxeResults, Result } from 'axe-core'; @@ -20,60 +20,70 @@ export enum RuleType { INCOMPLETION, } -const Icon = styled(Icons)( - { - height: '12px', - width: '12px', - marginRight: '4px', - }, - ({ status, theme }: any) => - status === 'running' - ? { - animation: `${theme.animation.rotate360} 1s linear infinite;`, - } - : {} -); +const RotatingIcons = styled(Icons)(({ theme }) => ({ + height: '12px', + width: '12px', + marginRight: '4px', + animation: `${theme.animation.rotate360} 1s linear infinite;`, +})); -const Passes = styled.span<{}>(({ theme }) => ({ +const Passes = styled.span(({ theme }) => ({ color: theme.color.positive, })); -const Violations = styled.span<{}>(({ theme }) => ({ +const Violations = styled.span(({ theme }) => ({ color: theme.color.negative, })); -const Incomplete = styled.span<{}>(({ theme }) => ({ +const Incomplete = styled.span(({ theme }) => ({ color: theme.color.warning, })); -const centeredStyle = { +const Centered = styled.span({ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', -}; - -const Loader = styled(({ className }) => ( -
- Please wait while the accessibility scan is running - ... -
-))(centeredStyle); -Loader.displayName = 'Loader'; - -interface A11YPanelNormalState { - status: 'ready' | 'ran' | 'running'; +}); + +interface InitialState { + status: 'initial'; +} + +interface ManualState { + status: 'manual'; +} + +interface RunningState { + status: 'running'; +} + +interface RanState { + status: 'ran'; + passes: Result[]; + violations: Result[]; + incomplete: Result[]; +} + +interface ReadyState { + status: 'ready'; passes: Result[]; violations: Result[]; incomplete: Result[]; } -interface A11YPanelErrorState { +interface ErrorState { status: 'error'; error: unknown; } -type A11YPanelState = A11YPanelNormalState | A11YPanelErrorState; +type A11YPanelState = + | InitialState + | ManualState + | RunningState + | RanState + | ReadyState + | ErrorState; interface A11YPanelProps { active: boolean; @@ -82,18 +92,15 @@ interface A11YPanelProps { export class A11YPanel extends Component { state: A11YPanelState = { - status: 'ready', - passes: [], - violations: [], - incomplete: [], + status: 'initial', }; componentDidMount() { const { api } = this.props; - api.on(STORY_RENDERED, this.request); - api.on(EVENTS.RESULT, this.onUpdate); + api.on(EVENTS.RESULT, this.onResult); api.on(EVENTS.ERROR, this.onError); + api.on(EVENTS.MANUAL, this.onManual); } componentDidUpdate(prevProps: A11YPanelProps) { @@ -103,18 +110,18 @@ export class A11YPanel extends Component { if (!prevProps.active && active) { // removes all elements from the redux map in store from the previous panel store.dispatch(clearElements()); - this.request(); } } componentWillUnmount() { const { api } = this.props; - api.off(STORY_RENDERED, this.request); - api.off(EVENTS.RESULT, this.onUpdate); + + api.off(EVENTS.RESULT, this.onResult); api.off(EVENTS.ERROR, this.onError); + api.off(EVENTS.MANUAL, this.onManual); } - onUpdate = ({ passes, violations, incomplete }: AxeResults) => { + onResult = ({ passes, violations, incomplete }: AxeResults) => { this.setState( { status: 'ran', @@ -142,9 +149,18 @@ export class A11YPanel extends Component { }); }; + onManual = (manual: boolean) => { + if (manual) { + this.setState({ + status: 'manual', + }); + } else { + this.request(); + } + }; + request = () => { const { api, active } = this.props; - if (active) { this.setState( { @@ -163,43 +179,39 @@ export class A11YPanel extends Component { const { active } = this.props; if (!active) return null; - // eslint-disable-next-line react/destructuring-assignment - if (this.state.status === 'error') { - const { error } = this.state; - return ( -
- The accessibility scan encountered an error. -
- {error} -
- ); - } - - const { passes, violations, incomplete, status } = this.state; - - let actionTitle; - if (status === 'ready') { - actionTitle = 'Rerun tests'; - } else if (status === 'running') { - actionTitle = ( - - Running test - - ); - } else if (status === 'ran') { - actionTitle = ( - - Tests completed - - ); - } - - return ( - - - {status === 'running' ? ( - + switch (this.state.status) { + case 'initial': + return Initializing...; + case 'manual': + return ( + + Manually run the accessibility scan. + + + ); + case 'running': + return ( + + Please wait while the accessibility scan is running + ... + + ); + case 'ready': + case 'ran': + const { passes, violations, incomplete, status } = this.state; + const actionTitle = + status === 'ready' ? ( + 'Rerun tests' ) : ( + + Tests completed + + ); + return ( + { ]} /> - )} - - - - ); + + + ); + case 'error': + const { error } = this.state; + return ( + + The accessibility scan encountered an error. +
+ {error} +
+ ); + } } } diff --git a/addons/a11y/src/components/__snapshots__/A11YPanel.test.js.snap b/addons/a11y/src/components/__snapshots__/A11YPanel.test.js.snap index f4267e78d817..5cbb4e634371 100644 --- a/addons/a11y/src/components/__snapshots__/A11YPanel.test.js.snap +++ b/addons/a11y/src/components/__snapshots__/A11YPanel.test.js.snap @@ -1124,3 +1124,148 @@ exports[`A11YPanel should render report 1`] = ` `; + +exports[`A11YPanel should show initial state on tab activation 1`] = ` +.emotion-0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + height: 100%; +} + + + + + Initializing... + + + +`; + +exports[`A11YPanel should show manual state depending on config 1`] = ` +.emotion-0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + height: 100%; +} + + + + + Initializing... + + + +`; diff --git a/addons/a11y/src/constants.ts b/addons/a11y/src/constants.ts index efabac7a268b..79ef7446a159 100755 --- a/addons/a11y/src/constants.ts +++ b/addons/a11y/src/constants.ts @@ -7,5 +7,6 @@ export const CLEAR_ELEMENTS = 'CLEAR_ELEMENTS'; const RESULT = `${ADDON_ID}/result`; const REQUEST = `${ADDON_ID}/request`; const ERROR = `${ADDON_ID}/error`; +const MANUAL = `${ADDON_ID}/manual`; -export const EVENTS = { RESULT, REQUEST, ERROR }; +export const EVENTS = { RESULT, REQUEST, ERROR, MANUAL }; diff --git a/addons/a11y/src/index.ts b/addons/a11y/src/index.ts index a7f53ec29a73..ef6b7d546d61 100644 --- a/addons/a11y/src/index.ts +++ b/addons/a11y/src/index.ts @@ -11,8 +11,10 @@ interface Setup { element?: ElementContext; config: Spec; options: RunOptions; + manual: boolean; } -let setup: Setup = { element: null, config: {}, options: {} }; + +let setup: Setup = { element: null, config: {}, options: {}, manual: false }; const getElement = () => { const storyRoot = document.getElementById('story-root'); @@ -58,12 +60,14 @@ export const withA11y = makeDecorator({ if (storedDefaultSetup === null) { storedDefaultSetup = { ...setup }; } - Object.assign(setup, parameters as Setup); + Object.assign(setup, parameters as Partial); } else if (storedDefaultSetup !== null) { Object.assign(setup, storedDefaultSetup); storedDefaultSetup = null; } + addons.getChannel().on(EVENTS.REQUEST, () => run(setup.element, setup.config, setup.options)); + addons.getChannel().emit(EVENTS.MANUAL, setup.manual); return getStory(context); }, diff --git a/lib/components/src/icon/icon.tsx b/lib/components/src/icon/icon.tsx index fc8f1b1a0202..e421548de521 100644 --- a/lib/components/src/icon/icon.tsx +++ b/lib/components/src/icon/icon.tsx @@ -2,13 +2,13 @@ import React, { FunctionComponent } from 'react'; import { styled } from '@storybook/theming'; import icons, { IconKey } from './icons'; -import Svg from './svg'; +import Svg, { SvgProps } from './svg'; const Path = styled.path({ fill: 'currentColor', }); -export interface IconsProps { +export interface IconsProps extends SvgProps { icon: IconKey; } From aa5a65435f7124298f003412c6b1d84c6675c4df Mon Sep 17 00:00:00 2001 From: Donald Pipowitch Date: Mon, 25 Nov 2019 21:16:20 +0100 Subject: [PATCH 2/3] updated tests --- addons/a11y/src/components/A11YPanel.test.js | 139 +- .../__snapshots__/A11YPanel.test.js.snap | 1271 ----------------- 2 files changed, 36 insertions(+), 1374 deletions(-) delete mode 100644 addons/a11y/src/components/__snapshots__/A11YPanel.test.js.snap diff --git a/addons/a11y/src/components/A11YPanel.test.js b/addons/a11y/src/components/A11YPanel.test.js index 9947bcc52f90..9bc88673ab01 100644 --- a/addons/a11y/src/components/A11YPanel.test.js +++ b/addons/a11y/src/components/A11YPanel.test.js @@ -1,5 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; +import { EventEmitter } from 'events'; import { ThemeProvider, themes, convert } from '@storybook/theming'; @@ -7,11 +8,11 @@ import { A11YPanel } from './A11YPanel'; import { EVENTS } from '../constants'; function createApi() { - return { - emit: jest.fn(), - on: jest.fn(), - off: jest.fn(), - }; + const emitter = new EventEmitter(); + jest.spyOn(emitter, 'emit'); + jest.spyOn(emitter, 'on'); + jest.spyOn(emitter, 'off'); + return emitter; } const axeResult = { @@ -76,28 +77,13 @@ describe('A11YPanel', () => { expect(api.on.mock.calls[2][0]).toBe(EVENTS.MANUAL); }); - it('should show initial state on tab activation', () => { - // given - const api = createApi(); - - const wrapper = mount(); - expect(api.emit).not.toHaveBeenCalled(); - - // when - wrapper.setProps({ active: true }); - wrapper.update(); - - // then - expect(wrapper.find(A11YPanel)).toMatchSnapshot(); - }); - it('should deregister event listener on unmount', () => { // given const api = createApi(); - const wrapper = mount(); expect(api.off).not.toHaveBeenCalled(); // when + const wrapper = mount(); wrapper.unmount(); // then @@ -107,123 +93,70 @@ describe('A11YPanel', () => { expect(api.off.mock.calls[2][0]).toBe(EVENTS.MANUAL); }); - it('should show manual state depending on config', () => { + it('should handle "initial" status', () => { // given const api = createApi(); - const wrapper = mount(); - expect(api.emit).not.toHaveBeenCalled(); - // when - wrapper.setProps({ active: true }); - api.emit(EVENTS.MANUAL, true); - wrapper.update(); - - // then - expect(wrapper.find(A11YPanel)).toMatchSnapshot(); - }); - - it('should update run result', () => { - // given - const api = createApi(); const wrapper = mount(); - const onUpdate = api.on.mock.calls.find(([event]) => event === EVENTS.RESULT)[1]; - - expect( - wrapper - .find('button') - .last() - .text() - .trim() - ).toBe('Rerun tests'); - - // when - onUpdate(axeResult); // then - expect( - wrapper - .find('button') - .last() - .text() - .trim() - ).toBe('Tests completed'); - }); - - it('should request run', () => { - // given - const api = createApi(); - const wrapper = mount(); - const request = api.on.mock.calls.find(([event]) => event === EVENTS.MANUAL)[1]; - - expect( - wrapper - .find('button') - .last() - .text() - .trim() - ).toBe('Rerun tests'); expect(api.emit).not.toHaveBeenCalled(); - - // when - request(); - - // then - expect( - wrapper - .find('button') - .last() - .text() - .trim() - ).toBe('Running test'); - expect(api.emit).toHaveBeenCalledWith(EVENTS.REQUEST); + expect(wrapper.text()).toMatch(/Initializing/); }); - it('should NOT request run on inactive tab', () => { + it('should handle "manual" status', () => { // given const api = createApi(); - mount(); - const request = api.on.mock.calls.find(([event]) => event === EVENTS.MANUAL)[1]; - expect(api.emit).not.toHaveBeenCalled(); + const wrapper = mount(); // when - request(); + api.emit(EVENTS.MANUAL, true); + wrapper.update(); // then - expect(api.emit).not.toHaveBeenCalled(); + expect(wrapper.text()).toMatch(/Manually run the accessibility scan/); + expect(api.emit).not.toHaveBeenCalledWith(EVENTS.REQUEST); }); - it('should render report', () => { + it('should handle "running" status', () => { // given const api = createApi(); const wrapper = mount(); - const onUpdate = api.on.mock.calls.find(([event]) => event === EVENTS.RESULT)[1]; // when - onUpdate(axeResult); + api.emit(EVENTS.MANUAL, false); + wrapper.update(); // then - expect(wrapper.find(A11YPanel)).toMatchSnapshot(); + expect(wrapper.text()).toMatch(/Please wait while the accessibility scan is running/); + expect(api.emit).toHaveBeenCalledWith(EVENTS.REQUEST); }); - it("should render loader when it's running", () => { + it('should handle "ran" status', () => { // given const api = createApi(); const wrapper = mount(); - const request = api.on.mock.calls.find(([event]) => event === EVENTS.MANUAL)[1]; // when - request(); + api.emit(EVENTS.RESULT, axeResult); wrapper.update(); // then - expect(wrapper.find('ScrollArea').length).toBe(0); - expect(wrapper.find('Loader').length).toBe(1); - expect(wrapper.find('ActionBar').length).toBe(1); - expect(wrapper.find('Loader')).toMatchSnapshot(); + expect( + wrapper + .find('button') + .last() + .text() + .trim() + ).toBe('Tests completed'); + expect(wrapper.find('Tabs').prop('tabs').length).toBe(3); + expect(wrapper.find('Tabs').prop('tabs')[0].label.props.children).toEqual([1, ' Violations']); + expect(wrapper.find('Tabs').prop('tabs')[1].label.props.children).toEqual([1, ' Passes']); + expect(wrapper.find('Tabs').prop('tabs')[2].label.props.children).toEqual([1, ' Incomplete']); }); - it('should NOT anything when tab is not active', () => { + it('should handle inactive state', () => { // given const api = createApi(); @@ -231,7 +164,7 @@ describe('A11YPanel', () => { const wrapper = mount(); // then - expect(wrapper.find('ScrollArea').length).toBe(0); - expect(wrapper.find('ActionBar').length).toBe(0); + expect(wrapper.text()).toBe(''); + expect(api.emit).not.toHaveBeenCalled(); }); }); diff --git a/addons/a11y/src/components/__snapshots__/A11YPanel.test.js.snap b/addons/a11y/src/components/__snapshots__/A11YPanel.test.js.snap deleted file mode 100644 index 5cbb4e634371..000000000000 --- a/addons/a11y/src/components/__snapshots__/A11YPanel.test.js.snap +++ /dev/null @@ -1,1271 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`A11YPanel should render loader when it's running 1`] = ` -@keyframes animation-0 { - from { - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); - } - - to { - -webkit-transform: rotate(360deg); - -ms-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - height: 100%; -} - -.emotion-2 { - height: 12px; - width: 12px; - margin-right: 4px; - -webkit-animation: animation-0 1s linear infinite; - animation: animation-0 1s linear infinite; -} - -.emotion-1 { - shape-rendering: inherit; - -webkit-transform: translate3d(0,0,0); - -ms-transform: translate3d(0,0,0); - transform: translate3d(0,0,0); - display: inline-block; - height: 12px; - width: 12px; - margin-right: 4px; - -webkit-animation: animation-0 1s linear infinite; - animation: animation-0 1s linear infinite; -} - -.emotion-0 { - fill: currentColor; -} - - - -
- - - - - - - - - - - - Please wait while the accessibility scan is running ... -
-
-
-`; - -exports[`A11YPanel should render report 1`] = ` -.emotion-0 { - overflow-y: auto; - height: 100%; - overflow-x: auto; - width: 100%; -} - -.emotion-4 { - position: absolute; - bottom: 0; - right: 0; - max-width: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - background: #FFFFFF; - z-index: 1; -} - -.emotion-3 { - border: 0 none; - padding: 4px 10px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - color: #333333; - background: #FFFFFF; - font-size: 12px; - line-height: 16px; - font-family: "Nunito Sans",-apple-system,".SFNSText-Regular","San Francisco",BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Helvetica,Arial,sans-serif; - font-weight: 700; - border-top: 1px solid rgba(0,0,0,.1); - border-left: 1px solid rgba(0,0,0,.1); - margin-left: -1px; - border-radius: 4px 0 0 0; -} - -.emotion-3:not(:last-child) { - border-right: 1px solid rgba(0,0,0,.1); -} - -.emotion-3 + * { - border-left: 1px solid rgba(0,0,0,.1); - border-radius: 0; -} - -.emotion-3:focus { - box-shadow: #1EA7FD 0 -3px 0 0 inset; - outline: 0 none; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - , - "ctr": 35, - "isSpeedy": false, - "key": "css", - "nonce": undefined, - "tags": Array [ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ], - }, - } - } - serialized={ - Object { - "map": undefined, - "name": "nh5djz", - "next": undefined, - "styles": "[data-simplebar]{position:relative;flex-direction:column;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:flex-start;}.simplebar-wrapper{overflow:hidden;width:inherit;height:inherit;max-width:inherit;max-height:inherit;}.simplebar-mask{direction:inherit;position:absolute;overflow:hidden;padding:0;margin:0;left:0;top:0;bottom:0;right:0;width:auto !important;height:auto !important;z-index:0;}.simplebar-offset{direction:inherit !important;resize:none !important;position:absolute;top:0;left:0;bottom:0;right:0;padding:0;margin:0;-webkit-overflow-scrolling:touch;}.simplebar-content-wrapper{direction:inherit;position:relative;display:block;visibility:visible;}.simplebar-placeholder{max-height:100%;max-width:100%;width:100%;pointer-events:none;}.simplebar-height-auto-observer-wrapper{height:100%;width:inherit;max-width:1px;position:relative;float:left;max-height:1px;overflow:hidden;z-index:-1;padding:0;margin:0;pointer-events:none;flex-grow:inherit;flex-shrink:0;flex-basis:0;}.simplebar-height-auto-observer{display:block;opacity:0;position:absolute;top:0;left:0;height:1000%;width:1000%;min-height:1px;min-width:1px;overflow:hidden;pointer-events:none;z-index:-1;}.simplebar-track{z-index:1;position:absolute;right:0;bottom:0;pointer-events:none;overflow:hidden;}[data-simplebar].simplebar-dragging .simplebar-track{pointer-events:all;}.simplebar-scrollbar{position:absolute;right:2px;width:7px;min-height:10px;}.simplebar-scrollbar:before{position:absolute;content:\\"\\";border-radius:7px;left:0;right:0;opacity:0;transition:opacity 0.2s linear;background:#333333;}.simplebar-track .simplebar-scrollbar.simplebar-visible:before{opacity:0.5;transition:opacity 0s linear;}.simplebar-track.simplebar-vertical{top:0;width:11px;}.simplebar-track.simplebar-vertical .simplebar-scrollbar:before{top:2px;bottom:2px;}.simplebar-track.simplebar-horizontal{left:0;height:11px;}.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before{height:100%;left:2px;right:2px;}.simplebar-track.simplebar-horizontal .simplebar-scrollbar{right:auto;left:0;top:2px;height:7px;min-height:0;min-width:10px;width:auto;}[data-simplebar-direction=\\"rtl\\"] .simplebar-track.simplebar-vertical{right:auto;left:0;}", - "toString": [Function], - } - } - /> - - - - -
-
-
-
-
-
-
-
-
- - 0 - Violations - , - "panel": , - "type": 0, - }, - Object { - "items": Array [], - "label": - 0 - Passes - , - "panel": , - "type": 1, - }, - Object { - "items": Array [], - "label": - 0 - Incomplete - , - "panel": , - "type": 2, - }, - ] - } - > - - - - - -
- - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - -
- - - -
-
-
- - -`; - -exports[`A11YPanel should show initial state on tab activation 1`] = ` -.emotion-0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - height: 100%; -} - - - - - Initializing... - - - -`; - -exports[`A11YPanel should show manual state depending on config 1`] = ` -.emotion-0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - height: 100%; -} - - - - - Initializing... - - - -`; From a03a2c49ff5ea87f716c8b43a5326044d2c54b34 Mon Sep 17 00:00:00 2001 From: Donald Pipowitch Date: Mon, 13 Jan 2020 08:36:24 +0100 Subject: [PATCH 3/3] fix initial render bug --- addons/a11y/src/components/A11YPanel.tsx | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/addons/a11y/src/components/A11YPanel.tsx b/addons/a11y/src/components/A11YPanel.tsx index f278877edc5f..8ae03635895a 100644 --- a/addons/a11y/src/components/A11YPanel.tsx +++ b/addons/a11y/src/components/A11YPanel.tsx @@ -160,19 +160,17 @@ export class A11YPanel extends Component { }; request = () => { - const { api, active } = this.props; - if (active) { - this.setState( - { - status: 'running', - }, - () => { - api.emit(EVENTS.REQUEST); - // removes all elements from the redux map in store from the previous panel - store.dispatch(clearElements()); - } - ); - } + const { api } = this.props; + this.setState( + { + status: 'running', + }, + () => { + api.emit(EVENTS.REQUEST); + // removes all elements from the redux map in store from the previous panel + store.dispatch(clearElements()); + } + ); }; render() {