tm-playwright-framework
Version:
Playwright Cucumber TS framework - The easiest way to learn
268 lines (267 loc) • 9.79 kB
JavaScript
/**
* CUCUMBER-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";
import { invokeBrowser } from "tm-playwright-framework/dist/browser/browserManager.js";
import fs from "fs-extra";
const args = minimist(process.argv.slice(2));
const additionalArgs = args;
const SUPPORTED_BROWSERS = ["chrome", "firefox", "webkit"];
let BROWSER_VERSION, EXEC_ENV, EXEC_TAGS, EXEC_FEATURES, EXEC_BROWSER, EXEC_HEADLESS, script;
// Function to run a script and wait for it to complete
async function runScript(scriptName, envVars = {}) {
// Execute Script
process.env.CUCUMBER_TEST = "true";
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}`);
});
});
return;
}
// Running Pre-Test
async function preScript() {
try {
console.log("npx tsc");
await runScript("npx tsc");
console.log("Build step is completed successfully");
await runScript("npx ts-node node_modules/tm-playwright-framework/dist/report/init.js");
console.log("Pre-test has been completed successfully");
}
catch (error) {
console.log("Pre-test has been completed with the following error:");
console.error(error);
}
return;
}
function removeProcessedArgs(key) {
delete additionalArgs[key];
}
export async function parseCommandLineArgs() {
// Parsing command line arguments and validations
script = `ENV=${args["ENV"]} `;
EXEC_ENV = `${args["ENV"]}`;
removeProcessedArgs("ENV");
// Validating Features argument
let featurePath = args["FEATURES"];
if (featurePath) {
// Check if the provided directory exists within the project folder
if (fs.existsSync(featurePath)) {
// If the directory exists, use it
script += ` FEATURES=${featurePath} `;
EXEC_FEATURES = `${featurePath} `;
console.log(`Info: Using features from directory '${featurePath}'.`);
}
else {
// If the directory doesn't exist or is not a directory
console.error(`Error: The directory '${featurePath}' does not exist or is not a valid directory.`);
process.exit(1); // Exit with an error code
}
}
else {
// Default behavior if FEATURES argument isn't provided
const defaultPath = "app/test/features/";
console.log(`Info: No FEATURES argument has been passed. Defaulted to run all features under folder '${defaultPath}'`);
// Validate default directory exists
if (fs.existsSync(defaultPath) && fs.lstatSync(defaultPath).isDirectory()) {
script += ` FEATURES=${defaultPath} `;
EXEC_FEATURES = `${defaultPath}`;
}
else {
// If the default directory doesn't exist
console.error(`Error: The default directory '${defaultPath}' does not exist. Please check the path and try again.`);
process.exit(1); // Exit with an error code
}
}
// Validating Tags argument
if (args["TAGS"]) {
script += ` TAGS="${args["TAGS"]}" `;
EXEC_TAGS = `"${args["TAGS"]}" `;
removeProcessedArgs("TAGS");
}
else
console.log("Info: No TAGS argument has been passed.");
// 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=chrome `;
EXEC_BROWSER = "chrome";
removeProcessedArgs("BROWSER");
}
else {
script += ` BROWSER=${args["BROWSER"].toLowerCase()} `;
EXEC_BROWSER = `${args["BROWSER"].toLowerCase()}`;
}
}
else {
console.log("Info: No BROWSER argument has been passed. Defaulted to run with Chrome");
script += ` BROWSER=chrome `;
EXEC_BROWSER = "chrome";
}
// Validating Headless argument
if (args["HEADLESS"]) {
if (!["true", "false"].includes(args["HEADLESS"])) {
console.warn("Warning: Invalid value for HEADLESS. Defaulting to 'true'.");
script += ` HEADLESS=true FORCE_COLOR=0 `;
EXEC_HEADLESS = "true";
removeProcessedArgs("HEADLESS");
}
else {
script += ` HEADLESS=${args["HEADLESS"]} FORCE_COLOR=0 `;
EXEC_HEADLESS = `${args["HEADLESS"]}`;
}
}
else {
console.log("Info: No HEADLESS argument has been passed. Defaulted to true");
script += ` HEADLESS=true FORCE_COLOR=0 `;
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"]} `;
process.env.REPORT_PATH = `${args["REPORT_PATH"]}`;
removeProcessedArgs("REPORT_APTH");
}
// Validating Report Path argument
if (args["PARALLEL_WORKER"]) {
script += ` 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 `;
script += await parseCommandLineArgs();
script += ` cucumber-js --config=node_modules/tm-playwright-framework/dist/config/cucumber.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();
}
// Get browser version
async function getBrowserVersion() {
process.env.BROWSER = `${EXEC_BROWSER}`;
const BROWSER = await invokeBrowser(EXEC_BROWSER);
BROWSER_VERSION = BROWSER.version();
console.log(BROWSER_VERSION);
BROWSER.close();
return;
}
// Running Post-Test
async function postScript() {
// Running Post-Test
try {
await getBrowserVersion();
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"]} `;
process.env.CLIENT = `${args["CLIENT"]}`;
}
script += ` REPORT_PATH=${process.env.REPORT_PATH || 'cucumber-results/default-report'}`;
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>");
}