feat: Add end-to-end tests for collection run reports (#5562)

* feat: Add end-to-end tests for collection run reports
This commit is contained in:
Sanjai Kumar
2025-09-18 15:20:28 +05:30
committed by GitHub
parent f3d4ac84d8
commit 4321846dbd
7 changed files with 216 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
import { test, expect } from '../../../playwright';
import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
function normalizeJunitReport(xmlContent: string): string {
return xmlContent
// Replace timestamps with fixed value
.replace(/timestamp="[^"]*"/g, 'timestamp="2024-01-01T00:00:00.000"')
// Replace hostnames with fixed value
.replace(/hostname="[^"]*"/g, 'hostname="test-host"')
// Replace execution times with fixed value
.replace(/time="[^"]*"/g, 'time="0.100"')
// Replace file paths with normalized path
.replace(/name="[^"]*\/[^"]*"/g, 'name="/test/path/collection"');
}
test.describe('Collection Run Report Tests', () => {
const collectionPath = path.join(__dirname, 'collection');
test('CLI: Run collection and generate JUnit report', async ({ createTmpDir }) => {
const outputDir = await createTmpDir('junit-report');
const junitOutputPath = path.join(outputDir, 'cli-report.xml');
// Run collection via CLI with JUnit reporter
const command = `cd "${collectionPath}" && node ../../../../packages/bruno-cli/bin/bru.js run --reporter-junit "${junitOutputPath}"`;
try {
execSync(command, { stdio: 'pipe' });
} catch (error) {
// CLI may exit with non-zero code if tests fail, which is expected
console.log('CLI execution completed with exit code:', error.status);
}
// Verify report was generated
expect(fs.existsSync(junitOutputPath)).toBe(true);
const junitReportContent = fs.readFileSync(junitOutputPath, 'utf8');
// Snapshot the normalized XML
const normalizedJunitReport = normalizeJunitReport(junitReportContent);
expect(normalizedJunitReport).toMatchSnapshot('cli-junit-report.xml');
});
});

View File

@@ -0,0 +1,29 @@
<?xml version="1.0"?>
<testsuites>
<testsuite name="/test/path/collection" errors="0" failures="0" skipped="0" tests="4" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response has slideshow property" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Slideshow has title" status="pass" classname="/test/path/collection" time="0.100"/>
</testsuite>
<testsuite name="/test/path/collection" errors="0" failures="1" skipped="0" tests="5" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
<testcase name="This test will fail" status="fail" classname="/test/path/collection" time="0.100">
<failure type="failure" message="expected 200 to equal 404"/>
</testcase>
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response has uuid property" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="UUID is a string" status="pass" classname="/test/path/collection" time="0.100"/>
</testsuite>
<testsuite name="/test/path/collection" errors="0" failures="0" skipped="0" tests="3" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response has json field" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response json has username" status="pass" classname="/test/path/collection" time="0.100"/>
</testsuite>
<testsuite name="/test/path/collection" errors="0" failures="1" skipped="0" tests="2" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
<testcase name="This test will also fail" status="fail" classname="/test/path/collection" time="0.100">
<failure type="failure" message="expected 200 to equal 500"/>
</testcase>
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
</testsuite>
</testsuites>

View File

@@ -0,0 +1,38 @@
meta {
name: Get UUID
type: http
seq: 2
}
get {
url: https://httpbin.org/uuid
body: none
auth: none
}
headers {
Accept: application/json
}
tests {
test("This test will fail", function() {
expect(res.getStatus()).to.equal(404); // Intentional failure
});
test("Status code is 200", function() {
expect(res.getStatus()).to.equal(200);
});
test("Response is an object", function() {
expect(res.getBody()).to.be.an('object');
});
test("Response has uuid property", function() {
expect(res.getBody()).to.have.property('uuid');
});
test("UUID is a string", function() {
const body = res.getBody();
expect(body.uuid).to.be.a('string');
});
}

View File

@@ -0,0 +1,34 @@
meta {
name: Get User Info
type: http
seq: 1
}
get {
url: https://httpbin.org/json
body: none
auth: none
}
headers {
Accept: application/json
}
tests {
test("Status code is 200", function() {
expect(res.getStatus()).to.equal(200);
});
test("Response is an object", function() {
expect(res.getBody()).to.be.an('object');
});
test("Response has slideshow property", function() {
expect(res.getBody()).to.have.property('slideshow');
});
test("Slideshow has title", function() {
const body = res.getBody();
expect(body.slideshow).to.have.property('title');
});
}

View File

@@ -0,0 +1,38 @@
meta {
name: Login Request
type: http
seq: 3
}
post {
url: https://httpbin.org/post
body: json
auth: none
}
headers {
Content-Type: application/json
}
body:json {
{
"username": "testuser",
"password": "testpass"
}
}
tests {
test("Status code is 200", function() {
expect(res.getStatus()).to.equal(200);
});
test("Response has json field", function() {
const response = res.getBody();
expect(response).to.have.property('json');
});
test("Response json has username", function() {
const response = res.getBody();
expect(response.json).to.have.property('username');
});
}

View File

@@ -0,0 +1,25 @@
meta {
name: Logout Request
type: http
seq: 4
}
delete {
url: https://httpbin.org/delete
body: none
auth: none
}
headers {
Accept: application/json
}
tests {
test("This test will also fail", function() {
expect(res.getStatus()).to.equal(500); // Intentional failure
});
test("Status code is 200", function() {
expect(res.getStatus()).to.equal(200);
});
}

View File

@@ -0,0 +1,9 @@
{
"version": "1",
"name": "Report Test Collection",
"type": "collection",
"ignore": [
"node_modules",
".git"
]
}