88 */
99
1010import type { Page } from '@playwright/test' ;
11+ import type { Result } from 'axe-core' ;
1112import AxeBuilder from '@axe-core/playwright' ;
1213import { AXE_OPTIONS , AXE_IMPACT_LEVELS } from '@kbn/axe-config' ;
1314
1415import type { KibanaUrl } from '../../..' ;
1516
16- export interface A11yViolation {
17- id : string ;
18- impact ?: string ;
19- description : string ;
20- help : string ;
21- helpUrl : string ;
22- nodes : Array < {
23- html : string ;
24- target : string [ ] ;
25- failureSummary ?: string ;
26- } > ;
27- url ?: string ;
28- }
29-
3017export interface RunA11yScanOptions {
3118 /** Optional CSS selectors to exclude from scan */
3219 exclude ?: string [ ] ;
3320 /** Timeout in ms for the scan (defaults 10000) */
3421 timeoutMs ?: number ;
3522}
3623
37- export interface RunA11yScanResult {
38- violations : A11yViolation [ ] ;
39- }
40-
41- export const runA11yScan = async (
24+ const runA11yScan = async (
4225 page : Page ,
4326 { exclude = [ ] , timeoutMs = 10000 } : RunA11yScanOptions = { }
44- ) : Promise < RunA11yScanResult > => {
27+ ) => {
4528 const builder = new AxeBuilder ( { page } ) ;
4629 builder . options ( AXE_OPTIONS ) ;
4730
@@ -68,7 +51,7 @@ export const runA11yScan = async (
6851 clearTimeout ( timeoutId ) ;
6952 }
7053
71- let violations = ( result . violations as A11yViolation [ ] ) || [ ] ;
54+ let violations : Result [ ] = result . violations ;
7255
7356 if ( AXE_IMPACT_LEVELS ?. length ) {
7457 const allowed = new Set ( AXE_IMPACT_LEVELS ) ;
@@ -80,22 +63,31 @@ export const runA11yScan = async (
8063 return { violations } ;
8164} ;
8265
83- /**
84- * Assert helper usable inside tests.
85- */
8666export const checkA11y = async ( page : Page , kbnUrl ?: KibanaUrl , options ?: RunA11yScanOptions ) => {
8767 const { violations } = await runA11yScan ( page , options ) ;
8868
69+ const formatA11yViolation = ( v : Result ) : string => {
70+ const nodesSection = v . nodes
71+ . map ( ( n , idx ) => {
72+ const selectors = n . target . join ( ', ' ) ;
73+ const failure = n . failureSummary ?. trim ( ) || 'No failure summary provided' ;
74+ return ` ${ idx + 1 } . Selectors: ${ selectors } \n Failure: ${ failure } ` ;
75+ } )
76+ . join ( '\n' ) ;
77+
78+ return [
79+ `\nAccessibility violation detected!\n` ,
80+ ` Rule: ${ v . id } . Impact: (${ v . impact ?? 'impact unknown' } )` ,
81+ ` Description: ${ v . description } ` ,
82+ ` Help: ${ v . help } . See more: ${ v . helpUrl } ` ,
83+ ` Page: ${ kbnUrl } ` ,
84+ ` Nodes:\n${ nodesSection } ` ,
85+ ]
86+ . join ( '\n' )
87+ . trim ( ) ;
88+ } ;
89+
8990 return {
90- violations : violations . map (
91- ( v ) =>
92- `Accessibility violation: ${ v . id } (${ v . impact } ): \n
93- ${ v . helpUrl } \n
94- ${ v . description } \n
95- ${ kbnUrl } \n
96- Nodes:\n${ v . nodes
97- . map ( ( n ) => ` ${ n . target . join ( ', ' ) } -> ${ n . failureSummary } ` )
98- . join ( '\n' ) } `
99- ) ,
91+ violations : violations . map ( ( v ) => formatA11yViolation ( v ) ) ,
10092 } ;
10193} ;
0 commit comments