I have set up a feature file along with its corresponding step definitions. The tests are running successfully, and I am able to generate a test-result.xml file.(Using Playwright + type script with cucumber)
Now, I’m trying to push the test results from my local environment to an Azure DevOps Test Plan that I’ve created (Test Plan ID: 341345 – dummy number).
Here’s what I’ve done so far:
Generated a Personal Access Token (PAT) in Azure DevOps with full permissions.
checked the company and project both are correct
Feature file
@341472 ----(Test case id in azure devops)
Scenario: @341472 Validate log in the user module
When End User navigates to user module and checks Subsection presence
Then End User add a log in release log under user and checks Whether the added data reflects in about module
And End User deletes the record in log and check the presence in user module
test-result after running the code by “@cucumber/pretty-formatter”
<?xml version="1.0"?>
<testsuite name="Cucumber" time="151.271" tests="1" skipped="0" failures="0" errors="0" timestamp="2025-05-11T14:37:06.272Z">
<testcase classname="regression in user module" name="@341472 Validate log in the user module" time="136.713">
<system-out><![CDATA[When End User navigates to user module and checks Subsection presence......................passed
When End User navigates to user module and checks Subsection presence.............................passed
Then End User add a log in release log under user and checks Whether the added data reflects in about module......passed
And End User deletes the record in log and check the presence in user module..passed]]></system-out>
</testcase>
</testsuite>
Created a upload-result.js script to upload the test results.
const fs = require('fs');
const xml2js = require('xml2js');
const axios = require('axios');
const xmlPath = 'test-results.xml'; // Path to your test results XML file
const testPlanId = '341345'; // Dummy number
const suiteId = '341456'; // dummy
const organization ='companyA'; //Dummy company
const project ='ProjectB'; // Dummy project
const pat = process.env.AZURE_DEVOPS_EXT_PAT; // Ensure this is set in your environment
if (!pat) {
throw new Error('AZURE_DEVOPS_EXT_PAT is not set in environment variables');
}
const apiVersion = '7.1-preview.6';
const baseUrl = `https://dev.azure.com/${organization}/${project}/_apis/test`;
const authHeader = {
headers: {
Authorization: `Basic ${Buffer.from(':' + pat).toString('base64')}`,
'Content-Type': 'application/json'
}
};
async function parseResults() {
console.log('Starting to parse the XML file...');
const xml = fs.readFileSync(xmlPath, 'utf8');
const result = await xml2js.parseStringPromise(xml);
console.log('Successfully parsed XML file...');
const testCases = result.testsuite.testcase;
if (!testCases) throw new Error('No test cases found in XML');
return testCases.map(tc => {
const name = tc.$.name;
const classname = tc.$.classname;
const outcome = tc.failure ? 'Failed' : 'Passed';
const durationInMs = parseFloat(tc.$.time) * 1000;
// Extract tag like @TC1234 to map to Azure DevOps test case
const tagMatch = name.match(/@(d+)/);
const automatedTestName = tagMatch ? tagMatch[1] : null;
if (!automatedTestName) {
console.warn(`No @xxxx tag found in "${name}". Test case will be skipped.`);
return null; // skip test cases without a valid tag
}
return {
automatedTestName: automatedTestName,
outcome,
automatedTestType: 'Cucumber',
durationInMs,
testCaseTitle: `${classname} - ${name}`
};
}).filter(Boolean); // remove any null entries
}
async function uploadToAzureDevOps() {
console.log('Starting the upload process...');
const results = await parseResults();
try {
const createRunUrl = `${baseUrl}/runs?api-version=${apiVersion}`;
console.log('Making a POST request to create a test run...');
console.log('Create Run URL:', createRunUrl);
const runPayload = {
name: 'Automated Test Run',
plan: { id: testPlanId },
automated: true,
state: 'InProgress'
};
console.log('Payload for creating test run:', JSON.stringify(runPayload, null, 2));
const runResponse = await axios.post(createRunUrl, runPayload, authHeader);
if (!runResponse || !runResponse.data || !runResponse.data.id) {
throw new Error(`No testRunId returned. Response: ${JSON.stringify(runResponse.data)}`);
}
const testRunId = runResponse.data.id;
console.log(`Created test run with ID: ${testRunId}`);
const resultsUrl = `${baseUrl}/runs/${testRunId}/results?api-version=${apiVersion}`;
console.log('Uploading test results to:', resultsUrl);
await axios.post(resultsUrl, results, authHeader);
console.log('Uploaded test results');
const completeUrl = `${baseUrl}/runs/${testRunId}?api-version=${apiVersion}`;
console.log('Marking test run as completed at:', completeUrl);
await axios.patch(completeUrl, { state: 'Completed' }, authHeader);
console.log('Marked test run as completed');
} catch (err) {
console.error('Error uploading test results:', err.message);
if (err.response) {
console.error('Response data:', JSON.stringify(err.response.data, null, 2));
}
}
}
// Execute the upload
uploadToAzureDevOps();
However, when I run the command node src/upload-result.js, I encounter an error in console when trying to upload the result.Please note i have added console.log to get the where error is happening so that why any to see the messages
Making a POST request to create a test run...
Create Run URL: https://dev.azure.com/companyA/ProjectB/_apis/test/runs?api-version=7.1-preview.6
Payload for creating test run: {
"name": "Automated Test Run",
"plan": {
"id": "341345"
},
"automated": true,
"state": "InProgress"
}
Error uploading test results: Request failed with status code 404
Response data: "Page not found"
Any help is much appreciated .if any additional details are required, please ask away. This is the first time trying this