Skip to content

Commit

Permalink
250 cli arguments are not working when a config file is used (#254)
Browse files Browse the repository at this point in the history
* fix: cli arguments in config

* chore: remove bullet point in failure and smart analysis

* chore: use failure analysis endpoint
  • Loading branch information
ASaiAnudeep authored Oct 19, 2024
1 parent 8ad86bf commit 5df0703
Show file tree
Hide file tree
Showing 14 changed files with 113 additions and 34 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "testbeats",
"version": "2.1.4",
"version": "2.1.5",
"description": "Publish test results to Microsoft Teams, Google Chat, Slack and InfluxDB",
"main": "src/index.js",
"types": "./src/index.d.ts",
Expand Down
14 changes: 14 additions & 0 deletions src/beats/beats.api.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ class BeatsApi {
}
});
}

/**
*
* @param {string} run_id
* @returns {import('./beats.types').IFailureAnalysisMetric[]}
*/
getFailureAnalysis(run_id) {
return request.get({
url: `${this.getBaseUrl()}/api/core/v1/test-runs/${run_id}/failure-analysis`,
headers: {
'x-api-key': this.config.api_key
}
});
}
}

module.exports = { BeatsApi }
3 changes: 2 additions & 1 deletion src/beats/beats.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,12 @@ class Beats {
try {
logger.info('🪄 Fetching Failure Analysis...');
await this.#setTestRun('Failure Analysis Status', 'failure_analysis_status');
const metrics = await this.api.getFailureAnalysis(this.test_run_id);
this.config.extensions.push({
name: 'failure-analysis',
hook: HOOK.AFTER_SUMMARY,
inputs: {
data: this.test_run
data: metrics
}
});
} catch (error) {
Expand Down
12 changes: 6 additions & 6 deletions src/beats/beats.types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ export type IBeatExecutionMetric = {
added: number
removed: number
flaky: number
product_bugs: number
environment_issues: number
automation_bugs: number
not_a_defects: number
to_investigate: number
auto_analysed: number
failure_summary: any
failure_summary_provider: any
failure_summary_model: any
Expand All @@ -38,3 +32,9 @@ export type IErrorCluster = {
failure: string
count: number
}

export type IFailureAnalysisMetric = {
id: string
name: string
count: number
}
11 changes: 10 additions & 1 deletion src/commands/publish.command.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const { MIN_NODE_VERSION } = require('../helpers/constants');
class PublishCommand {

/**
* @param {import('../index').PublishOptions} opts
* @param {import('../index').CommandLineOptions} opts
*/
constructor(opts) {
this.opts = opts;
Expand All @@ -28,6 +28,7 @@ class PublishCommand {
this.#buildConfig();
this.#validateOptions();
this.#setConfigFromFile();
this.#mergeConfigOptions();
this.#processConfig();
this.#validateConfig();
this.#processResults();
Expand Down Expand Up @@ -76,6 +77,14 @@ class PublishCommand {
}
}

#mergeConfigOptions() {
if (this.opts.config && typeof this.opts.config === 'object') {
this.opts.config.project = this.opts.project || this.opts.config.project;
this.opts.config.run = this.opts.run || this.opts.config.run;
this.opts.config.api_key = this.opts['api-key'] || this.opts.config.api_key;
}
}

#processConfig() {
const processed_config = processData(this.opts.config);
/**@type {import('../index').PublishConfig[]} */
Expand Down
31 changes: 16 additions & 15 deletions src/extensions/failure-analysis.extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,32 @@ class FailureAnalysisExtension extends BaseExtension {
}

#setText() {
const data = this.extension.inputs.data;
if (!data) {
return;
}

/**
* @type {import('../beats/beats.types').IBeatExecutionMetric}
* @type {import('../beats/beats.types').IFailureAnalysisMetric[]}
*/
const execution_metrics = data.execution_metrics[0];

if (!execution_metrics) {
logger.warn('⚠️ No execution metrics found. Skipping.');
const metrics = this.extension.inputs.data;
if (!metrics || metrics.length === 0) {
logger.warn('⚠️ No failure analysis metrics found. Skipping.');
return;
}

const to_investigate = metrics.find(metric => metric.name === 'To Investigate');
const auto_analysed = metrics.find(metric => metric.name === 'Auto Analysed');

const failure_analysis = [];

if (execution_metrics.to_investigate) {
failure_analysis.push(`🔎 To Investigate: ${execution_metrics.to_investigate}`);
if (to_investigate && to_investigate.count > 0) {
failure_analysis.push(`🔎 To Investigate: ${to_investigate.count}`);
}
if (auto_analysed && auto_analysed.count > 0) {
failure_analysis.push(`🪄 Auto Analysed: ${auto_analysed.count}`);
}
if (execution_metrics.auto_analysed) {
failure_analysis.push(`🪄 Auto Analysed: ${execution_metrics.auto_analysed}`);

if (failure_analysis.length === 0) {
return;
}

this.text = failure_analysis.join('    ');
this.text = failure_analysis.join('    ');
}

}
Expand Down
4 changes: 2 additions & 2 deletions src/extensions/smart-analysis.extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ class SmartAnalysisExtension extends BaseExtension {
for (const item of smart_analysis) {
rows.push(item);
if (rows.length === 3) {
texts.push(rows.join('    '));
texts.push(rows.join('    '));
rows.length = 0;
}
}

if (rows.length > 0) {
texts.push(rows.join('    '));
texts.push(rows.join('    '));
}

this.text = this.mergeTexts(texts);
Expand Down
2 changes: 1 addition & 1 deletion src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ export interface PublishOptions {
}

export interface CommandLineOptions {
config?: string;
config?: string | PublishConfig;
project?: string;
run?: string;
'api-key'?: string;
Expand Down
4 changes: 3 additions & 1 deletion test/beats.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ describe('TestBeats', () => {
const id1 = mock.addInteraction('post test results to beats');
const id2 = mock.addInteraction('get test results with failure analysis from beats');
const id3 = mock.addInteraction('get empty error clusters from beats');
const id4 = mock.addInteraction('post test-summary with beats to teams with ai failure summary and smart analysis and failure analysis');
const id4 = mock.addInteraction('get failure analysis from beats');
const id5 = mock.addInteraction('post test-summary with beats to teams with ai failure summary and smart analysis and failure analysis');
await publish({
config: {
api_key: 'api-key',
Expand Down Expand Up @@ -262,6 +263,7 @@ describe('TestBeats', () => {
assert.equal(mock.getInteraction(id2).exercised, true);
assert.equal(mock.getInteraction(id3).exercised, true);
assert.equal(mock.getInteraction(id4).exercised, true);
assert.equal(mock.getInteraction(id5).exercised, true);
});

});
12 changes: 12 additions & 0 deletions test/cli.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,16 @@ describe('CLI', () => {
});
});

it('publish results with config file and cli options', (done) => {
mock.addInteraction('post test results to beats');
mock.addInteraction('get test results from beats');
mock.addInteraction('post test-summary with beats to teams');
exec('node src/cli.js publish --api-key api-key --project project-name --run build-name --config test/data/configs/teams.config.json', (error, stdout, stderr) => {
console.log(stdout);
assert.match(stdout, /🚀 Publishing results to TestBeats Portal/);
assert.match(stdout, /✅ Results published successfully!/);
done();
});
});

});;
18 changes: 18 additions & 0 deletions test/data/configs/teams.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"targets": [
{
"name": "teams",
"inputs": {
"url": "http://localhost:9393/message"
}
}
],
"results": [
{
"type": "testng",
"files": [
"test/data/testng/single-suite.xml"
]
}
]
}
24 changes: 23 additions & 1 deletion test/mocks/beats.mock.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const { addInteractionHandler } = require('pactum').handler;
const { like, includes } = require('pactum-matchers');

addInteractionHandler('post test results to beats', () => {
return {
Expand Down Expand Up @@ -155,6 +154,29 @@ addInteractionHandler('get empty error clusters from beats', () => {
}
});

addInteractionHandler('get failure analysis from beats', () => {
return {
strict: false,
request: {
method: 'GET',
path: '/api/core/v1/test-runs/test-run-id/failure-analysis'
},
response: {
status: 200,
body: [
{
name: 'To Investigate',
count: 1
},
{
name: 'Auto Analysed',
count: 1
}
]
}
}
});

addInteractionHandler('upload attachments', () => {
return {
strict: false,
Expand Down
6 changes: 3 additions & 3 deletions test/mocks/teams.mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -1644,7 +1644,7 @@ addInteractionHandler('post test-summary with beats to teams with ai failure sum
},
{
"type": "TextBlock",
"text": "⭕ Newly Failed: 1    🔴 Always Failing: 1    🟡 Flaky: 1\n\n🟢 Recovered: 1",
"text": "⭕ Newly Failed: 1    🔴 Always Failing: 1    🟡 Flaky: 1\n\n🟢 Recovered: 1",
"wrap": true,
"separator": true,
}
Expand Down Expand Up @@ -1688,13 +1688,13 @@ addInteractionHandler('post test-summary with beats to teams with ai failure sum
},
{
"type": "TextBlock",
"text": "🔎 To Investigate: 1    🪄 Auto Analysed: 1",
"text": "🔎 To Investigate: 1    🪄 Auto Analysed: 1",
"wrap": true,
"separator": true,
},
{
"type": "TextBlock",
"text": "⭕ Newly Failed: 1    🔴 Always Failing: 1    🟡 Flaky: 1\n\n🟢 Recovered: 1",
"text": "⭕ Newly Failed: 1    🔴 Always Failing: 1    🟡 Flaky: 1\n\n🟢 Recovered: 1",
"wrap": true,
"separator": true,
}
Expand Down

0 comments on commit 5df0703

Please sign in to comment.