diff --git a/packages/documentation/.storybook/preview-body.html b/packages/documentation/.storybook/preview-body.html index 3fde0cc66f..c14958894c 100644 --- a/packages/documentation/.storybook/preview-body.html +++ b/packages/documentation/.storybook/preview-body.html @@ -1 +1,3 @@ - + + + \ No newline at end of file diff --git a/packages/documentation/.storybook/styles/preview.scss b/packages/documentation/.storybook/styles/preview.scss index 6f75613950..9b9876e416 100644 --- a/packages/documentation/.storybook/styles/preview.scss +++ b/packages/documentation/.storybook/styles/preview.scss @@ -1,11 +1,9 @@ // importing the complete styles package scss @use '@swisspost/design-system-styles/core.scss' as post; -@use '@swisspost/internet-header/dist/swisspost-internet-header/swisspost-internet-header.css'; -@use './components'; @use '@swisspost/design-system-styles/functions/tokens'; @use '@swisspost/design-system-styles/tokens/utilities'; - -tokens.$default-map: utilities.$post-color; +@use '@swisspost/internet-header/dist/swisspost-internet-header/swisspost-internet-header.css'; +@use './components'; $monospace: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; diff --git a/packages/documentation/cypress/e2e/components/palette.cy.ts b/packages/documentation/cypress/e2e/components/palette.cy.ts index dc38dc8312..3617686bc2 100644 --- a/packages/documentation/cypress/e2e/components/palette.cy.ts +++ b/packages/documentation/cypress/e2e/components/palette.cy.ts @@ -1,13 +1,156 @@ -describe('Palette', () => { - describe('Accessibility', () => { - beforeEach(() => { - cy.visit('/iframe.html?id=snapshots--palette'); - cy.get('.palette-default', { timeout: 30000 }).should('be.visible'); - cy.injectAxe(); +interface PaletteDefinition { + name: string; + scheme: 'even' | 'swapped' | 'light' | 'dark'; +} + +interface ThemeDefinition { + name: string; + palettes: PaletteDefinition[]; +} + +const THEME_PALETTE_DEFINITIONS: ThemeDefinition[] = [ + { + name: 'Post', + palettes: [ + { name: 'Default', scheme: 'even' }, + { name: 'Alternate', scheme: 'even' }, + { name: 'Accent', scheme: 'dark' }, + { name: 'Brand', scheme: 'light' }, + ], + }, + { + name: 'Cargo', + palettes: [ + { name: 'Default', scheme: 'even' }, + { name: 'Aternate', scheme: 'even' }, + { name: 'Accent', scheme: 'light' }, + { name: 'Brand', scheme: 'dark' }, + ], + }, +]; + +function testGenerator( + callback: (theme: string, scheme: string, palette: PaletteDefinition) => void, +) { + THEME_PALETTE_DEFINITIONS.forEach(theme => { + ['light', 'dark'].forEach(scheme => { + theme.palettes.forEach(palette => { + callback(theme.name, scheme, palette); + }); }); + }); +} + +function isDark(color: string) { + const rgb = color.match(/\d+/g); + + if (rgb) { + const [r, g, b] = rgb.map(Number); + const brightness = (r * 299 + g * 587 + b * 114) / 1000; + return brightness < 128; + } + + return false; +} + +describe('Palette', () => { + testGenerator((theme, scheme, palette) => { + const THEME_STYLES_URL = `/styles/${theme.toLowerCase()}-default.css`; + + describe(`${theme}: ${scheme} - Palette ${palette.name}`, () => { + beforeEach(() => { + cy.visit('/iframe.html?id=43481535-5b39-40b5-a273-478b07dc3b31--default'); + + cy.get('[data-color-scheme]', { timeout: 30000 }) + .as('schemecontainer') + .should('be.visible'); + cy.get('link[href="/styles/post-default.css"]').as('theme-css'); + cy.get('.palette').as('palette'); - it('Has no detectable a11y violations on load for all variants', () => { - cy.checkA11y('#root-inner'); + // update theme stylesheet (if needed) + cy.get('@theme-css') + .invoke('attr', 'href') + .then(href => { + if (href !== THEME_STYLES_URL) { + cy.intercept('GET', THEME_STYLES_URL).as('load-theme-styles'); + cy.get('@theme-css').invoke('attr', 'href', THEME_STYLES_URL); + cy.wait('@load-theme-styles'); + } + }); + + // update page color-scheme + cy.get('@schemecontainer').invoke('attr', 'data-color-scheme', scheme); + + // update palette variant + cy.get('@palette') + .invoke('removeClass', 'palette-default') + .invoke('addClass', `palette-${palette.name.toLowerCase()}`); + }); + + it(`should have a color-scheme "${palette.scheme}"`, () => { + cy.get('@schemecontainer').then($container => { + const containerStyles = window.getComputedStyle($container.get(0)); + const containerScheme = containerStyles.getPropertyValue('color-scheme'); + + cy.get('@palette').then($palette => { + const paletteStyles = window.getComputedStyle($palette.get(0)); + const paletteScheme = paletteStyles.getPropertyValue('color-scheme'); + + // check if palette color-scheme is set correctly, according to the page color-scheme + switch (palette.scheme) { + case 'even': + // light on light | dark on dark + expect(paletteScheme).to.equal(containerScheme); + break; + case 'swapped': + // dark on light | light on dark + expect(paletteScheme).to.not.equal(containerScheme); + break; + case 'light': + // light on light | light on dark + expect(paletteScheme).to.equal('light'); + break; + case 'dark': + // dark on light | dark on dark + expect(paletteScheme).to.equal('dark'); + break; + } + }); + }); + }); + + it(`should have a background- and foreground-color matching its color-scheme`, () => { + cy.get('@palette').then($palette => { + const paletteStyles = window.getComputedStyle($palette.get(0)); + const paletteScheme = paletteStyles.getPropertyValue('color-scheme'); + const paletteBg = paletteStyles.getPropertyValue('background-color'); + const paletteFg = paletteStyles.getPropertyValue('color'); + + // check if palette background- and foreground-color are set correctly, according to the palette color-scheme + switch (paletteScheme) { + case 'light': + expect(isDark(paletteBg)).to.be.false; + expect(isDark(paletteFg)).to.be.true; + break; + case 'dark': + expect(isDark(paletteBg)).to.be.true; + expect(isDark(paletteFg)).to.be.false; + break; + } + }); + }); }); }); }); + +describe('Accessibility', () => { + beforeEach(() => { + cy.visit('/iframe.html?id=snapshots--palette'); + cy.get('.palette-default', { timeout: 30000 }).should('be.visible'); + cy.injectAxe(); + }); + + it('Has no detectable a11y violations on load for all variants', () => { + cy.checkA11y('#root-inner'); + }); +}); diff --git a/packages/documentation/src/shared/snapshots/schemes.ts b/packages/documentation/src/shared/snapshots/schemes.ts index 2a9adac2a3..c84eed54bf 100644 --- a/packages/documentation/src/shared/snapshots/schemes.ts +++ b/packages/documentation/src/shared/snapshots/schemes.ts @@ -17,8 +17,6 @@ export function schemes(renderFn: (scheme: string) => TemplateResult, options: I return html`${[...additionalSchemes, ...Object.values(COLOR_SCHEMES)] .filter(filter) .map( - scheme => html`
- ${renderFn(scheme)} -
`, + scheme => html`
${renderFn(scheme)}
`, )}`; } diff --git a/packages/documentation/src/stories/foundations/palettes/palettes.stories.ts b/packages/documentation/src/stories/foundations/palettes/palettes.stories.ts index 0d54b51955..403fcf3f4f 100644 --- a/packages/documentation/src/stories/foundations/palettes/palettes.stories.ts +++ b/packages/documentation/src/stories/foundations/palettes/palettes.stories.ts @@ -42,7 +42,7 @@ export default meta; // RENDERER function renderPalette(args: Args) { return html` -
+

I use a specific color from the palette (it might be the same as the body color).