diff --git a/packages/react-components/react-breadcrumb/cypress.config.ts b/packages/react-components/react-breadcrumb/cypress.config.ts new file mode 100644 index 00000000000000..ca52cf041bbf2c --- /dev/null +++ b/packages/react-components/react-breadcrumb/cypress.config.ts @@ -0,0 +1,3 @@ +import { baseConfig } from '@fluentui/scripts-cypress'; + +export default baseConfig; diff --git a/packages/react-components/react-breadcrumb/docs/Spec.md b/packages/react-components/react-breadcrumb/docs/Spec.md index e49373e5993d8a..e340a0ef4d3178 100644 --- a/packages/react-components/react-breadcrumb/docs/Spec.md +++ b/packages/react-components/react-breadcrumb/docs/Spec.md @@ -176,6 +176,7 @@ Dropdown contains collapsed items. | ------------ | -------------------------- | ------------- | -------------------------------- | | appearance | `transparent`, `subtle` | `transparent` | Sets appearance | | dividerType | `chevron`, `slash` | `chevron` | Sets type of divider | +| focusMode | `tab`, `arrow` | `tab` | Sets focus mode | | iconPosition | `before`, `after` | `before` | Sets icon position for all items | | size | `small`, `medium`, `large` | `medium` | Defines size of the Breadcrumb | diff --git a/packages/react-components/react-breadcrumb/etc/react-breadcrumb.api.md b/packages/react-components/react-breadcrumb/etc/react-breadcrumb.api.md index 486f705ec9af82..a6169e5317cced 100644 --- a/packages/react-components/react-breadcrumb/etc/react-breadcrumb.api.md +++ b/packages/react-components/react-breadcrumb/etc/react-breadcrumb.api.md @@ -105,7 +105,7 @@ export type BreadcrumbLinkState = ComponentState & Partial< // @public export type BreadcrumbProps = ComponentProps & { appearance?: 'transparent' | 'subtle'; - disableFocus?: boolean; + focusMode?: 'arrow' | 'tab'; dividerType?: 'chevron' | 'slash'; iconPosition?: 'before' | 'after'; size?: 'small' | 'medium' | 'large'; diff --git a/packages/react-components/react-breadcrumb/package.json b/packages/react-components/react-breadcrumb/package.json index 707fe49009ddd6..d6b2173d077069 100644 --- a/packages/react-components/react-breadcrumb/package.json +++ b/packages/react-components/react-breadcrumb/package.json @@ -16,6 +16,8 @@ "build": "just-scripts build", "clean": "just-scripts clean", "code-style": "just-scripts code-style", + "e2e": "cypress run --component", + "e2e:local": "cypress open --component", "just": "just-scripts", "lint": "just-scripts lint", "test": "jest --passWithNoTests", @@ -30,6 +32,7 @@ "@fluentui/react-conformance": "*", "@fluentui/react-conformance-griffel": "9.0.0-beta.22", "@fluentui/scripts-api-extractor": "*", + "@fluentui/scripts-cypress": "*", "@fluentui/scripts-tasks": "*" }, "dependencies": { diff --git a/packages/react-components/react-breadcrumb/src/components/Breadcrumb/Breadcrumb.cy.tsx b/packages/react-components/react-breadcrumb/src/components/Breadcrumb/Breadcrumb.cy.tsx new file mode 100644 index 00000000000000..fae1df3bb3bce1 --- /dev/null +++ b/packages/react-components/react-breadcrumb/src/components/Breadcrumb/Breadcrumb.cy.tsx @@ -0,0 +1,183 @@ +import * as React from 'react'; +import { mount } from '@cypress/react'; +import type {} from '@cypress/react'; +import { FluentProvider } from '@fluentui/react-provider'; +import { webLightTheme } from '@fluentui/react-theme'; +import { Breadcrumb, BreadcrumbItem, BreadcrumbButton, BreadcrumbLink } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbProps } from '@fluentui/react-breadcrumb'; + +const mountFluent = (element: JSX.Element) => { + mount({element}); +}; + +const BreadcrumbSampleWithButton = (props: BreadcrumbProps) => ( + <> +

+ Before +

+ + + + Item 1 + + + Item 2 + + + + Item 3 + + + + +

+ After +

+ +); + +const BreadcrumbSampleWithLink = (props: BreadcrumbProps) => ( + <> +

+ Before +

+ + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + +

+ After +

+ +); + +const NonInteractiveBreadcrumbSample = (props: BreadcrumbProps) => ( + <> +

+ Before +

+ + + Item 1 + Item 2 + + Item 3 + + + +

+ After +

+ +); + +describe('Breadcrumb', () => { + describe('focus behaviors for BreadcrumbButton', () => { + describe('focusMode="tab"(default)', () => { + it('should be focusable', () => { + mountFluent(); + + cy.get('#before').focus(); + + cy.get('#breadcrumb-button-1').should('not.be.focused'); + + cy.realPress('Tab'); + + cy.get('#breadcrumb-button-1').should('be.focused'); + cy.realPress('Tab'); + cy.get('#breadcrumb-button-2').should('be.focused'); + cy.realPress('Tab'); + cy.get('#breadcrumb-button-3').should('be.focused'); + }); + }); + + describe('focusMode="arrow"', () => { + it('should be focusable', () => { + mountFluent(); + + cy.get('#before').focus(); + + cy.get('#breadcrumb-button-1').should('not.be.focused'); + + cy.realPress('Tab'); + + cy.get('#breadcrumb-button-1').should('be.focused'); + cy.realPress('ArrowRight'); + cy.get('#breadcrumb-button-2').should('be.focused'); + cy.realPress('ArrowRight'); + cy.get('#breadcrumb-button-3').should('be.focused'); + cy.realPress('ArrowRight'); + cy.get('#breadcrumb-button-1').should('be.focused'); + }); + }); + }); + describe('focus behaviors for BreadcrumbLink', () => { + describe('focusMode="tab"(default)', () => { + it('should be focusable', () => { + mountFluent(); + + cy.get('#before').focus(); + + cy.get('#breadcrumb-link-1').should('not.be.focused'); + + cy.realPress('Tab'); + + cy.get('#breadcrumb-link-1').should('be.focused'); + cy.realPress('Tab'); + cy.get('#breadcrumb-link-2').should('be.focused'); + cy.realPress('Tab'); + cy.get('#breadcrumb-link-3').should('be.focused'); + }); + }); + + describe('focusMode="arrow"', () => { + it('should be focusable', () => { + mountFluent(); + + cy.get('#before').focus(); + + cy.get('#breadcrumb-link-1').should('not.be.focused'); + + cy.realPress('Tab'); + + cy.get('#breadcrumb-link-1').should('be.focused'); + cy.realPress('ArrowRight'); + cy.get('#breadcrumb-link-2').should('be.focused'); + cy.realPress('ArrowRight'); + cy.get('#breadcrumb-link-3').should('be.focused'); + cy.realPress('ArrowRight'); + cy.get('#breadcrumb-link-1').should('be.focused'); + }); + }); + }); + describe('focus behaviors for BreadcrumbItem', () => { + it('should not be focusable', () => { + mountFluent(); + + cy.get('#before').focus(); + + cy.get('#breadcrumb-item-1').should('not.be.focused'); + cy.get('#before').should('be.focused'); + + cy.realPress('Tab'); + + cy.get('#breadcrumb-item-1').should('not.be.focused'); + cy.get('#after').should('be.focused'); + }); + }); +}); diff --git a/packages/react-components/react-breadcrumb/src/components/Breadcrumb/Breadcrumb.test.tsx b/packages/react-components/react-breadcrumb/src/components/Breadcrumb/Breadcrumb.test.tsx index 9f0cc13830edb8..a12d4346ecb4aa 100644 --- a/packages/react-components/react-breadcrumb/src/components/Breadcrumb/Breadcrumb.test.tsx +++ b/packages/react-components/react-breadcrumb/src/components/Breadcrumb/Breadcrumb.test.tsx @@ -28,7 +28,6 @@ describe('Breadcrumb', () => {