From b1e31811cfd7ffacc5b621741f35a0c141d519eb Mon Sep 17 00:00:00 2001 From: Davide Mininni Date: Tue, 2 Jul 2024 14:34:10 +0200 Subject: [PATCH 1/4] test: add visual tests --- src/elements/select/select.stories.ts | 4 +- src/elements/select/select.visual.spec.ts | 251 ++++++++++++++++++++++ 2 files changed, 253 insertions(+), 2 deletions(-) create mode 100644 src/elements/select/select.visual.spec.ts diff --git a/src/elements/select/select.stories.ts b/src/elements/select/select.stories.ts index 112d2be2a7..ff6dca943d 100644 --- a/src/elements/select/select.stories.ts +++ b/src/elements/select/select.stories.ts @@ -11,7 +11,7 @@ import type { } from '@storybook/web-components'; import isChromatic from 'chromatic/isChromatic'; import type { TemplateResult } from 'lit'; -import { html, nothing } from 'lit'; +import { html } from 'lit'; import type { StyleInfo } from 'lit/directives/style-map.js'; import { styleMap } from 'lit/directives/style-map.js'; @@ -241,7 +241,7 @@ const textBlock = (text: string | null = null): TemplateResult => { the form field, but it must always be covered by the select overlay. ` - : nothing} + : text} `; }; diff --git a/src/elements/select/select.visual.spec.ts b/src/elements/select/select.visual.spec.ts new file mode 100644 index 0000000000..c1e3f08d3d --- /dev/null +++ b/src/elements/select/select.visual.spec.ts @@ -0,0 +1,251 @@ +import { html, nothing, type TemplateResult } from 'lit'; + +import { describeViewports, visualDiffDefault, visualDiffFocus } from '../core/testing/private.js'; + +import '../form-error.js'; +import '../form-field.js'; +import '../option.js'; +import './select.js'; + +describe('sbb-select', () => { + const valueEllipsis: string = 'This label name is so long that it needs ellipsis to fit.'; + const defaultArgs = { + borderless: false, + negative: false, + floatingLabel: false, + disableOption: false, + withOptionGroup: false, + disableGroup: false, + withEllipsis: false, + value: undefined as string | string[] | undefined, + multiple: false, + disabled: false, + required: false, + readonly: false, + }; + + const createOptions = ( + disableOption: boolean, + group: string | boolean, + selectValue: string | string[] | undefined = undefined, + ): TemplateResult[] => { + return new Array(5).fill(null).map((_, i) => { + const value = group ? `Option ${i + 1} ${' - ' + group}` : `Option ${i + 1}`; + const selected = Array.isArray(selectValue) + ? selectValue.includes(value) + : selectValue === value; + return html` + + ${value} + + `; + }); + }; + + const createOptionsGroup = ( + disableOption: boolean, + disableGroup: boolean, + ): TemplateResult => html` + + ${createOptions(disableOption, '1')} + + ${createOptions(disableOption, '2')} + `; + + const template = ({ + borderless, + negative, + floatingLabel, + disableOption, + withOptionGroup, + disableGroup, + withEllipsis, + ...args + }: typeof defaultArgs): TemplateResult => { + if (args.multiple && args.value) { + args.value = [args.value as string]; + } + return html` +
+ + + + ${withEllipsis + ? html` + ${valueEllipsis} + ` + : nothing} + ${withOptionGroup + ? createOptionsGroup(disableOption, disableGroup) + : createOptions(disableOption, false, args.value)} + + ${args.required ? html`Error` : nothing} + +
+ `; + }; + + describeViewports({ viewports: ['zero', 'medium'], viewportHeight: 400 }, () => { + for (const negative of [false, true]) { + for (const visualDiffState of [visualDiffDefault, visualDiffFocus]) { + it( + `state=above negative=${negative} ${visualDiffState.name}`, + visualDiffState.with(async (setup) => { + await setup.withFixture( + html` +
+ ${template({ ...defaultArgs, negative })} +
+ `, + { + minHeight: '400px', + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }, + ); + setup.withPostSetupAction(() => { + const select = setup.snapshotElement.querySelector('sbb-select')!; + select.open(); + }); + }), + ); + } + } + }); + + describeViewports({ viewports: ['zero', 'medium'] }, () => { + for (const negative of [false, true]) { + for (const visualDiffState of [visualDiffDefault, visualDiffFocus]) { + it( + `state=${visualDiffState.name} negative=${negative}`, + visualDiffState.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, negative }), { + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }); + }), + ); + } + + it( + `state=required negative=${negative}`, + visualDiffDefault.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, negative, required: true }), { + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }); + }), + ); + + it( + `state=disabled negative=${negative}`, + visualDiffDefault.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, negative, disabled: true }), { + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }); + }), + ); + + it( + `state=readonly negative=${negative}`, + visualDiffDefault.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, negative, readonly: true }), { + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }); + }), + ); + + it( + `state=borderless negative=${negative}`, + visualDiffDefault.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, negative, borderless: true }), { + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }); + }), + ); + + for (const multiple of [false, true]) { + it( + `negative=${negative} multiple=${multiple}`, + visualDiffDefault.with(async (setup) => { + await setup.withFixture(template({ ...defaultArgs, negative, multiple }), { + minHeight: '400px', + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }); + setup.withPostSetupAction(() => { + const select = setup.snapshotElement.querySelector('sbb-select')!; + select.open(); + }); + }), + ); + + it( + `negative=${negative} multiple=${multiple} withEllipsis=true`, + visualDiffDefault.with(async (setup) => { + await setup.withFixture( + template({ ...defaultArgs, negative, multiple, withEllipsis: true }), + { + minHeight: '600px', + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }, + ); + setup.withPostSetupAction(() => { + const select = setup.snapshotElement.querySelector('sbb-select')!; + select.open(); + }); + }), + ); + + it( + `negative=${negative} multiple=${multiple} disableOption=true`, + visualDiffDefault.with(async (setup) => { + await setup.withFixture( + template({ ...defaultArgs, negative, multiple, disableOption: true }), + { + minHeight: '400px', + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }, + ); + setup.withPostSetupAction(() => { + const select = setup.snapshotElement.querySelector('sbb-select')!; + select.open(); + }); + }), + ); + + for (const disableGroup of [false, true]) { + it( + `negative=${negative} multiple=${multiple} withOptionGroup=true disableGroup=${disableGroup}`, + visualDiffDefault.with(async (setup) => { + await setup.withFixture( + template({ + ...defaultArgs, + negative, + multiple, + disableGroup, + withOptionGroup: true, + }), + { + minHeight: '800px', + backgroundColor: negative ? 'var(--sbb-color-black)' : undefined, + }, + ); + setup.withPostSetupAction(() => { + const select = setup.snapshotElement.querySelector('sbb-select')!; + select.open(); + }); + }), + ); + } + } + } + }); +}); From be0f8eb2dedc4df9f58e8aa404585b9c0808e94c Mon Sep 17 00:00:00 2001 From: Davide Mininni Date: Tue, 2 Jul 2024 14:38:34 +0200 Subject: [PATCH 2/4] chore: minor fix --- src/elements/select/select.visual.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elements/select/select.visual.spec.ts b/src/elements/select/select.visual.spec.ts index c1e3f08d3d..a211e56174 100644 --- a/src/elements/select/select.visual.spec.ts +++ b/src/elements/select/select.visual.spec.ts @@ -104,7 +104,7 @@ describe('sbb-select', () => { visualDiffState.with(async (setup) => { await setup.withFixture( html` -
+
${template({ ...defaultArgs, negative })}
`, From 54faa8cf55f16322e92514d4c01fe8dc8bb3ba2b Mon Sep 17 00:00:00 2001 From: Davide Mininni Date: Wed, 3 Jul 2024 09:38:07 +0200 Subject: [PATCH 3/4] chore: minor fix --- src/elements/select/select.visual.spec.ts | 50 +++++++++++------------ 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/elements/select/select.visual.spec.ts b/src/elements/select/select.visual.spec.ts index a211e56174..1c106e49b7 100644 --- a/src/elements/select/select.visual.spec.ts +++ b/src/elements/select/select.visual.spec.ts @@ -66,33 +66,29 @@ describe('sbb-select', () => { args.value = [args.value as string]; } return html` -
- + + - - - ${withEllipsis - ? html` - ${valueEllipsis} - ` - : nothing} - ${withOptionGroup - ? createOptionsGroup(disableOption, disableGroup) - : createOptions(disableOption, false, args.value)} - - ${args.required ? html`Error` : nothing} - -
+ ${withEllipsis + ? html` ${valueEllipsis} ` + : nothing} + ${withOptionGroup + ? createOptionsGroup(disableOption, disableGroup) + : createOptions(disableOption, false, args.value)} + + ${args.required ? html`Error` : nothing} + `; }; @@ -104,7 +100,7 @@ describe('sbb-select', () => { visualDiffState.with(async (setup) => { await setup.withFixture( html` -
+
${template({ ...defaultArgs, negative })}
`, From bc1991c764024105cc8fdc56f273c537fbe0bb59 Mon Sep 17 00:00:00 2001 From: Davide Mininni Date: Wed, 3 Jul 2024 10:14:14 +0200 Subject: [PATCH 4/4] fix: remove useless param --- src/elements/select/select.visual.spec.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/elements/select/select.visual.spec.ts b/src/elements/select/select.visual.spec.ts index 1c106e49b7..88370f71dd 100644 --- a/src/elements/select/select.visual.spec.ts +++ b/src/elements/select/select.visual.spec.ts @@ -12,7 +12,6 @@ describe('sbb-select', () => { const defaultArgs = { borderless: false, negative: false, - floatingLabel: false, disableOption: false, withOptionGroup: false, disableGroup: false, @@ -55,7 +54,6 @@ describe('sbb-select', () => { const template = ({ borderless, negative, - floatingLabel, disableOption, withOptionGroup, disableGroup, @@ -66,11 +64,7 @@ describe('sbb-select', () => { args.value = [args.value as string]; } return html` - +