Skip to content

Commit bd6d71a

Browse files
AzureTestPlanTask: Implemented support for Jest (#20035)
* Added implementation for Jest * Added version * Added changes * Added chagnes for error handling --------- Co-authored-by: triptijain2112 <[email protected]>
1 parent fa06ce1 commit bd6d71a

19 files changed

+205
-37
lines changed
+44-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,52 @@
11
import tl = require('azure-pipelines-task-lib/task');
22
import utils = require('../utils');
33
import constants = require('../constants');
4+
import { executeJestCommand } from '../testLibExecutor';
45

6+
//Jest command like: >set JEST_JUNIT_OUTPUT_NAME=TEST-Jest0-junit.xml
7+
//>npx jest --ci --reporters=default --reporters=jest-junit -t "JestTestName"
58
export async function executeJestTests(testsToBeExecuted: string[]): Promise<number> {
69

7-
// jest execution will be added
8-
/*executable = npm
9-
args = test
10-
*/
10+
//Jest-Junit Link:https://github.com/jest-community/jest-junit
11+
let finalStatus = 0;
12+
let npmPath = tl.which("npm", true);
13+
try {
14+
await executeJestCommand(npmPath, constants.INSTALL_JESTJUNIT);
15+
} catch (error) {
16+
tl.error(`Error installing Jest-Junit: ${error}`);
17+
return 1;
18+
}
19+
//testToBeExecuted: <TestSuiteName1> <TestCase1>. <TestSuiteName1> <TestCase1>,<TestSuiteName2> <TestCase3>. <TestSuiteName2> <TestCase3>
20+
let npxPath = tl.which("npx", true);
21+
let i = 0;
22+
for (let tests of testsToBeExecuted) {
23+
const JestTestName = utils.separateJestTestName(tests);
24+
try {
25+
let junitFileName: string = `TEST-Jest${i}-junit.xml`;
26+
try {
27+
tl.setVariable('JEST_JUNIT_OUTPUT_NAME', junitFileName);
28+
let junitName = tl.getVariable('JEST_JUNIT_OUTPUT_NAME');
29+
if (junitName !== junitFileName) {
30+
throw new Error(`Retrieved JEST_JUNIT_OUTPUT_NAME (${junitName}) does not match the set value (${junitFileName})`);
31+
}
32+
tl.debug(`Junit Filename ${junitName} environment set and retrieved successfully.`);
33+
} catch (error) {
34+
tl.error(`Error setting or getting JEST_JUNIT_OUTPUT_NAME variable: ${error}`);
35+
finalStatus = 1;
36+
continue;
37+
}
1138

12-
console.log("jest changes1");
13-
return 1;
39+
const jestCommand = `jest --ci --reporters=default --reporters=jest-junit -t "${JestTestName}"`;
40+
const status = await executeJestCommand(npxPath, jestCommand);
41+
if (status != 0) {
42+
finalStatus = 1;
43+
}
44+
tl.debug(`Test case ${JestTestName} executed successfully.`);
45+
} catch (error) {
46+
tl.error(`Error executing ${JestTestName} test case: ${error}`);
47+
finalStatus = 1;
48+
}
49+
i++;
50+
}
51+
return finalStatus;
1452
}

Tasks/AzureTestPlanV0/constants.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export const MERGE_THRESHOLD = 100;
1212
export const AUTOMATED_EXECUTION = "AutomatedExecutionPhase";
1313
export const AUTOMATED_PUBLISHING = "PublishingAutomatedResultsPhase";
1414
export const MANUALTESTS_PUBLISHING = "ManualTestResultsPublishingPhase";
15-
export const INSTALL_GOTESTSUM = "install gotest.tools/gotestsum@latest";
15+
export const INSTALL_GOTESTSUM = "install gotest.tools/gotestsum@latest";
16+
export const INSTALL_JESTJUNIT = "i jest-junit";

Tasks/AzureTestPlanV0/task.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 241,
17-
"Patch": 6
17+
"Patch": 8
1818
},
1919
"preview": true,
2020
"demands": [],

Tasks/AzureTestPlanV0/task.loc.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 241,
17-
"Patch": 6
17+
"Patch": 8
1818
},
1919
"preview": true,
2020
"demands": [],

Tasks/AzureTestPlanV0/testLibExecutor.ts

+6
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,10 @@ export async function executeGoCommand(goPath: string, argument: string): Promis
164164
let go: tr.ToolRunner = tl.tool(goPath);
165165
go.line(argument);
166166
return await go.exec(<tr.IExecOptions>{ cwd: "" });
167+
}
168+
169+
export async function executeJestCommand(jestPath: string, argument: string): Promise<number> {
170+
let jest: tr.ToolRunner = tl.tool(jestPath);
171+
jest.line(argument);
172+
return await jest.exec(<tr.IExecOptions>{ cwd: "" });
167173
}

Tasks/AzureTestPlanV0/utils.ts

+11
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,15 @@ export function separateGoTestName(inputString) {
4242
// If there is no dot in the string, return the original string
4343
return inputString;
4444
}
45+
}
46+
47+
export function separateJestTestName(inputString) {
48+
const lastDotIndex = inputString.lastIndexOf('.');
49+
50+
if (lastDotIndex !== -1) {
51+
const testName = inputString.slice(lastDotIndex + 1);
52+
return testName;
53+
} else {
54+
return inputString;
55+
}
4556
}
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Default|0.241.6
2-
Node20-225|0.241.7
1+
Default|0.241.8
2+
Node20-225|0.241.9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,52 @@
11
import tl = require('azure-pipelines-task-lib/task');
22
import utils = require('../utils');
33
import constants = require('../constants');
4+
import { executeJestCommand } from '../testLibExecutor';
45

6+
//Jest command like: >set JEST_JUNIT_OUTPUT_NAME=TEST-Jest0-junit.xml
7+
//>npx jest --ci --reporters=default --reporters=jest-junit -t "JestTestName"
58
export async function executeJestTests(testsToBeExecuted: string[]): Promise<number> {
69

7-
// jest execution will be added
8-
/*executable = npm
9-
args = test
10-
*/
10+
//Jest-Junit Link:https://github.com/jest-community/jest-junit
11+
let finalStatus = 0;
12+
let npmPath = tl.which("npm", true);
13+
try {
14+
await executeJestCommand(npmPath, constants.INSTALL_JESTJUNIT);
15+
} catch (error) {
16+
tl.error(`Error installing Jest-Junit: ${error}`);
17+
return 1;
18+
}
19+
//testToBeExecuted: <TestSuiteName1> <TestCase1>. <TestSuiteName1> <TestCase1>,<TestSuiteName2> <TestCase3>. <TestSuiteName2> <TestCase3>
20+
let npxPath = tl.which("npx", true);
21+
let i = 0;
22+
for (let tests of testsToBeExecuted) {
23+
const JestTestName = utils.separateJestTestName(tests);
24+
try {
25+
let junitFileName: string = `TEST-Jest${i}-junit.xml`;
26+
try {
27+
tl.setVariable('JEST_JUNIT_OUTPUT_NAME', junitFileName);
28+
let junitName = tl.getVariable('JEST_JUNIT_OUTPUT_NAME');
29+
if (junitName !== junitFileName) {
30+
throw new Error(`Retrieved JEST_JUNIT_OUTPUT_NAME (${junitName}) does not match the set value (${junitFileName})`);
31+
}
32+
tl.debug(`Junit Filename ${junitName} environment set and retrieved successfully.`);
33+
} catch (error) {
34+
tl.error(`Error setting or getting JEST_JUNIT_OUTPUT_NAME variable: ${error}`);
35+
finalStatus = 1;
36+
continue;
37+
}
1138

12-
console.log("jest changes1");
13-
return 1;
39+
const jestCommand = `jest --ci --reporters=default --reporters=jest-junit -t "${JestTestName}"`;
40+
const status = await executeJestCommand(npxPath, jestCommand);
41+
if (status != 0) {
42+
finalStatus = 1;
43+
}
44+
tl.debug(`Test case ${JestTestName} executed successfully.`);
45+
} catch (error) {
46+
tl.error(`Error executing ${JestTestName} test case: ${error}`);
47+
finalStatus = 1;
48+
}
49+
i++;
50+
}
51+
return finalStatus;
1452
}

_generated/AzureTestPlanV0/constants.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export const MERGE_THRESHOLD = 100;
1212
export const AUTOMATED_EXECUTION = "AutomatedExecutionPhase";
1313
export const AUTOMATED_PUBLISHING = "PublishingAutomatedResultsPhase";
1414
export const MANUALTESTS_PUBLISHING = "ManualTestResultsPublishingPhase";
15-
export const INSTALL_GOTESTSUM = "install gotest.tools/gotestsum@latest";
15+
export const INSTALL_GOTESTSUM = "install gotest.tools/gotestsum@latest";
16+
export const INSTALL_JESTJUNIT = "i jest-junit";

_generated/AzureTestPlanV0/task.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 241,
17-
"Patch": 6
17+
"Patch": 8
1818
},
1919
"preview": true,
2020
"demands": [],
@@ -178,7 +178,7 @@
178178
"MultipleMatchingGradlewFound": "Multiple gradlew files found. Selecting the first matched instance"
179179
},
180180
"_buildConfigMapping": {
181-
"Default": "0.241.6",
182-
"Node20-225": "0.241.7"
181+
"Default": "0.241.8",
182+
"Node20-225": "0.241.9"
183183
}
184184
}

_generated/AzureTestPlanV0/task.loc.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 241,
17-
"Patch": 6
17+
"Patch": 8
1818
},
1919
"preview": true,
2020
"demands": [],
@@ -178,7 +178,7 @@
178178
"MultipleMatchingGradlewFound": "ms-resource:loc.messages.MultipleMatchingGradlewFound"
179179
},
180180
"_buildConfigMapping": {
181-
"Default": "0.241.6",
182-
"Node20-225": "0.241.7"
181+
"Default": "0.241.8",
182+
"Node20-225": "0.241.9"
183183
}
184184
}

_generated/AzureTestPlanV0/testLibExecutor.ts

+6
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,10 @@ export async function executeGoCommand(goPath: string, argument: string): Promis
164164
let go: tr.ToolRunner = tl.tool(goPath);
165165
go.line(argument);
166166
return await go.exec(<tr.IExecOptions>{ cwd: "" });
167+
}
168+
169+
export async function executeJestCommand(jestPath: string, argument: string): Promise<number> {
170+
let jest: tr.ToolRunner = tl.tool(jestPath);
171+
jest.line(argument);
172+
return await jest.exec(<tr.IExecOptions>{ cwd: "" });
167173
}

_generated/AzureTestPlanV0/utils.ts

+11
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,15 @@ export function separateGoTestName(inputString) {
4242
// If there is no dot in the string, return the original string
4343
return inputString;
4444
}
45+
}
46+
47+
export function separateJestTestName(inputString) {
48+
const lastDotIndex = inputString.lastIndexOf('.');
49+
50+
if (lastDotIndex !== -1) {
51+
const testName = inputString.slice(lastDotIndex + 1);
52+
return testName;
53+
} else {
54+
return inputString;
55+
}
4556
}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,52 @@
11
import tl = require('azure-pipelines-task-lib/task');
22
import utils = require('../utils');
33
import constants = require('../constants');
4+
import { executeJestCommand } from '../testLibExecutor';
45

6+
//Jest command like: >set JEST_JUNIT_OUTPUT_NAME=TEST-Jest0-junit.xml
7+
//>npx jest --ci --reporters=default --reporters=jest-junit -t "JestTestName"
58
export async function executeJestTests(testsToBeExecuted: string[]): Promise<number> {
69

7-
// jest execution will be added
8-
/*executable = npm
9-
args = test
10-
*/
10+
//Jest-Junit Link:https://github.com/jest-community/jest-junit
11+
let finalStatus = 0;
12+
let npmPath = tl.which("npm", true);
13+
try {
14+
await executeJestCommand(npmPath, constants.INSTALL_JESTJUNIT);
15+
} catch (error) {
16+
tl.error(`Error installing Jest-Junit: ${error}`);
17+
return 1;
18+
}
19+
//testToBeExecuted: <TestSuiteName1> <TestCase1>. <TestSuiteName1> <TestCase1>,<TestSuiteName2> <TestCase3>. <TestSuiteName2> <TestCase3>
20+
let npxPath = tl.which("npx", true);
21+
let i = 0;
22+
for (let tests of testsToBeExecuted) {
23+
const JestTestName = utils.separateJestTestName(tests);
24+
try {
25+
let junitFileName: string = `TEST-Jest${i}-junit.xml`;
26+
try {
27+
tl.setVariable('JEST_JUNIT_OUTPUT_NAME', junitFileName);
28+
let junitName = tl.getVariable('JEST_JUNIT_OUTPUT_NAME');
29+
if (junitName !== junitFileName) {
30+
throw new Error(`Retrieved JEST_JUNIT_OUTPUT_NAME (${junitName}) does not match the set value (${junitFileName})`);
31+
}
32+
tl.debug(`Junit Filename ${junitName} environment set and retrieved successfully.`);
33+
} catch (error) {
34+
tl.error(`Error setting or getting JEST_JUNIT_OUTPUT_NAME variable: ${error}`);
35+
finalStatus = 1;
36+
continue;
37+
}
1138

12-
console.log("jest changes1");
13-
return 1;
39+
const jestCommand = `jest --ci --reporters=default --reporters=jest-junit -t "${JestTestName}"`;
40+
const status = await executeJestCommand(npxPath, jestCommand);
41+
if (status != 0) {
42+
finalStatus = 1;
43+
}
44+
tl.debug(`Test case ${JestTestName} executed successfully.`);
45+
} catch (error) {
46+
tl.error(`Error executing ${JestTestName} test case: ${error}`);
47+
finalStatus = 1;
48+
}
49+
i++;
50+
}
51+
return finalStatus;
1452
}

_generated/AzureTestPlanV0_Node20/constants.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export const MERGE_THRESHOLD = 100;
1212
export const AUTOMATED_EXECUTION = "AutomatedExecutionPhase";
1313
export const AUTOMATED_PUBLISHING = "PublishingAutomatedResultsPhase";
1414
export const MANUALTESTS_PUBLISHING = "ManualTestResultsPublishingPhase";
15-
export const INSTALL_GOTESTSUM = "install gotest.tools/gotestsum@latest";
15+
export const INSTALL_GOTESTSUM = "install gotest.tools/gotestsum@latest";
16+
export const INSTALL_JESTJUNIT = "i jest-junit";

_generated/AzureTestPlanV0_Node20/task.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 241,
17-
"Patch": 7
17+
"Patch": 9
1818
},
1919
"preview": true,
2020
"demands": [],
@@ -182,7 +182,7 @@
182182
"MultipleMatchingGradlewFound": "Multiple gradlew files found. Selecting the first matched instance"
183183
},
184184
"_buildConfigMapping": {
185-
"Default": "0.241.6",
186-
"Node20-225": "0.241.7"
185+
"Default": "0.241.8",
186+
"Node20-225": "0.241.9"
187187
}
188188
}

_generated/AzureTestPlanV0_Node20/task.loc.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 241,
17-
"Patch": 7
17+
"Patch": 9
1818
},
1919
"preview": true,
2020
"demands": [],
@@ -182,7 +182,7 @@
182182
"MultipleMatchingGradlewFound": "ms-resource:loc.messages.MultipleMatchingGradlewFound"
183183
},
184184
"_buildConfigMapping": {
185-
"Default": "0.241.6",
186-
"Node20-225": "0.241.7"
185+
"Default": "0.241.8",
186+
"Node20-225": "0.241.9"
187187
}
188188
}

_generated/AzureTestPlanV0_Node20/testLibExecutor.ts

+6
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,10 @@ export async function executeGoCommand(goPath: string, argument: string): Promis
164164
let go: tr.ToolRunner = tl.tool(goPath);
165165
go.line(argument);
166166
return await go.exec(<tr.IExecOptions>{ cwd: "" });
167+
}
168+
169+
export async function executeJestCommand(jestPath: string, argument: string): Promise<number> {
170+
let jest: tr.ToolRunner = tl.tool(jestPath);
171+
jest.line(argument);
172+
return await jest.exec(<tr.IExecOptions>{ cwd: "" });
167173
}

_generated/AzureTestPlanV0_Node20/utils.ts

+11
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,15 @@ export function separateGoTestName(inputString) {
4242
// If there is no dot in the string, return the original string
4343
return inputString;
4444
}
45+
}
46+
47+
export function separateJestTestName(inputString) {
48+
const lastDotIndex = inputString.lastIndexOf('.');
49+
50+
if (lastDotIndex !== -1) {
51+
const testName = inputString.slice(lastDotIndex + 1);
52+
return testName;
53+
} else {
54+
return inputString;
55+
}
4556
}

0 commit comments

Comments
 (0)