···11+import {expect, type Page} from '@playwright/test';
22+import {AxeBuilder} from '@axe-core/playwright';
33+44+export async function accessibilityCheck({page}: {page: Page}, includes: string[], excludes: string[], disabledRules: string[]) {
55+ // contrast of inline links is still a global issue in Forgejo
66+ disabledRules += 'link-in-text-block';
77+88+ let accessibilityScanner = await new AxeBuilder({page})
99+ .disableRules(disabledRules);
1010+ // passing the whole array seems to be not supported,
1111+ // iterating has the nice side-effectof skipping this if the array is empty
1212+ for (const incl of includes) {
1313+ // passing the whole array seems to be not supported
1414+ accessibilityScanner = accessibilityScanner.include(incl);
1515+ }
1616+ for (const excl of excludes) {
1717+ accessibilityScanner = accessibilityScanner.exclude(excl);
1818+ }
1919+2020+ // scan the page both in dark and light theme
2121+ let accessibilityScanResults = await accessibilityScanner.analyze();
2222+ expect(accessibilityScanResults.violations).toEqual([]);
2323+ await page.emulateMedia({colorScheme: 'dark'});
2424+ // in https://codeberg.org/forgejo/forgejo/pulls/5899 there have been
2525+ // some weird failures related to contrast scanning,
2626+ // reporting for colours that haven't been used and no trace in the
2727+ // screenshots.
2828+ // Since this was only happening with some browsers and not always,
2929+ // my bet is on a transition effect on dark/light mode switch.
3030+ // Waiting a little seems to work around this.
3131+ await page.waitForTimeout(100); // eslint-disable-line playwright/no-wait-for-timeout
3232+ accessibilityScanResults = await accessibilityScanner.analyze();
3333+ expect(accessibilityScanResults.violations).toEqual([]);
3434+ await page.emulateMedia({colorScheme: 'light'});
3535+}
+6-9
tests/e2e/shared/forms.ts
···11import {expect, type Page} from '@playwright/test';
22-import {AxeBuilder} from '@axe-core/playwright';
22+import {accessibilityCheck} from './accessibility.ts';
3344export async function validate_form({page}: {page: Page}, scope: 'form' | 'fieldset' = 'form') {
55- const accessibilityScanResults = await new AxeBuilder({page})
66- // disable checking for link style - should be fixed, but not now
77- .disableRules('link-in-text-block')
88- .include(scope)
55+ const excludedElements = [
96 // exclude automated tooltips from accessibility scan, remove when fixed
1010- .exclude('span[data-tooltip-content')
77+ 'span[data-tooltip-content',
118 // exclude weird non-semantic HTML disabled content
1212- .exclude('.disabled')
1313- .analyze();
1414- expect(accessibilityScanResults.violations).toEqual([]);
99+ '.disabled',
1010+ ];
1111+ await accessibilityCheck({page}, [scope], excludedElements, []);
15121613 // assert CSS properties that needed to be overriden for forms (ensure they remain active)
1714 const boxes = page.getByRole('checkbox').or(page.getByRole('radio'));