diff --git a/package.json b/package.json
index bb25470..8cce7e9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "qas-cli",
- "version": "0.3.3",
+ "version": "0.3.4",
"description": "QAS CLI is a command line tool for submitting your automation test results to QA Sphere at https://qasphere.com/",
"type": "module",
"main": "./build/bin/qasphere.js",
diff --git a/src/tests/fixtures/junit-xml/jest-failure-type-missing.xml b/src/tests/fixtures/junit-xml/jest-failure-type-missing.xml
new file mode 100644
index 0000000..bb98059
--- /dev/null
+++ b/src/tests/fixtures/junit-xml/jest-failure-type-missing.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+ Error: expect(received).toBe(expected) // Object.is equality
+
+Expected: 2
+Received: 3
+ at Object.toBe (/Users/a/tmp/jest-test/src/math.test.js:10:28)
+ at Promise.then.completed (/Users/a/tmp/jest-test/node_modules/jest-circus/build/utils.js:298:28)
+ at new Promise (<anonymous>)
+ at callAsyncCircusFn (/Users/a/tmp/jest-test/node_modules/jest-circus/build/utils.js:231:10)
+ at _callCircusTest (/Users/a/tmp/jest-test/node_modules/jest-circus/build/run.js:316:40)
+ at _runTest (/Users/a/tmp/jest-test/node_modules/jest-circus/build/run.js:252:3)
+ at _runTestsForDescribeBlock (/Users/a/tmp/jest-test/node_modules/jest-circus/build/run.js:126:9)
+ at _runTestsForDescribeBlock (/Users/a/tmp/jest-test/node_modules/jest-circus/build/run.js:121:9)
+ at run (/Users/a/tmp/jest-test/node_modules/jest-circus/build/run.js:71:3)
+ at runAndTransformResultsToJestFormat (/Users/a/tmp/jest-test/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
+ at jestAdapter (/Users/a/tmp/jest-test/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
+ at runTestInternal (/Users/a/tmp/jest-test/node_modules/jest-runner/build/runTest.js:367:16)
+ at runTest (/Users/a/tmp/jest-test/node_modules/jest-runner/build/runTest.js:444:34)
+
+
+
+
+
\ No newline at end of file
diff --git a/src/tests/junit-xml-parsing.spec.ts b/src/tests/junit-xml-parsing.spec.ts
index e6dd520..dd6dc8d 100644
--- a/src/tests/junit-xml-parsing.spec.ts
+++ b/src/tests/junit-xml-parsing.spec.ts
@@ -83,4 +83,27 @@ describe('Junit XML parsing', () => {
// Message should include system-out content but not fail on empty system-err
expect(result.testcases[0].message).toContain('ViewManager initialized')
})
+
+ test('Should handle Jest failure without type attribute', async () => {
+ const xmlPath = `${xmlBasePath}/jest-failure-type-missing.xml`
+ const xmlContent = await readFile(xmlPath, 'utf8')
+
+ const result = await parseJUnitXml(xmlContent, xmlBasePath)
+ expect(result.testcases).toHaveLength(3)
+
+ // Verify test result types
+ const typeCounts = result.testcases.reduce((acc, tc) => {
+ acc[tc.type] = (acc[tc.type] || 0) + 1
+ return acc
+ }, {} as Record)
+
+ expect(typeCounts.success).toBe(2)
+ expect(typeCounts.failure).toBe(1)
+
+ // Find the failure test case
+ const failedTest = result.testcases.find(tc => tc.type === 'failure')
+ expect(failedTest).toBeDefined()
+ expect(failedTest?.name).toContain('subtracts two numbers correctly')
+ expect(failedTest?.message).toContain('expect(received).toBe(expected)')
+ })
})
diff --git a/src/utils/junit/junitXmlParser.ts b/src/utils/junit/junitXmlParser.ts
index 881365b..a40a856 100644
--- a/src/utils/junit/junitXmlParser.ts
+++ b/src/utils/junit/junitXmlParser.ts
@@ -4,6 +4,13 @@ import { readFile } from 'fs/promises'
import xml from 'xml2js'
import z from 'zod'
+// Note about junit xml schema:
+// there are multiple schemas on the internet, and apparently some are more strict than others
+// we have to use LESS strict schema (see one from Jest, based on Jenkins JUnit schema)
+// see https://github.com/jest-community/jest-junit/blob/master/__tests__/lib/junit.xsd#L42
+
+
+
const stringContent = z.object({
_: z.string().optional(),
})
@@ -11,8 +18,8 @@ const stringContent = z.object({
const failureErrorSchema = stringContent.extend({
$: z.object({
message: z.string().optional(),
- type: z.string(), // type attribute is required for failure and error
- }),
+ type: z.string().optional(), // type attribute is optional (some test runners like Jest don't include it)
+ }).optional(),
})
// As per https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd, only message attribute