Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

ctrf

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ctrf - npm Package Compare versions

Comparing version
0.0.6
to
0.0.7
+1
dist/flaky.d.ts
export declare function identifyFlakyTests(filePath: string): Promise<void>;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.identifyFlakyTests = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
function identifyFlakyTests(filePath) {
return __awaiter(this, void 0, void 0, function* () {
try {
const resolvedFilePath = path_1.default.resolve(filePath);
if (!fs_1.default.existsSync(resolvedFilePath)) {
console.error(`The file ${resolvedFilePath} does not exist.`);
return;
}
const fileContent = fs_1.default.readFileSync(resolvedFilePath, 'utf8');
const report = JSON.parse(fileContent);
const flakyTests = report.results.tests.filter((test) => test.flaky === true);
if (flakyTests.length > 0) {
console.log(`Found ${flakyTests.length} flaky test(s):`);
flakyTests.forEach((test) => {
console.log(`- Test Name: ${test.name}, Retries: ${test.retries}`);
});
}
else {
console.log(`No flaky tests found in ${resolvedFilePath}.`);
}
}
catch (error) {
console.error('Error identifying flaky tests:', error);
}
});
}
exports.identifyFlakyTests = identifyFlakyTests;
export declare function mergeReports(directory: string, output: string, outputDir: string, keepReports: boolean): Promise<void>;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeReports = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
function mergeReports(directory, output, outputDir, keepReports) {
return __awaiter(this, void 0, void 0, function* () {
try {
const directoryPath = path_1.default.resolve(directory);
const outputFileName = output;
const resolvedOutputDir = outputDir ? path_1.default.resolve(outputDir) : directoryPath;
const outputPath = path_1.default.join(resolvedOutputDir, outputFileName);
console.log("Merging CTRF reports...");
const files = fs_1.default.readdirSync(directoryPath);
files.forEach((file) => {
console.log('Found CTRF report file:', file);
});
const ctrfReportFiles = files.filter((file) => {
try {
const filePath = path_1.default.join(directoryPath, file);
const fileContent = fs_1.default.readFileSync(filePath, 'utf8');
const jsonData = JSON.parse(fileContent);
return jsonData.hasOwnProperty('results');
}
catch (error) {
console.error(`Error reading JSON file '${file}':`, error);
return false;
}
});
if (ctrfReportFiles.length === 0) {
console.log('No CTRF reports found in the specified directory.');
return;
}
if (!fs_1.default.existsSync(resolvedOutputDir)) {
fs_1.default.mkdirSync(resolvedOutputDir, { recursive: true });
console.log(`Created output directory: ${resolvedOutputDir}`);
}
const mergedReport = ctrfReportFiles
.map((file) => {
console.log("Merging report:", file);
const filePath = path_1.default.join(directoryPath, file);
const fileContent = fs_1.default.readFileSync(filePath, 'utf8');
return JSON.parse(fileContent);
})
.reduce((acc, curr) => {
if (!acc.results) {
return curr;
}
acc.results.summary.tests += curr.results.summary.tests;
acc.results.summary.passed += curr.results.summary.passed;
acc.results.summary.failed += curr.results.summary.failed;
acc.results.summary.skipped += curr.results.summary.skipped;
acc.results.summary.pending += curr.results.summary.pending;
acc.results.summary.other += curr.results.summary.other;
acc.results.tests.push(...curr.results.tests);
acc.results.summary.start = Math.min(acc.results.summary.start, curr.results.summary.start);
acc.results.summary.stop = Math.max(acc.results.summary.stop, curr.results.summary.stop);
return acc;
}, { results: null });
fs_1.default.writeFileSync(outputPath, JSON.stringify(mergedReport, null, 2));
if (!keepReports) {
ctrfReportFiles.forEach((file) => {
const filePath = path_1.default.join(directoryPath, file);
if (file !== outputFileName) {
fs_1.default.unlinkSync(filePath);
}
});
}
console.log('CTRF reports merged successfully.');
console.log(`Merged report saved to: ${outputPath}`);
}
catch (error) {
console.error('Error merging CTRF reports:', error);
}
});
}
exports.mergeReports = mergeReports;
+1
-1

@@ -1,2 +0,2 @@

#!/usr/bin/env node
#!/usr/bin/env ts-node
export {};

@@ -1,2 +0,2 @@

#!/usr/bin/env node
#!/usr/bin/env ts-node
"use strict";

@@ -16,6 +16,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const yargs_1 = __importDefault(require("yargs/yargs"));
const helpers_1 = require("yargs/helpers");
const merge_1 = require("./merge");
const flaky_1 = require("./flaky");
const argv = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))

@@ -47,76 +47,16 @@ .command('merge <directory>', 'Merge CTRF reports into a single report', (yargs) => {

}, (argv) => __awaiter(void 0, void 0, void 0, function* () {
try {
if (!argv.directory) {
throw new Error('The "directory" argument is required.');
}
const directoryPath = path_1.default.resolve(argv.directory);
const outputFileName = argv.output;
const outputDir = argv['output-dir'] ? path_1.default.resolve(argv['output-dir']) : directoryPath;
const keepReports = argv['keep-reports'];
const outputPath = path_1.default.join(outputDir, outputFileName);
console.log("Merging CTRF reports...");
const files = fs_1.default.readdirSync(directoryPath);
files.forEach((file) => {
console.log('Found CTRF report file:', file);
});
const ctrfReportFiles = files.filter((file) => {
try {
const filePath = path_1.default.join(directoryPath, file);
const fileContent = fs_1.default.readFileSync(filePath, 'utf8');
const jsonData = JSON.parse(fileContent);
return jsonData.hasOwnProperty('results');
}
catch (error) {
console.error(`Error reading JSON file '${file}':`, error);
return false;
}
});
if (ctrfReportFiles.length === 0) {
console.log('No CTRF reports found in the specified directory.');
return;
}
if (!fs_1.default.existsSync(outputDir)) {
fs_1.default.mkdirSync(outputDir, { recursive: true });
console.log(`Created output directory: ${outputDir}`);
}
const mergedReport = ctrfReportFiles
.map((file) => {
console.log("Merging report:", file);
const filePath = path_1.default.join(directoryPath, file);
const fileContent = fs_1.default.readFileSync(filePath, 'utf8');
return JSON.parse(fileContent);
})
.reduce((acc, curr) => {
if (!acc.results) {
return curr;
}
acc.results.summary.tests += curr.results.summary.tests;
acc.results.summary.passed += curr.results.summary.passed;
acc.results.summary.failed += curr.results.summary.failed;
acc.results.summary.skipped += curr.results.summary.skipped;
acc.results.summary.pending += curr.results.summary.pending;
acc.results.summary.other += curr.results.summary.other;
acc.results.tests.push(...curr.results.tests);
acc.results.summary.start = Math.min(acc.results.summary.start, curr.results.summary.start);
acc.results.summary.stop = Math.max(acc.results.summary.stop, curr.results.summary.stop);
return acc;
}, { results: null });
fs_1.default.writeFileSync(outputPath, JSON.stringify(mergedReport, null, 2));
if (!keepReports) {
ctrfReportFiles.forEach((file) => {
const filePath = path_1.default.join(directoryPath, file);
if (file !== outputFileName) {
fs_1.default.unlinkSync(filePath);
}
});
}
console.log('CTRF reports merged successfully.');
console.log(`Merged report saved to: ${outputPath}`);
}
catch (error) {
console.error('Error merging CTRF reports:', error);
}
yield (0, merge_1.mergeReports)(argv.directory, argv.output, argv['output-dir'], argv['keep-reports']);
}))
.command('flaky <file>', 'Identify flaky tests from a CTRF report file', (yargs) => {
return yargs
.positional('file', {
describe: 'CTRF report file',
type: 'string',
demandOption: true,
});
}, (argv) => __awaiter(void 0, void 0, void 0, function* () {
yield (0, flaky_1.identifyFlakyTests)(argv.file);
}))
.help()
.demandCommand(1, 'You need at least one command before moving on')
.argv;
{
"name": "ctrf",
"version": "0.0.6",
"version": "0.0.7",
"description": "",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -32,3 +32,5 @@ # CTRF CLI

| `merge` | Merge multiple CTRF reports into a single report. |
| `flaky` | Output flaky test name and retries. |
## Merge

@@ -46,3 +48,3 @@

## Options
### Options

@@ -67,10 +69,25 @@ -o, --output `filename`: Output file name for the merged report. Default is ctrf-report.json.

## Example
## Flaky
Merge all CTRF reports in the ctrf directory into a single report named merged-report.json and save it in the output directory, keeping the original reports:
The flaky command is useful for identifying tests marked as flaky in your CTRF report. Flaky tests are tests that pass or fail inconsistently and may require special attention or retries to determine their reliability.
Usage
To output flaky tests, use the following command:
```sh
npx ctrf merge ctrf --output merged-report.json --output-dir output --keep-reports
npx ctrf flaky <file-path>
```
Replace <file-path> with the path to the CTRF report file you want to analyze.
### Output
The command will output the names of the flaky tests and the number of retries each test has undergone. For example:
```zsh
Processing report: reports/sample-report.json
Found 1 flaky test(s) in reports/sample-report.json:
- Test Name: Test 1, Retries: 2
```
## What is CTRF?

@@ -77,0 +94,0 @@