1+ import JUnitReporter from '../../src/reporter/junitReporter'
2+ import { Result } from 'axe-core'
3+ import * as fs from 'fs'
4+ import * as path from 'path'
5+
6+ describe ( 'JUnit Reporter XML Generation' , ( ) => {
7+ const testOutputDir = path . join ( process . cwd ( ) , 'test-output' )
8+ const testXmlFile = path . join ( testOutputDir , 'test-results.xml' )
9+
10+ beforeEach ( ( ) => {
11+ // Clean up before each test
12+ if ( fs . existsSync ( testXmlFile ) ) {
13+ fs . unlinkSync ( testXmlFile )
14+ }
15+ if ( fs . existsSync ( testOutputDir ) ) {
16+ fs . rmSync ( testOutputDir , { recursive : true } )
17+ }
18+ } )
19+
20+ afterEach ( ( ) => {
21+ // Clean up after each test
22+ if ( fs . existsSync ( testXmlFile ) ) {
23+ fs . unlinkSync ( testXmlFile )
24+ }
25+ if ( fs . existsSync ( testOutputDir ) ) {
26+ fs . rmSync ( testOutputDir , { recursive : true } )
27+ }
28+ } )
29+
30+ it ( 'generates valid XML when violations exist' , async ( ) => {
31+ const violations : Result [ ] = [
32+ {
33+ id : 'label' ,
34+ description : 'Form elements must have labels' ,
35+ help : 'Form elements must have labels' ,
36+ helpUrl : 'https://dequeuniversity.com/rules/axe/4.4/label' ,
37+ impact : 'critical' ,
38+ nodes : [
39+ {
40+ target : [ '#username' ] ,
41+ html : '<input type="text" name="username">' ,
42+ failureSummary : 'Fix any of the following:\n Element does not have a label'
43+ }
44+ ]
45+ } as Result
46+ ]
47+
48+ const reporter = new JUnitReporter ( false , undefined , testXmlFile )
49+
50+ try {
51+ await reporter . report ( violations )
52+ } catch ( e ) {
53+ // Expected to throw, but XML should still be generated
54+ }
55+
56+ // Check that XML file was created
57+ expect ( fs . existsSync ( testXmlFile ) ) . toBe ( true )
58+
59+ // Read and validate XML content
60+ const xmlContent = fs . readFileSync ( testXmlFile , 'utf8' )
61+
62+ // Basic XML structure checks
63+ expect ( xmlContent ) . toContain ( '<?xml version="1.0" encoding="UTF-8"?>' )
64+ expect ( xmlContent ) . toContain ( '<testsuite' )
65+ expect ( xmlContent ) . toContain ( '<testcase' )
66+ expect ( xmlContent ) . toContain ( '</testsuite>' )
67+
68+ // Violation-specific checks
69+ expect ( xmlContent ) . toContain ( 'label' )
70+ expect ( xmlContent ) . toContain ( 'Form elements must have labels' )
71+ expect ( xmlContent ) . toContain ( '<failure' )
72+ } )
73+
74+ it ( 'generates valid XML when no violations exist' , async ( ) => {
75+ const reporter = new JUnitReporter ( false , undefined , testXmlFile )
76+
77+ await reporter . report ( [ ] )
78+
79+ // Check that XML file was created
80+ expect ( fs . existsSync ( testXmlFile ) ) . toBe ( true )
81+
82+ // Read and validate XML content
83+ const xmlContent = fs . readFileSync ( testXmlFile , 'utf8' )
84+
85+ // Basic XML structure checks
86+ expect ( xmlContent ) . toContain ( '<?xml version="1.0" encoding="UTF-8"?>' )
87+ expect ( xmlContent ) . toContain ( '<testsuite' )
88+ expect ( xmlContent ) . toContain ( '<testcase' )
89+ expect ( xmlContent ) . toContain ( '</testsuite>' )
90+
91+ // Should contain the success test case
92+ expect ( xmlContent ) . toContain ( 'Accesibility testing - A11Y' )
93+
94+ // Should NOT contain failure tags
95+ expect ( xmlContent ) . not . toContain ( '<failure>' )
96+ } )
97+
98+ it ( 'creates directory structure if missing' , async ( ) => {
99+ const deepPath = path . join ( testOutputDir , 'nested' , 'deeper' , 'results.xml' )
100+ const reporter = new JUnitReporter ( false , undefined , deepPath )
101+
102+ await reporter . report ( [ ] )
103+
104+ expect ( fs . existsSync ( deepPath ) ) . toBe ( true )
105+ } )
106+
107+ it ( 'validates XML structure with real XML parser' , async ( ) => {
108+ const violations : Result [ ] = [
109+ {
110+ id : 'color-contrast' ,
111+ description : 'Elements must have sufficient color contrast' ,
112+ help : 'Elements must have sufficient color contrast' ,
113+ nodes : [
114+ {
115+ target : [ '.text' ] ,
116+ html : '<span class="text">Low contrast text</span>' ,
117+ failureSummary : 'Element has insufficient color contrast'
118+ }
119+ ]
120+ } as Result
121+ ]
122+
123+ const reporter = new JUnitReporter ( false , undefined , testXmlFile )
124+
125+ try {
126+ await reporter . report ( violations )
127+ } catch ( e ) {
128+ // Expected to throw
129+ }
130+
131+ const xmlContent = fs . readFileSync ( testXmlFile , 'utf8' )
132+
133+ // Try to parse as XML (will throw if invalid)
134+ const parseXML = require ( 'xml2js' ) . parseString
135+ expect ( ( ) => {
136+ parseXML ( xmlContent , ( err : any , result : any ) => {
137+ if ( err ) throw err
138+ expect ( result ) . toBeDefined ( )
139+ } )
140+ } ) . not . toThrow ( )
141+ } )
142+ } )
0 commit comments