Skip to content

Commit 46e36b4

Browse files
committedNov 20, 2024·
feat: added cypress example (still with error)
1 parent c147458 commit 46e36b4

10 files changed

+1395
-33
lines changed
 

‎.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ node_modules
33
*/fullTestSuite.json
44
upload.marker.json
55
.currents
6-
.env
6+
.env
7+
cypress/

‎cy-example/combined-results.xml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<testsuites>
3+
<testsuite name="First Test Suite" timestamp="2024-11-20T05:26:28" tests="2" failures="1" time="3.238" file="cy-example/e2e/first.cy.js">
4+
<testcase name="First Test Suite visits google" time="0" classname="visits google" failure="true" error="true" success="false">
5+
<failure message="Timed out retrying after 4000ms: expected 'Google' to include 'Amazon'" type="AssertionError">AssertionError: Timed out retrying after 4000ms: expected 'Google' to include 'Amazon'
6+
at Context.eval (webpack:///./e2e/first.cy.js:4:15)</failure>
7+
</testcase>
8+
<testcase name="First Test Suite can search" time="3.238" classname="can search" failure="false" error="false" success="true"/>
9+
</testsuite>
10+
<testsuite name="Second Test Suite" timestamp="2024-11-20T05:26:40" tests="2" failures="0" time="4.33" file="cy-example/e2e/second.cy.js">
11+
<testcase name="Second Test Suite visits google" time="1.174" classname="visits google" failure="false" error="false" success="true"/>
12+
<testcase name="Second Test Suite can search" time="3.156" classname="can search" failure="false" error="false" success="true"/>
13+
</testsuite>
14+
</testsuites>

‎cy-example/config.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"framework": "junit",
3+
"frameworkVersion": "13.16.0",
4+
"cliArgs": {
5+
"options": { "jUnitFile": "cy-example/combined-results.xml" },
6+
"args": []
7+
},
8+
"frameworkConfig": {
9+
"originFramework": "cypress",
10+
"originFrameworkVersion": "13.16.0"
11+
}
12+
}

‎cy-example/cypress.config.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const { defineConfig } = require("cypress");
2+
3+
module.exports = defineConfig({
4+
e2e: {
5+
supportFile: false,
6+
specPattern: "cy-example/e2e/*.cy.js",
7+
reporter: "cypress-junit-reporter",
8+
reporterOptions: {
9+
mochaFile: "cy-example/results-[hash].xml",
10+
toConsole: true,
11+
},
12+
setupNodeEvents(on, config) {
13+
// implement node event listeners here
14+
},
15+
},
16+
});

‎cy-example/e2e/first.cy.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
describe("First Test Suite", () => {
2+
it("visits google", () => {
3+
cy.visit("https://www.google.com");
4+
cy.title().should("include", "Amazon");
5+
});
6+
7+
it("can search", () => {
8+
cy.visit("https://www.google.com");
9+
cy.get('[name="q"]').type("Cypress testing{enter}");
10+
});
11+
});

‎cy-example/e2e/second.cy.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
describe("Second Test Suite", () => {
2+
it("visits google", () => {
3+
cy.visit("https://www.google.com");
4+
cy.title().should("include", "Google");
5+
});
6+
7+
it("can search", () => {
8+
cy.visit("https://www.google.com");
9+
cy.get('[name="q"]').type("Cypress testing{enter}");
10+
});
11+
});

‎package-lock.json

+1,232-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "",
55
"main": "index.js",
66
"scripts": {
7-
"initial-setup": "mkdir -p postman-tests-example/instances && mkdir -p vitest-example/instances && mkdir -p wdio-example/instances",
7+
"initial-setup": "mkdir -p postman-tests-example/instances && mkdir -p vitest-example/instances && mkdir -p wdio-example/instances && mkdir -p cy-example/instances",
88
"parse-postman-test": "newman run postman-tests-example/tests.json -r junit --reporter-junit-export postman-tests-example/tests.xml",
99
"gen-instance-postman": "node scripts/junitXmlToInstanceJson.js --input postman-tests-example/tests.xml --output postman-tests-example/instances",
1010
"report-results-postman": "node scripts/uploadResults.js --report-dir postman-tests-example",
@@ -16,7 +16,11 @@
1616
"test-wdio": "npx wdio run wdio-example/wdio.conf.js || true && node ./scripts/combine-results.js --reports-dir wdio-example --output-file wdio-example/combined-results.xml",
1717
"gen-instance-wdio": "node scripts/junitXmlToInstanceJson.js --input wdio-example/combined-results.xml --output wdio-example/instances",
1818
"report-results-wdio": "node scripts/uploadResults.js --report-dir wdio-example",
19-
"wdio:full": "npm run test-wdio || true && npm run gen-instance-wdio && npm run report-results-wdio"
19+
"wdio:full": "npm run test-wdio || true && npm run gen-instance-wdio && npm run report-results-wdio",
20+
"test-cy": "npx cypress run --config-file cy-example/cypress.config.js || true && node ./scripts/combine-results.js --reports-dir cy-example --output-file cy-example/combined-results.xml",
21+
"gen-instance-cy": "node scripts/junitXmlToInstanceJson.js --input cy-example/combined-results.xml --output cy-example/instances",
22+
"report-results-cy": "node scripts/uploadResults.js --report-dir cy-example",
23+
"cy:full": "npm run test-cy || true && npm run gen-instance-cy && npm run report-results-cy"
2024
},
2125
"author": "",
2226
"license": "ISC",
@@ -32,6 +36,8 @@
3236
"@wdio/mocha-framework": "^9.2.8",
3337
"@wdio/spec-reporter": "^9.2.14",
3438
"chromedriver": "^131.0.0",
39+
"cypress": "^13.16.0",
40+
"cypress-junit-reporter": "^1.3.1",
3541
"dotenv-cli": "^7.4.3",
3642
"vitest": "^2.1.5"
3743
}

‎scripts/combine-results.js

+28-13
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const args = process.argv.slice(2);
66
const reportsDirIndex = args.indexOf('--reports-dir');
77
const outputFileIndex = args.indexOf('--output-file');
88

9-
// Set directories with defaults
109
const reportsDir = reportsDirIndex !== -1 ? args[reportsDirIndex + 1] : "wdio-example";
1110
const outputFile = outputFileIndex !== -1 ? args[outputFileIndex + 1] : "wdio-example/combined-results.xml";
1211

@@ -15,31 +14,47 @@ if (reportsDirIndex === -1 || outputFileIndex === -1) {
1514
console.log(`Using defaults: --reports-dir="${reportsDir}" --output-file="${outputFile}"`);
1615
}
1716

17+
async function processTestSuites(testsuites) {
18+
const processedSuites = [];
19+
20+
for (let i = 0; i < testsuites.length; i++) {
21+
const currentSuite = testsuites[i];
22+
const nextSuite = testsuites[i + 1];
23+
24+
if (currentSuite.$.name === "Root Suite" && nextSuite) {
25+
// Add file property from Root Suite to next suite
26+
nextSuite.$.file = currentSuite.$.file;
27+
// Skip the Root Suite (increment i)
28+
i++;
29+
processedSuites.push(nextSuite);
30+
} else if (currentSuite.$.name !== "Root Suite") {
31+
// Keep non-Root suites as they are
32+
processedSuites.push(currentSuite);
33+
}
34+
}
35+
36+
return processedSuites;
37+
}
38+
1839
async function combineResults() {
1940
const files = fs
2041
.readdirSync(reportsDir)
2142
.filter((f) => f.startsWith("results-") && f.endsWith(".xml"));
2243

2344
let combinedTestsuites = {
2445
testsuites: {
25-
testsuite: [],
26-
},
46+
$: {},
47+
testsuite: []
48+
}
2749
};
2850

2951
for (const file of files) {
3052
const content = fs.readFileSync(path.join(reportsDir, file), "utf-8");
3153
const result = await xml2js.parseStringPromise(content);
3254

3355
if (result.testsuites && result.testsuites.testsuite) {
34-
if (Array.isArray(result.testsuites.testsuite)) {
35-
combinedTestsuites.testsuites.testsuite.push(
36-
...result.testsuites.testsuite
37-
);
38-
} else {
39-
combinedTestsuites.testsuites.testsuite.push(
40-
result.testsuites.testsuite
41-
);
42-
}
56+
const processedSuites = await processTestSuites(result.testsuites.testsuite);
57+
combinedTestsuites.testsuites.testsuite.push(...processedSuites);
4358
}
4459
}
4560

@@ -54,4 +69,4 @@ async function combineResults() {
5469
console.log("Results combined into:", outputFile);
5570
}
5671

57-
combineResults().catch(console.error);
72+
combineResults().catch(console.error);

‎scripts/junitXmlToInstanceJson.js

+61-15
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ fs.readFile(xmlFilePath, "utf-8", (err, data) => {
8484

8585
const suiteJson = {
8686
groupId: result.testsuites.name,
87-
spec: suite.name,
87+
spec: suite.file ?? suite.name,
8888
worker: {
8989
workerIndex: 1,
9090
parallelIndex: 1,
@@ -94,46 +94,57 @@ fs.readFile(xmlFilePath, "utf-8", (err, data) => {
9494
stats: {
9595
suites: testcases.length,
9696
tests: parseInt(suite.tests),
97-
passes: testcases.filter((tc) => !tc.failure).length,
97+
passes: testcases.filter((tc) => !tc?.failure).length,
9898
pending: 0,
9999
skipped: 0,
100-
failures: testcases.filter((tc) => tc.failure).length,
100+
failures: testcases.filter((tc) => tc?.failure).length,
101101
flaky: 0,
102102
wallClockStartedAt: suite.timestamp,
103103
wallClockEndedAt: endTime.toISOString(),
104104
wallClockDuration: durationMillis,
105105
},
106106
tests: testcases.map((test) => {
107+
console.log("FAIL::", test.failure);
108+
const hasFailure = test?.failure && test?.failure !== "false";
109+
console.log("FAILURERES::", extractFailure(test?.failure));
107110
return {
108111
_t: Date.now(),
109-
testId: generateTestId(test.name, suite.name),
110-
title: [test.name],
111-
state: test.failure ? "failed" : "passed",
112+
testId: generateTestId(test?.name, suite.name),
113+
title: [test?.name],
114+
state: hasFailure ? "failed" : "passed",
112115
isFlaky: false,
113-
expectedStatus: test.failure ? "failed" : "passed",
116+
expectedStatus: hasFailure ? "failed" : "passed",
114117
timeout: 0,
115118
location: {
116119
column: 1,
117-
file: "postman-tests-example/tests.xml",
120+
file: suite.file ?? suite.name,
118121
line: 1,
119122
},
120123
retries: 1,
121124
attempts: [
122125
{
123-
_s: test.failure ? "failed" : "passed",
126+
_s: hasFailure ? "failed" : "passed",
124127
attempt: 1,
125128
workerIndex: 1,
126129
parallelIndex: 1,
127130
startTime: suite.timestamp,
128131
steps: [],
129-
duration: parseFloat(test.time) * 1000,
130-
status: test.failure ? "failed" : "passed",
132+
duration: parseFloat(test?.time) * 1000,
133+
status: hasFailure ? "failed" : "passed",
131134
stdout: test?.["system-out"] ? [test?.["system-out"]] : [],
132-
stderr: test.failure
133-
? [test.failure.message ?? test.failure._]
135+
stderr: hasFailure ? extractFailure(test?.failure) : [],
136+
errors: hasFailure
137+
? [
138+
mergeFailuresIntoMessage(
139+
extractFailure(test?.failure)
140+
) ?? {},
141+
]
134142
: [],
135-
errors: test.failure ? [test.failure] : [],
136-
error: test.failure ? test.failure : {},
143+
error: hasFailure
144+
? mergeFailuresIntoMessage(
145+
extractFailure(test?.failure)
146+
) ?? {}
147+
: {},
137148
},
138149
],
139150
};
@@ -155,3 +166,38 @@ fs.readFile(xmlFilePath, "utf-8", (err, data) => {
155166
}
156167
);
157168
});
169+
170+
function extractFailure(failure) {
171+
const failureArray = [];
172+
if (failure?.message) {
173+
failureArray.push(failure?.message);
174+
}
175+
if (failure?._) {
176+
failureArray.push(failure?._);
177+
}
178+
if (Array.isArray(failure)) {
179+
console.log("ENTER::");
180+
let failureItem;
181+
for (let i = 0; i < failure.length; i++) {
182+
if (typeof failure[i] === "object" && failure[i] !== null) {
183+
failureItem = failure[i];
184+
break;
185+
}
186+
}
187+
console.log("FAIL ITEM::", failureItem);
188+
return extractFailure(failureItem);
189+
}
190+
return failureArray;
191+
}
192+
193+
function mergeFailuresIntoMessage(failuresArray) {
194+
if (!failuresArray) {
195+
return;
196+
}
197+
if (failuresArray.length === 0) {
198+
return;
199+
}
200+
return {
201+
message: failuresArray.join(", "),
202+
};
203+
}

0 commit comments

Comments
 (0)
Please sign in to comment.