diff --git a/change/@fluentui-eslint-plugin-2020-09-24-17-16-06-mituron-acc-behavior-tests-docs.json b/change/@fluentui-eslint-plugin-2020-09-24-17-16-06-mituron-acc-behavior-tests-docs.json new file mode 100644 index 0000000000000..7312a18d0bf32 --- /dev/null +++ b/change/@fluentui-eslint-plugin-2020-09-24-17-16-06-mituron-acc-behavior-tests-docs.json @@ -0,0 +1,8 @@ +{ + "type": "none", + "comment": "removing overrides from eslintrc.json file", + "packageName": "@fluentui/eslint-plugin", + "email": "email not defined", + "dependentChangeType": "none", + "date": "2020-09-24T15:16:06.898Z" +} diff --git a/packages/a11y-rules/.eslintrc.json b/packages/a11y-rules/.eslintrc.json deleted file mode 100644 index 24ece4e08168b..0000000000000 --- a/packages/a11y-rules/.eslintrc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": ["plugin:@fluentui/eslint-plugin/node"], - "root": true -} diff --git a/packages/a11y-rules/.npmignore b/packages/a11y-rules/.npmignore deleted file mode 100644 index 8f524f038059e..0000000000000 --- a/packages/a11y-rules/.npmignore +++ /dev/null @@ -1,34 +0,0 @@ -*.api.json -*.config.js -*.log -*.nuspec -*.test.* -*.yml -.editorconfig -.eslintrc* -.eslintcache -.gitattributes -.gitignore -.vscode -coverage -dist-storybook -dist/*.stats.html -dist/*.stats.json -dist/demo*.* -fabric-test* -gulpfile.js -images -index.html -jsconfig.json -node_modules -results -src/**/* -!src/**/examples/*.tsx -!src/**/docs/**/*.md -!src/**/*.types.ts -temp -tsconfig.json -tsd.json -tslint.json -typings -visualtests diff --git a/packages/a11y-rules/.npmrc b/packages/a11y-rules/.npmrc deleted file mode 100644 index 214c29d139591..0000000000000 --- a/packages/a11y-rules/.npmrc +++ /dev/null @@ -1 +0,0 @@ -registry=https://registry.npmjs.org/ diff --git a/packages/a11y-rules/LICENSE b/packages/a11y-rules/LICENSE deleted file mode 100644 index d654a1ed7b949..0000000000000 --- a/packages/a11y-rules/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -@fluentui/a11y-rules - -Copyright (c) Microsoft Corporation - -All rights reserved. - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Note: Usage of the fonts and icons referenced in Fluent UI React is subject to the terms listed at https://aka.ms/fluentui-assets-license diff --git a/packages/a11y-rules/README.md b/packages/a11y-rules/README.md deleted file mode 100644 index 3d4662e485b62..0000000000000 --- a/packages/a11y-rules/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# @fluentui/a11y-rules - -Rules for: - -- testing a11y conformance of components and hooks, together with typings for creating custom definitions -- generating documentation used for behavior files on docsite diff --git a/packages/a11y-rules/just.config.ts b/packages/a11y-rules/just.config.ts deleted file mode 100644 index 4382fd55bf369..0000000000000 --- a/packages/a11y-rules/just.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -const { preset, just } = require('@uifabric/build'); -const { task } = just; - -preset(); - -task('build', 'build:node-lib').cached(); diff --git a/packages/a11y-rules/package.json b/packages/a11y-rules/package.json deleted file mode 100644 index cd66fdf86af25..0000000000000 --- a/packages/a11y-rules/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "@fluentui/a11y-rules", - "version": "0.1.0", - "description": "Fluent UI rules for a11y testing a generating doc for behaviors files.", - "private": true, - "main": "lib/index.js", - "typings": "lib/index.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/microsoft/fluentui" - }, - "license": "MIT", - "scripts": { - "build": "just-scripts build", - "clean": "just-scripts clean", - "code-style": "just-scripts code-style", - "just": "just-scripts", - "lint": "just-scripts lint" - }, - "devDependencies": { - "@fluentui/eslint-plugin": "^0.54.1", - "@uifabric/build": "^7.0.0" - }, - "dependencies": { - "tslib": "^1.10.0" - } -} diff --git a/packages/a11y-rules/src/types.ts b/packages/a11y-rules/src/types.ts deleted file mode 100644 index ebd8e5dab8fa3..0000000000000 --- a/packages/a11y-rules/src/types.ts +++ /dev/null @@ -1,24 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type PropValue = string | number | boolean | any; -export type Props = { [name: string]: PropValue }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type AccessibilityBehavior = (props: Props) => any; - -export interface Rule { - stringify: () => string; -} - -export interface Slot { - name: string; - props: Props[]; - expectAttribute: boolean; - expectedAttribute: string; - expectedValue: PropValue; - description: string; - hidden: boolean; - afterEventData: Event; - checkClick: boolean; - checkSpaceKeyPressed: boolean; - checkEnterKeyPressed: boolean; - checkOnClickWasExecuted: boolean; -} diff --git a/packages/a11y-rules/tsconfig.json b/packages/a11y-rules/tsconfig.json deleted file mode 100644 index f88cbaf329b5c..0000000000000 --- a/packages/a11y-rules/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": ".", - "outDir": "lib", - "target": "es6", - "module": "commonjs", - "jsx": "react", - "declaration": true, - "sourceMap": true, - "experimentalDecorators": true, - "importHelpers": true, - "noUnusedLocals": true, - "forceConsistentCasingInFileNames": true, - "strictNullChecks": true, - "noImplicitAny": true, - "moduleResolution": "node", - "skipLibCheck": true, - "preserveConstEnums": true, - "lib": ["es2017", "dom"], - "types": [] - }, - "include": ["src"] -} diff --git a/packages/a11y-testing/package.json b/packages/a11y-testing/package.json index 4a3da87021af6..b0cdd9437aa19 100644 --- a/packages/a11y-testing/package.json +++ b/packages/a11y-testing/package.json @@ -30,7 +30,6 @@ "react-dom": "16.8.6" }, "dependencies": { - "@fluentui/a11y-rules": "^0.1.0", "tslib": "^1.10.0" }, "peerDependencies": { diff --git a/packages/a11y-testing/src/definitions/Button/buttonBehaviorDefinition.ts b/packages/a11y-testing/src/definitions/Button/buttonBehaviorDefinition.ts new file mode 100644 index 0000000000000..9cfb3bb2ad474 --- /dev/null +++ b/packages/a11y-testing/src/definitions/Button/buttonBehaviorDefinition.ts @@ -0,0 +1,49 @@ +import { Rule } from './../../types'; +import { BehaviorRule } from './../../rules/rules'; + +export const buttonBehaviorDefinition: Rule[] = [ + BehaviorRule.root() + .forProps({ as: 'div' }) + .hasAttribute('role', 'button') + .description(`if element type is other than 'button'.`), + BehaviorRule.root() + .doesNotHaveAttribute('role') + .description(`if element is native button.`), + BehaviorRule.root() + .forProps({ as: 'div' }) + .hasAttribute('tabindex', '0') + .description(`if element type is other than 'button'.`), + BehaviorRule.root() + .doesNotHaveAttribute('tabindex') + .description(`if element is native 'button'.`), + BehaviorRule.root() + .forProps({ disabled: true }) + .hasAttribute('disabled') + .description(`based on 'disabled' prop when element is native 'button'.`), + BehaviorRule.root() + .forProps({ disabled: true, as: 'div' }) + .doesNotHaveAttribute('disabled') + .description(`if element is NOT native 'button'.`), + BehaviorRule.root() + .forProps({ disabled: true, loading: true }) + .doesNotHaveAttribute('disabled') + .description(`if element is loading.`), + BehaviorRule.root() + .forProps({ disabled: true }) + .hasAttribute('aria-disabled', 'true') + .description(`if property 'disabled' is 'true'.`), + BehaviorRule.root() + .forProps({ loading: true }) + .hasAttribute('aria-disabled', 'true') + .description(`if property 'aria-disabled' is 'true'.`), + BehaviorRule.root() + .forProps({ as: 'div' }) + .pressSpaceKey() + .verifyOnclickExecution() + .description(`when element is not native 'button' or 'link'.`), + BehaviorRule.root() + .forProps({ as: 'div' }) + .pressEnterKey() + .verifyOnclickExecution() + .description(`when element is not native 'button' or 'link'.`), +]; diff --git a/packages/a11y-testing/src/definitions/Button/buttonGroupBehaviorDefinition.ts b/packages/a11y-testing/src/definitions/Button/buttonGroupBehaviorDefinition.ts new file mode 100644 index 0000000000000..ba9b9c2b0c341 --- /dev/null +++ b/packages/a11y-testing/src/definitions/Button/buttonGroupBehaviorDefinition.ts @@ -0,0 +1,4 @@ +import { Rule } from './../../types'; +import { BehaviorRule } from './../../rules/rules'; + +export const buttonGroupBehaviorDefinition: Rule[] = [BehaviorRule.root().hasAttribute('role', 'group')]; diff --git a/packages/a11y-testing/src/definitions/Button/toggleButtonBehaviorDefinition.ts b/packages/a11y-testing/src/definitions/Button/toggleButtonBehaviorDefinition.ts new file mode 100644 index 0000000000000..092332ea00110 --- /dev/null +++ b/packages/a11y-testing/src/definitions/Button/toggleButtonBehaviorDefinition.ts @@ -0,0 +1,12 @@ +import { Rule } from './../../types'; +import { BehaviorRule } from './../../rules/rules'; + +export const toggleButtonBehaviorDefinition: Rule[] = [ + BehaviorRule.root() + .forProps({ active: 'true' }) + .hasAttribute('aria-pressed', 'true') + .description(`if element has active prop.`), + BehaviorRule.root() + .hasAttribute('aria-pressed', 'false') + .description(`if element has no 'active' prop.`), +]; diff --git a/packages/a11y-testing/src/definitions/index.ts b/packages/a11y-testing/src/definitions/index.ts new file mode 100644 index 0000000000000..59b3b7603ec90 --- /dev/null +++ b/packages/a11y-testing/src/definitions/index.ts @@ -0,0 +1,3 @@ +export * from './Button/buttonBehaviorDefinition'; +export * from './Button/buttonGroupBehaviorDefinition'; +export * from './Button/toggleButtonBehaviorDefinition'; diff --git a/packages/a11y-testing/src/index.ts b/packages/a11y-testing/src/index.ts index bba7f0c1dbcf3..8397080f2fa3e 100644 --- a/packages/a11y-testing/src/index.ts +++ b/packages/a11y-testing/src/index.ts @@ -1,3 +1,5 @@ export * from './types'; export * from './validators'; export * from './facades'; +export * from './rules'; +export * from './definitions'; diff --git a/packages/a11y-rules/src/index.ts b/packages/a11y-testing/src/rules/index.ts similarity index 50% rename from packages/a11y-rules/src/index.ts rename to packages/a11y-testing/src/rules/index.ts index 2cdf310aa7220..6a37aaa5d4bd9 100644 --- a/packages/a11y-rules/src/index.ts +++ b/packages/a11y-testing/src/rules/index.ts @@ -1,2 +1 @@ export * from './rules'; -export * from './types'; diff --git a/packages/a11y-rules/src/rules.tsx b/packages/a11y-testing/src/rules/rules.tsx similarity index 98% rename from packages/a11y-rules/src/rules.tsx rename to packages/a11y-testing/src/rules/rules.tsx index d9bf1dd78ed8a..d7ed913436fe0 100644 --- a/packages/a11y-rules/src/rules.tsx +++ b/packages/a11y-testing/src/rules/rules.tsx @@ -1,4 +1,4 @@ -import { Props, PropValue, Rule, Slot } from './types'; +import { Props, PropValue, Rule, Slot } from '../types'; export class SlotRule implements Rule { private data: Slot; diff --git a/packages/a11y-testing/src/types.ts b/packages/a11y-testing/src/types.ts index e263e13c27ed6..d0e5f1321d93c 100644 --- a/packages/a11y-testing/src/types.ts +++ b/packages/a11y-testing/src/types.ts @@ -15,3 +15,22 @@ export interface TestFacade { pressEnterKey(slotName: string): void; verifyOnclickExecution(slotName: string): boolean; } + +export interface Rule { + stringify: () => string; +} + +export interface Slot { + name: string; + props: Props[]; + expectAttribute: boolean; + expectedAttribute: string; + expectedValue: PropValue; + description: string; + hidden: boolean; + afterEventData: Event; + checkClick: boolean; + checkSpaceKeyPressed: boolean; + checkEnterKeyPressed: boolean; + checkOnClickWasExecuted: boolean; +} diff --git a/packages/a11y-testing/src/validators/validate.ts b/packages/a11y-testing/src/validators/validate.ts index 81a6ad66af274..53be7bc9c079d 100644 --- a/packages/a11y-testing/src/validators/validate.ts +++ b/packages/a11y-testing/src/validators/validate.ts @@ -1,6 +1,6 @@ import { Props, TestFacade } from '../types'; - -import { SlotRule, Rule } from '@fluentui/a11y-rules'; +import { Rule } from './../types'; +import { SlotRule } from './../rules/rules'; export const validateSlot = (rule: SlotRule, baseTestFacade: TestFacade): void => { const slot = rule.getData(); diff --git a/packages/a11y-testing/tsconfig.json b/packages/a11y-testing/tsconfig.json index 53457d177760f..96ccddcc8fa01 100644 --- a/packages/a11y-testing/tsconfig.json +++ b/packages/a11y-testing/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "composite": true, "baseUrl": ".", "outDir": "lib", "target": "es6", diff --git a/packages/eslint-plugin/src/configs/react-northstar.js b/packages/eslint-plugin/src/configs/react-northstar.js index 9621d663cd30e..ce0d421a0535c 100644 --- a/packages/eslint-plugin/src/configs/react-northstar.js +++ b/packages/eslint-plugin/src/configs/react-northstar.js @@ -23,6 +23,10 @@ module.exports = { 'react-hooks/rules-of-hooks': 'error', 'import/no-default-export': 'error', + 'import/no-extraneous-dependencies': [ + 'error', + { devDependencies: ['**/*-test.ts*', '**/*.test.ts*', '*.config.js', 'gulpfile.ts', 'just.config.ts'] }, + ], // False positive on arg types: // https://github.com/typescript-eslint/typescript-eslint/issues/46 @@ -48,10 +52,6 @@ module.exports = { 'import/export': 'off', 'import/first': 'off', 'import/no-dynamic-require': 'off', - 'import/no-extraneous-dependencies': [ - 'error', - { devDependencies: ['**/*-test.ts*', '**/*.test.ts*', '*.config.js', 'gulpfile.ts', 'just.config.ts'] }, - ], 'import/no-named-default': 'off', 'import/no-useless-path-segments': 'off', 'import/order': 'off', diff --git a/packages/fluentui/accessibility/src/behaviors/Button/buttonBehavior.ts b/packages/fluentui/accessibility/src/behaviors/Button/buttonBehavior.ts index a0bb2a6d25e55..c5f1b2fb727c6 100644 --- a/packages/fluentui/accessibility/src/behaviors/Button/buttonBehavior.ts +++ b/packages/fluentui/accessibility/src/behaviors/Button/buttonBehavior.ts @@ -1,14 +1,6 @@ import { keyboardKey, SpacebarKey } from '@fluentui/keyboard-key'; import { Accessibility, AccessibilityDefinition } from '../../types'; -/** - * @specification - * Adds role='button' if element type is other than 'button'. This allows screen readers to handle the component as a button. - * Adds attribute 'tabIndex=0' if element type is other than 'button'. - * Adds attribute 'aria-disabled=true' based on the property 'disabled'. This can be overriden by providing 'aria-disabled' property directly to the component. - * Adds attribute 'aria-disabled=true' based on the property 'loading'. - * Triggers 'performClick' action with 'Enter' or 'Spacebar' on 'root'. - */ export const buttonBehavior: Accessibility = props => { const definition: AccessibilityDefinition = { attributes: { diff --git a/packages/fluentui/accessibility/src/behaviors/Button/buttonGroupBehavior.ts b/packages/fluentui/accessibility/src/behaviors/Button/buttonGroupBehavior.ts index 37af2d5414c3b..a175f889e72a8 100644 --- a/packages/fluentui/accessibility/src/behaviors/Button/buttonGroupBehavior.ts +++ b/packages/fluentui/accessibility/src/behaviors/Button/buttonGroupBehavior.ts @@ -1,9 +1,5 @@ import { Accessibility } from '../../types'; -/** - * @specification - * Adds role 'group' to 'root' slot. - */ export const buttonGroupBehavior: Accessibility = props => ({ attributes: { root: { diff --git a/packages/fluentui/accessibility/src/behaviors/Button/toggleButtonBehavior.ts b/packages/fluentui/accessibility/src/behaviors/Button/toggleButtonBehavior.ts index 721147b629fbe..695833003a986 100644 --- a/packages/fluentui/accessibility/src/behaviors/Button/toggleButtonBehavior.ts +++ b/packages/fluentui/accessibility/src/behaviors/Button/toggleButtonBehavior.ts @@ -1,14 +1,6 @@ import { Accessibility } from '../../types'; import { buttonBehavior, ButtonBehaviorProps } from './buttonBehavior'; -/** - * @specification - * Adds role='button' if element type is other than 'button'. This allows screen readers to handle the component as a button. - * Adds attribute 'tabIndex=0' if element type is other than 'button'. - * Adds attribute 'aria-pressed=true' based on the property 'active'. - * Adds attribute 'aria-disabled=true' based on the property 'disabled'. This can be overriden by providing 'aria-disabled' property directly to the component. - * Triggers 'performClick' action with 'Enter' or 'Spacebar' on 'root'. - */ export const toggleButtonBehavior: Accessibility = props => { const behaviorData = buttonBehavior(props); behaviorData.attributes.root = { diff --git a/packages/fluentui/accessibility/test/behaviors/testHelper.tsx b/packages/fluentui/accessibility/test/behaviors/testHelper.tsx index 9770574d5f152..84d63658b1f92 100644 --- a/packages/fluentui/accessibility/test/behaviors/testHelper.tsx +++ b/packages/fluentui/accessibility/test/behaviors/testHelper.tsx @@ -18,6 +18,9 @@ export interface TestDefinition { } const skipSpecChecksForFiles = [ + 'buttonBehavior.ts', // tests are written new way in buttonBehaviorDefinition.ts + 'buttonGroupBehavior.ts', // tests are written new way in buttonGroupBehaviorDefinition.ts + 'toggleButtonBehavior.ts', // tests are written new way in toggleButtonBehaviorDefinition.ts 'listBehavior.ts', // tests are written in listBehavior-test.tsx 'listItemBehavior.ts', // tests are written in listItemBehavior-test.tsx 'alertBehavior.ts', // tests are written in alertBehavior-test.tsx diff --git a/packages/fluentui/docs/package.json b/packages/fluentui/docs/package.json index 34da0febed530..8a3b7ac628072 100644 --- a/packages/fluentui/docs/package.json +++ b/packages/fluentui/docs/package.json @@ -47,6 +47,7 @@ "react-vis": "^1.11.6" }, "devDependencies": { + "@fluentui/a11y-testing": "^0.1.0", "@fluentui/eslint-plugin": "^0.54.1", "@types/classnames": "^2.2.9", "@types/color": "^3.0.0", diff --git a/packages/fluentui/docs/tsconfig.json b/packages/fluentui/docs/tsconfig.json index 84c912258735c..accf62a608508 100644 --- a/packages/fluentui/docs/tsconfig.json +++ b/packages/fluentui/docs/tsconfig.json @@ -4,6 +4,7 @@ "module": "esnext", "paths": { "@fluentui/*": ["packages/fluentui/*/src/index"], + "@fluentui/a11y-testing": ["packages/a11y-testing/src/index"], "@fluentui/dom-utilities": ["packages/dom-utilities/src"], "@fluentui/keyboard-key": ["packages/keyboard-key/src/index"], "@fluentui/react-compose": ["packages/react-compose/src/index"], diff --git a/packages/fluentui/react-northstar/package.json b/packages/fluentui/react-northstar/package.json index 9ff02d6b970fc..3b0d827209180 100644 --- a/packages/fluentui/react-northstar/package.json +++ b/packages/fluentui/react-northstar/package.json @@ -32,6 +32,7 @@ "react-transition-group": "^4.3.0" }, "devDependencies": { + "@fluentui/a11y-testing": "^0.1.0", "@fluentui/eslint-plugin": "^0.54.1", "@fluentui/react-conformance": "^0.1.4", "@testing-library/jest-dom": "^5.1.1", diff --git a/packages/fluentui/react-northstar/src/components/Button/Button.tsx b/packages/fluentui/react-northstar/src/components/Button/Button.tsx index b0eedb50c464e..87d69463247d7 100644 --- a/packages/fluentui/react-northstar/src/components/Button/Button.tsx +++ b/packages/fluentui/react-northstar/src/components/Button/Button.tsx @@ -232,7 +232,6 @@ export const Button = compose<'button', ButtonProps, ButtonStylesProps, {}, {}>( {...rtlTextContainer.getAttributes({ forElements: [children] })} {...getA11yProps('root', { onClick: handleClick, - disabled, className: classes.root, onFocus: handleFocus, ref, diff --git a/packages/fluentui/react-northstar/test/specs/components/Button/Button-test.tsx b/packages/fluentui/react-northstar/test/specs/components/Button/Button-test.tsx index 38219cfc2d0ef..622824f590b50 100644 --- a/packages/fluentui/react-northstar/test/specs/components/Button/Button-test.tsx +++ b/packages/fluentui/react-northstar/test/specs/components/Button/Button-test.tsx @@ -10,6 +10,12 @@ import { mountWithProvider, mountWithProviderAndGetComponent } from 'test/utils' import { toggleButtonBehavior } from '@fluentui/accessibility'; import { Button } from 'src/components/Button/Button'; +import { + validateBehavior, + ComponentTestFacade, + buttonBehaviorDefinition, + toggleButtonBehaviorDefinition, +} from '@fluentui/a11y-testing'; describe('Button', () => { isConformant(Button, { @@ -163,4 +169,16 @@ describe('Button', () => { ); }); }); + + describe('ButtonBehavior', () => { + const testFacade = new ComponentTestFacade(Button, {}); + const errors = validateBehavior(buttonBehaviorDefinition, testFacade); + expect(errors).toEqual([]); + }); + + describe('ButtonToggleBehavior', () => { + const testFacade = new ComponentTestFacade(Button, { accessibility: toggleButtonBehavior }); + const errors = validateBehavior(toggleButtonBehaviorDefinition, testFacade); + expect(errors).toEqual([]); + }); }); diff --git a/packages/fluentui/react-northstar/test/specs/components/Button/ButtonGroup-test.tsx b/packages/fluentui/react-northstar/test/specs/components/Button/ButtonGroup-test.tsx index 196e708f2d67f..b78c7c2e990ed 100644 --- a/packages/fluentui/react-northstar/test/specs/components/Button/ButtonGroup-test.tsx +++ b/packages/fluentui/react-northstar/test/specs/components/Button/ButtonGroup-test.tsx @@ -3,9 +3,27 @@ import { ButtonGroup } from 'src/components/Button/ButtonGroup'; import { implementsCollectionShorthandProp } from '../../commonTests/implementsCollectionShorthandProp'; import { Button } from 'src/components/Button/Button'; +import { validateBehavior, ComponentTestFacade, buttonGroupBehaviorDefinition } from '@fluentui/a11y-testing'; + const buttonGroupImplementsCollectionShorthandProp = implementsCollectionShorthandProp(ButtonGroup); +const buttons = [ + { + content: 'first button', + key: 'firstButton', + }, + { + content: 'second button', + key: 'secondButton', + }, +]; describe('ButtonGroup', () => { isConformant(ButtonGroup, { testPath: __filename, constructorName: 'ButtonGroup' }); buttonGroupImplementsCollectionShorthandProp('buttons', Button); }); + +describe('ButtonGroupBehavior', () => { + const testFacade = new ComponentTestFacade(Button.Group, { buttons }); + const errors = validateBehavior(buttonGroupBehaviorDefinition, testFacade); + expect(errors).toEqual([]); +}); diff --git a/packages/fluentui/react-northstar/tsconfig.json b/packages/fluentui/react-northstar/tsconfig.json index ecb4d6153e196..a87f31a261cd9 100644 --- a/packages/fluentui/react-northstar/tsconfig.json +++ b/packages/fluentui/react-northstar/tsconfig.json @@ -6,7 +6,8 @@ "paths": { "docs/*": ["packages/fluentui/docs/*"], "src/*": ["packages/fluentui/react-northstar/src/*"], - "test/*": ["packages/fluentui/react-northstar/test/*"] + "test/*": ["packages/fluentui/react-northstar/test/*"], + "@fluentui/a11y-testing": ["packages/a11y-testing/src/index"] } }, "include": ["src", "test"], @@ -14,6 +15,9 @@ { "path": "../accessibility" }, + { + "path": "../../a11y-testing" + }, { "path": "../styles" }, diff --git a/scripts/gulp/plugins/gulp-component-menu-behaviors.ts b/scripts/gulp/plugins/gulp-component-menu-behaviors.ts index fc9cbb56c5731..630c15a7c7440 100644 --- a/scripts/gulp/plugins/gulp-component-menu-behaviors.ts +++ b/scripts/gulp/plugins/gulp-component-menu-behaviors.ts @@ -1,3 +1,4 @@ +import * as behaviorDefinitions from '@fluentui/a11y-testing'; import gutil from 'gulp-util'; import path from 'path'; import through2 from 'through2'; @@ -59,12 +60,31 @@ export default () => { variation.specification = getTextFromCommentToken(commentTokens, 'specification'); } - result.push({ - displayName: behaviorName, - type: componentType, - variations: variation, - }); - cb(); + // generate behavior description from 'behavior definition' file if no was found in behavior file + if (!variation.description && !variation.specification) { + const variationName = variation.name.replace('.ts', ''); + const definitionName = `${variationName}Definition`; + + const definition = behaviorDefinitions[definitionName]; + const descriptionFromDefinition = definition.map(definition => { + return definition.stringify(); + }); + + variation.description = descriptionFromDefinition.join('\r\n'); + result.push({ + displayName: behaviorName, + type: componentType, + variations: variation, + }); + cb(); + } else { + result.push({ + displayName: behaviorName, + type: componentType, + variations: variation, + }); + cb(); + } } catch (err) { const pluginError = new gutil.PluginError(pluginName, err); const relativePath = path.relative(process.cwd(), file.path);