Skip to content

Commit

Permalink
Integrating playwright with azure devops test plan, updating test cas…
Browse files Browse the repository at this point in the history
…e outcome
  • Loading branch information
BakkappaN committed Aug 31, 2024
1 parent 74531e8 commit f12dccc
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 7 deletions.
58 changes: 58 additions & 0 deletions globals/global-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const XLSX = require('xlsx');
const fs = require('fs').promises;

async function globalSetup() {
console.log('Global setup is running...')
const filePath = process.env.TC_STATUS_PATH

if (process.env.UPDATE_TEST_PLAN == 'Yes' && process.env.PIPELINE == 'Yes') {
try {
// Check if the file exists
try {
await fs.access(filePath);
// File exists, delete it
await deleteFile(filePath);
} catch (err) {
if (err.code === 'ENOENT') {
// File does not exist, no need to delete
console.log(`File does not exist at ${filePath}`);
} else {
// Unexpected error
throw err;
}
}

// Create the Excel file
await createTCStatusFile(filePath);
} catch (err) {
console.error('An error occurred:', err);
}
} else {

}
}

async function createTCStatusFile(filePath) {
const workbook = XLSX.utils.book_new();
const headers = ['Test_Case_Id', 'Test_Case_Status', 'TC_Outcome_Updated'];
const worksheet = XLSX.utils.aoa_to_sheet([headers]);
XLSX.utils.book_append_sheet(workbook, worksheet, process.env.TC_STATUS_SHEET);
XLSX.writeFile(workbook, filePath);
console.log(`Generated new test case status file : ${filePath}`);
}

async function deleteFile(filePath) {
try {
await fs.unlink(filePath);
console.log(`File successfully deleted at ${filePath}`);
} catch (err) {
if (err.code === 'ENOENT') {
// File does not exist
console.log(`File does not exist at ${filePath}`);
} else {
// Unexpected error
console.error(`Error deleting file at ${filePath}:`, err);
}
}
}
export default globalSetup;
18 changes: 18 additions & 0 deletions globals/global-teardown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const XLSX = require('xlsx');
const path = require('path');

import AzureDevOps from '../utils/azuredevops';

async function globalTeardown() {
console.log('Global teardown is running...');
const azureDevOps = new AzureDevOps();
const filePath = process.env.TC_STATUS_PATH;
const sheetName = process.env.TC_STATUS_SHEET;

if (process.env.UPDATE_TEST_PLAN == 'Yes' && process.env.PIPELINE == 'Yes') {
await azureDevOps.updateTestCaseStatus(filePath,sheetName);
} else {

}
}
module.exports = globalTeardown;
20 changes: 13 additions & 7 deletions playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ module.exports = defineConfig({
timeout: 2 * 60 * 1000
},
testDir: './tests',
//testDir: './tests-e2e',

/* Run tests in files in parallel */
fullyParallel: false,
/* Fail the build on CI if you accidentally left test.only in the source code. */
Expand All @@ -23,11 +25,11 @@ module.exports = defineConfig({
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : 1,
// Reporter
reporter:[
reporter: [
['html'],
// ['allure-playwright'],
// ['allure-playwright'],
['junit', { outputFile: 'test-results/e2e-junit-results.xml' }],
],
],

use: {
/* Base URL to use in actions like `await page.goto('/')`. */
Expand All @@ -38,9 +40,9 @@ module.exports = defineConfig({
// },

// video, screenshot, headless mode
video:'off',
video: 'off',
screenshot: 'on',
headless : false,
headless: false,

// custom attribute
testIdAttribute: 'autocomplete',
Expand All @@ -49,6 +51,9 @@ module.exports = defineConfig({
trace: 'on',
},

globalSetup: require.resolve('./globals/global-setup'),
globalTeardown: require.resolve('./globals/global-teardown'),

/* Configure projects for major browsers */
projects: [
// {
Expand Down Expand Up @@ -83,8 +88,9 @@ module.exports = defineConfig({
// },
{
name: 'Google Chrome',
use: { ...devices['Desktop Chrome'], channel: 'chrome',
},
use: {
...devices['Desktop Chrome'], channel: 'chrome',
},
},
],

Expand Down
23 changes: 23 additions & 0 deletions tests/demo.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Include playwright module
const { test, expect } = require('@playwright/test');

import { writeTestStatusToExcelFile } from '../utils/excelhandler';

test.afterEach('Running after each test...', async ({ page }, testInfo) => {
if (process.env.UPDATE_TEST_PLAN == 'Yes' && process.env.PIPELINE == 'Yes') {
await writeTestStatusToExcelFile(testInfo);
} else {
}
});

test('[2] testcase1', async ({ page, request }) => {
console.log('test is running');
});

test('[9,12] testcase2 @test1', async ({ page }) => {
console.log('test is running');
});

test('[14] testcase3', async ({ page }) => {
expect(true).toBe(false);
});
97 changes: 97 additions & 0 deletions utils/azuredevops.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
const { request, expect } = require('@playwright/test');

const fs = require('fs');
const XLSX = require('xlsx');

import { readExcelFile } from '../utils/excelhandler';


let apiRequest;

// Initialize the API request object
(async () => {
apiRequest = await request.newContext();
})();

const credentials = Buffer.from(`${process.env.AZURE_DEVOPS_USER}:${process.env.AZURE_DEVOPS_PASS}`).toString('base64');

/**
* Bakkappa N
*/
class AzureDevOps {
constructor() {
}

async updateTestCaseStatus(filePath, sheetName) {

try {
const data = await readExcelFile(filePath, sheetName);

// Log the keys of the first row to check column names
if (data.length > 0) {
console.log('First row column headers:', Object.keys(data[0]));
} else {
console.error('No data found.');
return;
}

console.log(`Total no. of test cases : ${data.length}`);
console.log('Excel data converted into JSON : ' + JSON.stringify(data));

const testPlanId = process.env.TEST_PLAN_ID;
const testSuiteId = process.env.TEST_SUITE_ID;

for (let i = 0; i < data.length; i++) {
let row = data[i];
const testCaseId = row['Test_Case_Id'];
const testCaseStatus = row['Test_Case_Status'];
const testPointId = await this.getTestPoint(testPlanId, testSuiteId, testCaseId);
await this.updateTestPointStatus(testPlanId, testSuiteId, testPointId, testCaseStatus.charAt(0).toUpperCase() + testCaseStatus.slice(1));
console.log('row is : ' + row);
console.log(`Test Case ID - ${testCaseId} is : ${testCaseStatus}`);
}
} catch (error) {
console.error('Error in updating test case status:', error);
throw error; // Rethrow to indicate failure
}
}

async getTestPoint(testPlanId, testSuiteId, testCaseId) {
const values = [testPlanId, testSuiteId, testCaseId];
const URL = process.env.TEST_PLAN_GET_API.replace(/{(\d+)}/g, (match, number) => values[number] || match);

let getTestPointResponse = await apiRequest.get(URL, {
headers: {
"Content-Type": "application/json",
'Authorization': `Basic ${credentials}`
},
});

const jsonResponse = await getTestPointResponse.json();
expect(getTestPointResponse.ok()).toBeTruthy();
expect(getTestPointResponse.status()).toBe(200);
return jsonResponse.value[0].id;
}

async updateTestPointStatus(testPlanId, testSuiteId, testPointId, testCaseStatus) {
const values = [testPlanId, testSuiteId, testPointId];
const URL = process.env.TEST_PLAN_PATCH_API.replace(/{(\d+)}/g, (match, number) => values[number] || match);
const patchAPIResponse = await apiRequest.patch(URL, {
headers: {
"Content-Type": "application/json",
'Authorization': `Basic ${credentials}`
},
data: {
"outcome": testCaseStatus // Passed, Failed, Passed, Blocked,
},
});
expect(patchAPIResponse.ok()).toBeTruthy();
expect(patchAPIResponse.status()).toBe(200);
}
}

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

export default AzureDevOps;
46 changes: 46 additions & 0 deletions utils/excelhandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,49 @@ export async function printAllRowsData(filePath, sheet) {
// data[0].Skill1 - access using row & key
}

export async function readExcelFile(filePath, sheetName) {
// Read the Excel file
const workbook = xlsx.readFile(filePath);

// Get the first sheet
const sheet = workbook.Sheets[sheetName];

// Convert the sheet to JSON
const data = xlsx.utils.sheet_to_json(sheet, { header: 1 });

// If you want to access data as objects with column names as keys
const headers = data[0]; // Assumes the first row is the header row
const rows = data.slice(1).map(row => {
const rowData = {};
headers.forEach((header, index) => {
rowData[header] = row[index];
});
return rowData;
});
return rows;
}

export async function writeTestStatusToExcelFile(testInfo) {
const matches = testInfo.title.match(/\[(.*?)\]/);

if (matches) {
const numbersPart = matches[1];
const numbersArray = numbersPart.split(',').map(num => parseInt(num.trim(), 10));

numbersArray.forEach(number => {
const workbook = xlsx.readFile(process.env.TC_STATUS_PATH);
const worksheet = workbook.Sheets[process.env.TC_STATUS_SHEET];
const newRowData = [number, testInfo.status, ''];
const data = xlsx.utils.sheet_to_json(worksheet, { header: 1 });
data.push(newRowData);
const updatedWorksheet = xlsx.utils.aoa_to_sheet(data);
workbook.Sheets[process.env.TC_STATUS_SHEET] = updatedWorksheet;
xlsx.writeFile(workbook, process.env.TC_STATUS_PATH);
console.log(`1 Row of data added successfully to ${process.env.TC_STATUS_PATH}`);
});
} else {
console.log('No test case id found in title...');
}
}


0 comments on commit f12dccc

Please sign in to comment.