tm-playwright-framework
Version:
Playwright Cucumber TS framework - The easiest way to learn
280 lines (279 loc) • 10.2 kB
JavaScript
/**
* PLAYWRIGHT-RUNNER.TS
*
* This TypeScript file instantiates all classes and provides access to their methods and members.
*
* @author Sasitharan, Govindharam
* @reviewer Sahoo, AshokKumar
* @version 1.0 - 1st-JUNE-2025
*
* @functions
* - `runScript`: Function to run a script and wait for it to complete.
* - `preScript`: Function tp run pre test to compile and build the script
* - `parseCommandLineArgs`: Parse and Validate the command line arguments passed
* - `runScriptsInOrder`: Executes scripts in a specific order.
* - `getBrowserVersion`: Get the version of currently executed browser
* - `postScript`: Function to run post to generate Multiple Cucumber Report
*/
import minimist from 'minimist';
import { spawn } from "child_process";
const args = minimist(process.argv.slice(2));
const additionalArgs = args;
const SUPPORTED_BROWSERS = ["chromium", "firefox", "webkit"];
let BROWSER_VERSION, EXEC_ENV, EXEC_REPORTER, EXEC_DIR, EXEC_BROWSER, EXEC_HEADLESS, RETRY_COUNT, TIME_OUT, REPEAT_EACH, script;
// Function to run a script and wait for it to complete
async function runScript(scriptName, envVars = {}) {
// Execute Script
return new Promise((resolve, reject) => {
const script = spawn(scriptName, [], {
env: { ...process.env, ...envVars },
shell: true,
});
// Output Listener
script.stdout.on("data", (data) => {
console.log(`stdout: ${data}`);
});
// Error Listener
script.stderr.on("data", (data) => {
console.error(`stderr: ${data}`);
});
// Execute when script completes
script.on("close", (code) => {
if (code !== 0) {
reject(`Error executing ${scriptName}, exited with code ${code}`);
}
else {
resolve("");
}
});
// Execute when script erred
script.on("error", (error) => {
reject(`Error executing ${scriptName}: ${error.message}`);
});
});
}
// Running Pre-Test
async function preScript() {
try {
console.log("Compiling TypeScript files...");
await runScript("npx tsc");
console.log("Compilation of TypeScript files is completed successfully");
console.log("npm run build");
await runScript("npm run build && cls");
console.log("Build step is completed successfully");
}
catch (error) {
console.log("Pre-test has been completed with the following error:");
console.error(error);
}
}
function removeProcessedArgs(key) {
delete additionalArgs[key];
}
async function parseCommandLineArgs() {
// Parsing command line arguments and validations
//script = `ENV=${args["ENV"]} `;
EXEC_ENV = `${args["ENV"]}`;
process.env.ENV = `${args["ENV"]}`;
removeProcessedArgs("ENV");
// Validating Test Directory argument
if (args["TEST_DIR"]) {
script += ` ${args["TEST_DIR"]} `;
EXEC_DIR = `${args["TEST_DIR"]} `;
removeProcessedArgs("TEST_DIR");
}
else {
console.log("Info: No Test Directory argument has been passed. Defaulted to run all tests under folder 'tests'");
script += ` tests/`;
EXEC_DIR = `tests/`;
}
// Validating Reporter argument
if (args["REPORTER"]) {
script += ` --reporter="${args["REPORTER"]}" `;
EXEC_REPORTER = `"${args["REPORTER"]}" `;
removeProcessedArgs("REPORTER");
}
else
console.log("Info: No Reporter argument has been passed.");
// Validating Time Out argument
if (args["TIME_OUT"]) {
script += ` --timeout="${args["TIME_OUT"]}" `;
TIME_OUT = `"${args["TIME_OUT"]}" `;
removeProcessedArgs("TIME_OUT");
}
else {
console.log("Info: No Time Out argument has been passed. Defaulted to 80000");
script += ' --timeout=80000 ';
TIME_OUT = `80000`;
}
// Validating Retry Count argument
if (args["RETRY_COUNT"]) {
process.env.RETRY_COUNT = `${args["RETRY_COUNT"]}`;
RETRY_COUNT = `"${args["RETRY_COUNT"]}" `;
removeProcessedArgs("RETRY_COUNT");
}
else {
console.log("Info: No Retry Count argument has been passed. Defaulted to 0");
process.env.RETRY_COUNT = `0`;
}
// Validating Repeat Each argument
if (args["REPEAT_EACH"]) {
script += ` --repeat-each="${args["REPEAT_EACH"]}" `;
process.env.REPEAT_EACH = `${args["REPEAT_EACH"]}`;
REPEAT_EACH = `"${args["REPEAT_EACH"]}" `;
removeProcessedArgs("REPEAT_EACH");
}
else {
console.log("Info: No Repeat Count argument has been passed. Defaulted to 1");
script += ' --repeat-each=1';
process.env.REPEAT_EACH = `1`;
}
// Validating Browser argument
if (args["BROWSER"]) {
if (!SUPPORTED_BROWSERS.includes(args["BROWSER"].toLowerCase())) {
console.warn(`Warning: The browser '${args["BROWSER"]}' is invalid. Defaulting to 'chrome'. Supported browsers are : ${SUPPORTED_BROWSERS}`);
//script += ` BROWSER=chromium `;
EXEC_BROWSER = "chromium";
process.env.BROWSER = "chromium";
removeProcessedArgs("BROWSER");
}
else {
//script += ` BROWSER=${args["BROWSER"].toLowerCase()} `;
process.env.BROWSER = `${args["BROWSER"].toLowerCase()}`;
EXEC_BROWSER = `${args["BROWSER"].toLowerCase()}`;
}
}
else {
console.log("Info: No BROWSER argument has been passed. Defaulted to run with Chrome");
process.env.BROWSER = 'chromium';
EXEC_BROWSER = "chromium";
}
// Validating Headless argument
if (args["HEADLESS"]) {
if (!["true", "false"].includes(args["HEADLESS"])) {
console.warn("Warning: Invalid value for HEADLESS. Defaulting to 'false'.");
EXEC_HEADLESS = "false";
}
else {
`${args["HEADLESS"] === "true" ? '' : script += ` --headed `}`;
EXEC_HEADLESS = false;
removeProcessedArgs("HEADLESS");
}
}
else {
console.log("Info: Invalid or no HEADLESS argument has been passed. Defaulted Headless as true");
EXEC_HEADLESS = "true";
}
// Validating Client argument
if (args["CLIENT"]) {
script += ` CLIENT=${args["CLIENT"]} `;
process.env.CLIENT = `${args["CLIENT"]}`;
removeProcessedArgs("CLIENT");
}
// Validating Report Path argument
if (args["REPORT_PATH"]) {
script += ` REPORT_PATH=${args["REPORT_PATH"].trim()} `;
process.env.REPORT_PATH = `${args["REPORT_PATH"].trim()}`;
removeProcessedArgs("REPORT_PATH");
}
else {
script += ` REPORT_PATH=playwright-test-results/`;
process.env.REPORT_PATH = `playwright-test-results/`;
}
// Validating Report Path argument
if (args["PARALLEL_WORKER"]) {
script += ` --workers=${args["PARALLEL_WORKER"]} `;
process.env.PARALLEL_WORKER = `${args["PARALLEL_WORKER"]}`;
removeProcessedArgs("PARALLEL_WORKER");
}
// Processing additional arguments
Object.entries(additionalArgs).forEach(([key, value]) => {
if (key != "_")
script += ` ${key}=${value} `;
});
return script;
}
// Execute scripts in a specific order
async function runScriptsInOrder() {
// Running Pre-Test
await preScript();
script = `npx cross-env playwright test `;
script = await parseCommandLineArgs();
await runScript("npx ts-node node_modules/tm-playwright-framework/dist/report/init.js");
// Running Test based on command line arguments passed
try {
console.log(script);
await runScript(script);
console.log("Test execution has been completed successfully");
}
catch (error) {
console.log("Test execution is completed with the following error:");
console.error(error);
}
// Running Post-Test
// await postScript(); -- Multiple Cucumber Report Generation is not possible with Playwright Json report
}
// Get browser version
// async function getBrowserVersion() {
// const BROWSER = await invokeBrowser(args["BROWSER"]);
// process.env.BROWSER = `${args["BROWSER"]}`;
// BROWSER_VERSION = BROWSER.version();
// console.log(BROWSER_VERSION);
// BROWSER.close();
// }
// Running Post-Test
async function postScript() {
// // Running Post-Test
try {
let script = `npx ts-node node_modules/tm-playwright-framework/dist/report/report.js ENV=${EXEC_ENV} `;
// if (EXEC_FEATURES) {
// script += ` FEATURES=${EXEC_FEATURES} `;
// } else {
// script += ` FEATURES=} `;
// }
// if (args["TAGS"]) {
// script += ` TAGS="${EXEC_TAGS}" `;
// } else {
// script += ` TAGS=`;
// }
if (args["BROWSER"]) {
script += ` BROWSER=${EXEC_BROWSER} `;
}
else
script += ` BROWSER=Chrome`;
if (args["HEADLESS"]) {
script += ` HEADLESS=${EXEC_HEADLESS} `;
}
else {
script += ` HEADLESS=false`;
}
if (BROWSER_VERSION) {
script += ` VERSION=${BROWSER_VERSION.split(".")[0]}`;
}
else {
script += ` VERSION= `;
}
if (args["CLIENT"]) {
script += ` CLIENT=${args["CLIENT"]} `;
}
if (args["REPORT_PATH"]) {
script += ` REPORT_PATH=${args["REPORT_PATH"]} `;
}
console.log(script);
await runScript(script);
console.log("Post-test execution has been completed successfully");
return;
}
catch (error) {
console.log("Post-test execution is completed with the following error:");
console.error(error);
return;
}
}
// Main method to Call internal method for execution of the test
if (args["ENV"]) {
runScriptsInOrder();
}
else {
throw new Error("ENV variable is required. Please set the 'ENV' environment variable.\n Syntax: npm run ccs_run_test -- --ENV=<ENV>");
}