diff --git a/src/elements/core/testing/private/fixture.ts b/src/elements/core/testing/private/fixture.ts index 5be174efb5..24fe8280ba 100644 --- a/src/elements/core/testing/private/fixture.ts +++ b/src/elements/core/testing/private/fixture.ts @@ -90,8 +90,8 @@ export async function visualRegressionFixture( focusOutlineDark?: boolean; padding?: string; minHeight?: string; - forcedColors?: boolean; maxWidth?: string; + forcedColors?: boolean; }, ): Promise { const base = tryFindBase(new Error().stack!); diff --git a/src/elements/menu/menu-button/__snapshots__/menu-button.snapshot.spec.snap.js b/src/elements/menu/menu-button/__snapshots__/menu-button.snapshot.spec.snap.js index a9aa7f8792..e04288744f 100644 --- a/src/elements/menu/menu-button/__snapshots__/menu-button.snapshot.spec.snap.js +++ b/src/elements/menu/menu-button/__snapshots__/menu-button.snapshot.spec.snap.js @@ -1,7 +1,7 @@ /* @web/test-runner snapshot v1 */ export const snapshots = {}; -snapshots["sbb-menu-button renders Light DOM"] = +snapshots["sbb-menu-button renders DOM"] = ` `; -/* end snapshot sbb-menu-button renders Light DOM */ +/* end snapshot sbb-menu-button renders DOM */ snapshots["sbb-menu-button renders Shadow DOM"] = ` @@ -36,23 +36,7 @@ snapshots["sbb-menu-button renders Shadow DOM"] = `; /* end snapshot sbb-menu-button renders Shadow DOM */ -snapshots["sbb-menu-button renders A11y tree Chrome"] = -`

- { - "role": "WebArea", - "name": "", - "children": [ - { - "role": "button", - "name": "a11y label" - } - ] -} -

-`; -/* end snapshot sbb-menu-button renders A11y tree Chrome */ - -snapshots["sbb-menu-button renders component with icon and amount Light DOM"] = +snapshots["sbb-menu-button renders component with icon and amount DOM"] = ` `; -/* end snapshot sbb-menu-button renders component with icon and amount Light DOM */ +/* end snapshot sbb-menu-button renders component with icon and amount DOM */ snapshots["sbb-menu-button renders component with icon and amount Shadow DOM"] = ` @@ -95,7 +79,23 @@ snapshots["sbb-menu-button renders component with icon and amount Shadow DOM"] = `; /* end snapshot sbb-menu-button renders component with icon and amount Shadow DOM */ -snapshots["sbb-menu-button renders A11y tree Firefox"] = +snapshots["sbb-menu-button renders component with icon and amount A11y tree Chrome"] = +`

+ { + "role": "WebArea", + "name": "", + "children": [ + { + "role": "button", + "name": "Action 123456" + } + ] +} +

+`; +/* end snapshot sbb-menu-button renders component with icon and amount A11y tree Chrome */ + +snapshots["sbb-menu-button renders component with icon and amount A11y tree Firefox"] = `

{ "role": "document", @@ -103,11 +103,11 @@ snapshots["sbb-menu-button renders A11y tree Firefox"] = "children": [ { "role": "button", - "name": "a11y label" + "name": "Action 123456" } ] }

`; -/* end snapshot sbb-menu-button renders A11y tree Firefox */ +/* end snapshot sbb-menu-button renders component with icon and amount A11y tree Firefox */ diff --git a/src/elements/menu/menu-button/menu-button.snapshot.spec.ts b/src/elements/menu/menu-button/menu-button.snapshot.spec.ts index d0f5ea950a..59d99df61f 100644 --- a/src/elements/menu/menu-button/menu-button.snapshot.spec.ts +++ b/src/elements/menu/menu-button/menu-button.snapshot.spec.ts @@ -19,15 +19,13 @@ describe(`sbb-menu-button`, () => { `); }); - it('Light DOM', async () => { + it('DOM', async () => { await expect(element).dom.to.be.equalSnapshot(); }); it('Shadow DOM', async () => { await expect(element).shadowDom.to.be.equalSnapshot(); }); - - testA11yTreeSnapshot(); }); describe('renders component with icon and amount', () => { @@ -41,12 +39,14 @@ describe(`sbb-menu-button`, () => { `); }); - it('Light DOM', async () => { + it('DOM', async () => { await expect(element).dom.to.be.equalSnapshot(); }); it('Shadow DOM', async () => { await expect(element).shadowDom.to.be.equalSnapshot(); }); + + testA11yTreeSnapshot(); }); }); diff --git a/src/elements/menu/menu-button/menu-button.stories.ts b/src/elements/menu/menu-button/menu-button.stories.ts index c3acbb37ce..1b73a8b33c 100644 --- a/src/elements/menu/menu-button/menu-button.stories.ts +++ b/src/elements/menu/menu-button/menu-button.stories.ts @@ -8,7 +8,6 @@ import { sbbSpread } from '../../../storybook/helpers/spread.js'; import readme from './readme.md?raw'; import './menu-button.js'; -import '../../icon.js'; const getBasicTemplate = ( { text, ...args }: Args, diff --git a/src/elements/menu/menu-button/menu-button.visual.spec.ts b/src/elements/menu/menu-button/menu-button.visual.spec.ts new file mode 100644 index 0000000000..7ecaafaae2 --- /dev/null +++ b/src/elements/menu/menu-button/menu-button.visual.spec.ts @@ -0,0 +1,95 @@ +import { html, nothing, type TemplateResult } from 'lit'; +import { repeat } from 'lit/directives/repeat.js'; + +import type { visualRegressionFixture } from '../../core/testing/private.js'; +import { + describeEach, + describeViewports, + visualDiffDefault, + visualDiffFocus, + visualDiffHover, +} from '../../core/testing/private.js'; + +import './menu-button.js'; + +describe(`sbb-menu-button`, () => { + const defaultArgs = { + amount: 123 as number | undefined, + iconName: 'tick-small', + label: 'Button', + disabled: false, + slottedIcon: false, + }; + + const template = ({ + amount, + iconName, + label, + disabled, + slottedIcon, + }: typeof defaultArgs): TemplateResult => html` + ${repeat( + new Array(3), + (_, index) => html` + + ${label} ${index} + ${slottedIcon ? html`` : nothing} + + `, + )} + `; + + const state = { + amount: [undefined, 123], + slottedIcon: [false, true], + }; + + const wrapperStyles: Parameters[1] = { + backgroundColor: 'var(--sbb-color-black)', + maxWidth: '256px', + }; + + describeViewports({ viewports: ['zero', 'medium'] }, () => { + for (const visualDiffState of [visualDiffDefault, visualDiffHover, visualDiffFocus]) { + it( + visualDiffState.name, + visualDiffState.with(async (setup) => { + await setup.withFixture(template(defaultArgs), wrapperStyles); + }), + ); + + it( + `disabled ${visualDiffState.name}`, + visualDiffState.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, disabled: true }), wrapperStyles); + }), + ); + + it( + `long label ${visualDiffState.name}`, + visualDiffState.with(async (setup) => { + await setup.withFixture( + template({ + ...defaultArgs, + label: 'Button lorem ipsum dolor sit amet, consectetur adipiscing elit', + }), + wrapperStyles, + ); + }), + ); + } + + describeEach(state, ({ amount, slottedIcon }) => { + it( + visualDiffDefault.name, + visualDiffDefault.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, amount, slottedIcon }), wrapperStyles); + }), + ); + }); + }); +}); diff --git a/src/elements/menu/menu-link/__snapshots__/menu-link.snapshot.spec.snap.js b/src/elements/menu/menu-link/__snapshots__/menu-link.snapshot.spec.snap.js index 23b48564d5..e6d85b3d68 100644 --- a/src/elements/menu/menu-link/__snapshots__/menu-link.snapshot.spec.snap.js +++ b/src/elements/menu/menu-link/__snapshots__/menu-link.snapshot.spec.snap.js @@ -1,7 +1,48 @@ /* @web/test-runner snapshot v1 */ export const snapshots = {}; -snapshots["sbb-menu-link renders component with icon and amount Light DOM"] = +snapshots["sbb-menu-link renders DOM"] = +` + + Action + + +`; +/* end snapshot sbb-menu-link renders DOM */ + +snapshots["sbb-menu-link renders Shadow DOM"] = +` + + + + + + + + + + + + . Link target opens in a new window. + + +`; +/* end snapshot sbb-menu-link renders Shadow DOM */ + +snapshots["sbb-menu-link renders component with icon and amount DOM"] = ` `; -/* end snapshot sbb-menu-link renders component with icon and amount Light DOM */ +/* end snapshot sbb-menu-link renders component with icon and amount DOM */ snapshots["sbb-menu-link renders component with icon and amount Shadow DOM"] = ` { + describe('renders', () => { + let element: SbbMenuLinkElement; + + beforeEach(async () => { + element = await fixture(html` + + Action + + `); + }); + + it('DOM', async () => { + await expect(element).dom.to.be.equalSnapshot(); + }); + + it('Shadow DOM', async () => { + await expect(element).shadowDom.to.be.equalSnapshot(); + }); + }); + describe('renders component with icon and amount', () => { let element: SbbMenuLinkElement; @@ -25,7 +49,7 @@ describe(`sbb-menu-link`, () => { `); }); - it('Light DOM', async () => { + it('DOM', async () => { await expect(element).dom.to.be.equalSnapshot(); }); diff --git a/src/elements/menu/menu-link/menu-link.stories.ts b/src/elements/menu/menu-link/menu-link.stories.ts index 32b4cfc5ba..679d4c79da 100644 --- a/src/elements/menu/menu-link/menu-link.stories.ts +++ b/src/elements/menu/menu-link/menu-link.stories.ts @@ -9,7 +9,6 @@ import { sbbSpread } from '../../../storybook/helpers/spread.js'; import readme from './readme.md?raw'; import './menu-link.js'; -import '../../icon.js'; const getBasicTemplate = ( { text, ...args }: Args, diff --git a/src/elements/menu/menu-link/menu-link.visual.spec.ts b/src/elements/menu/menu-link/menu-link.visual.spec.ts new file mode 100644 index 0000000000..f9ca477fa5 --- /dev/null +++ b/src/elements/menu/menu-link/menu-link.visual.spec.ts @@ -0,0 +1,95 @@ +import { html, nothing, type TemplateResult } from 'lit'; +import { repeat } from 'lit/directives/repeat.js'; + +import type { visualRegressionFixture } from '../../core/testing/private.js'; +import { + describeEach, + describeViewports, + visualDiffDefault, + visualDiffFocus, + visualDiffHover, +} from '../../core/testing/private.js'; + +import './menu-link.js'; + +describe(`sbb-menu-link`, () => { + const defaultArgs = { + amount: 123 as number | undefined, + iconName: 'tick-small', + label: 'Link', + disabled: false, + slottedIcon: false, + }; + + const template = ({ + amount, + iconName, + label, + disabled, + slottedIcon, + }: typeof defaultArgs): TemplateResult => + html` ${repeat( + new Array(3), + (_, index) => html` + + ${label} ${index} + ${slottedIcon ? html`` : nothing} + + `, + )}`; + + const state = { + amount: [undefined, 123], + slottedIcon: [false, true], + }; + + const wrapperStyles: Parameters[1] = { + backgroundColor: 'var(--sbb-color-black)', + maxWidth: '256px', + }; + + describeViewports({ viewports: ['zero', 'medium'] }, () => { + for (const visualDiffState of [visualDiffDefault, visualDiffHover, visualDiffFocus]) { + it( + visualDiffState.name, + visualDiffState.with(async (setup) => { + await setup.withFixture(template(defaultArgs), wrapperStyles); + }), + ); + + it( + `disabled ${visualDiffState.name}`, + visualDiffState.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, disabled: true }), wrapperStyles); + }), + ); + + it( + `long label ${visualDiffState.name}`, + visualDiffState.with(async (setup) => { + await setup.withFixture( + template({ + ...defaultArgs, + label: 'Link lorem ipsum dolor sit amet, consectetur adipiscing elit', + }), + wrapperStyles, + ); + }), + ); + } + + describeEach(state, ({ amount, slottedIcon }) => { + it( + visualDiffDefault.name, + visualDiffDefault.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, amount, slottedIcon }), wrapperStyles); + }), + ); + }); + }); +}); diff --git a/src/elements/menu/menu/__snapshots__/menu.snapshot.spec.snap.js b/src/elements/menu/menu/__snapshots__/menu.snapshot.spec.snap.js index bc36348581..2b9b6c9495 100644 --- a/src/elements/menu/menu/__snapshots__/menu.snapshot.spec.snap.js +++ b/src/elements/menu/menu/__snapshots__/menu.snapshot.spec.snap.js @@ -173,3 +173,37 @@ snapshots["sbb-menu renders with list Shadow DOM"] = `; /* end snapshot sbb-menu renders with list Shadow DOM */ +snapshots["sbb-menu renders with list A11y tree Chrome"] = +`

+ { + "role": "WebArea", + "name": "", + "children": [ + { + "role": "button", + "name": "Menu trigger", + "haspopup": "menu" + } + ] +} +

+`; +/* end snapshot sbb-menu renders with list A11y tree Chrome */ + +snapshots["sbb-menu renders with list A11y tree Firefox"] = +`

+ { + "role": "document", + "name": "", + "children": [ + { + "role": "button", + "name": "Menu trigger", + "haspopup": "menu" + } + ] +} +

+`; +/* end snapshot sbb-menu renders with list A11y tree Firefox */ + diff --git a/src/elements/menu/menu/menu.snapshot.spec.ts b/src/elements/menu/menu/menu.snapshot.spec.ts index 494d06bdca..f54d059cc7 100644 --- a/src/elements/menu/menu/menu.snapshot.spec.ts +++ b/src/elements/menu/menu/menu.snapshot.spec.ts @@ -1,7 +1,7 @@ import { expect } from '@open-wc/testing'; import { html } from 'lit/static-html.js'; -import { fixture } from '../../core/testing/private.js'; +import { fixture, testA11yTreeSnapshot } from '../../core/testing/private.js'; import type { SbbMenuElement } from './menu.js'; @@ -66,5 +66,7 @@ describe(`sbb-menu`, () => { it('Shadow DOM', async () => { await expect(element).shadowDom.to.be.equalSnapshot(); }); + + testA11yTreeSnapshot(); }); }); diff --git a/src/elements/menu/menu/menu.visual.spec.ts b/src/elements/menu/menu/menu.visual.spec.ts new file mode 100644 index 0000000000..f28f2b271b --- /dev/null +++ b/src/elements/menu/menu/menu.visual.spec.ts @@ -0,0 +1,109 @@ +import { html } from 'lit'; +import { repeat } from 'lit/directives/repeat.js'; +import { styleMap } from 'lit/directives/style-map.js'; + +import type { SbbButtonElement } from '../../button/button.js'; +import { describeViewports, visualDiffDefault } from '../../core/testing/private.js'; + +import '../../button/button.js'; +import '../../divider.js'; +import '../../link.js'; +import '../menu-link.js'; +import '../menu-button.js'; +import './menu.js'; + +describe(`sbb-menu`, () => { + const userNameStyle = { + fontWeight: 'bold', + fontSize: 'var(--sbb-font-size-text-xs)', + marginTop: 'var(--sbb-spacing-fixed-1x)', + }; + + const userInfoStyle = { + color: 'var(--sbb-color-graphite)', + fontSize: 'var(--sbb-font-size-text-xxs)', + }; + + describeViewports({ viewports: ['zero', 'medium'], viewportHeight: 400 }, () => { + it( + visualDiffDefault.name, + visualDiffDefault.with(async (setup) => { + await setup.withFixture( + html` + Menu trigger + + + View + + Edit + Details + + Cancel + + `, + { minHeight: '400px' }, + ); + setup.withPostSetupAction(() => { + const button = setup.snapshotElement.querySelector('#menu-trigger-1')!; + button.click(); + }); + }), + ); + + it( + 'list with scroll', + visualDiffDefault.with(async (setup) => { + await setup.withFixture( + html` + Menu trigger + + ${repeat( + new Array(10), + (_, index) => html`Element ${index}`, + )} + + `, + { minHeight: '400px' }, + ); + setup.withPostSetupAction(() => { + const button = setup.snapshotElement.querySelector('#menu-trigger-2')!; + button.click(); + }); + }), + ); + + it( + 'custom content with long label', + visualDiffDefault.with(async (setup) => { + await setup.withFixture( + html` + Menu trigger + +
Christina Müller
+ UIS9057 + + Profile + + + + Very long label that exceeds the maximum width of the menu + + + View + + Tickets + + Log Out +
+ `, + { minHeight: '400px' }, + ); + + setup.withPostSetupAction(() => { + const button = setup.snapshotElement.querySelector('#menu-trigger-3')!; + button.click(); + }); + }), + ); + }); +});