trident-beta
Version:
trident is a sample and lightly tools aims to improve collaboration efficiency between SDET and QA based on initiative from Einstein/TestIT.
168 lines (155 loc) • 6.9 kB
text/typescript
import { option } from "commander";
import { CaseInfo, SearchOptions } from "../sdk/dto";
import TestItSDK from "../sdk/testit";
const log4js = require("log4js");
const logger = log4js.getLogger();
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const loadingSpinner = require('loading-spinner');
const { Command } = require('commander');
const fs = require('fs');
const program = new Command();
program.version('0.0.1');
program
.option('-s, --suiteName [suite name]', 'test id or suite name is required with check option, eg: Atlas')
.option('-i, --id [case id]', 'case id or suite name is required with check option, eg: JPT-64401')
.option('-st, --subType [sub type]', 'query field sub type: E2E')
.option('-p, --projectName [project name]', 'project name is required', "Jupiter")
.option('-e, --export [output path]', 'export test cases files', "test/fixtures/")
.option('-t, --template [template file name]', 'template file path', "./src/templates/JupiterTemplate.ts.txt")
.option('-c, --check', 'sync with suite name or testid and print report in console')
.option('-r, --range [range]', 'update time range: 1d/1w/1m')
.option('-v, --verbose', 'show detail log in console')
.parse(process.argv);
program.helpOption('-h, --HELP', 'read more information');
const options = program.opts();
if (!options.suiteName && !options.testId) {
throw new Error("At least one parameter is required for suite name and test id!");
}
if (!options.username) {
rl.question("Please enter your username:", function (username) {
rl.stdoutMuted = true;
rl.question(`Please enter ${username}'s password to login TestIt:`, function (password) {
options.username = username;
options.password = password;
rl.close();
});
rl._writeToOutput = function _writeToOutput(stringToWrite) {
if (rl.stdoutMuted) {
rl.output.write("*");
}
else {
rl.output.write(stringToWrite);
}
};
});
rl.on("close", () => {
console.log("\r\n");
log4js.configure({
appenders: { console: { type: 'console' } },
categories: { default: { appenders: ['console'], level: options.verbose ? 'debug' : 'info' } }
});
if (options.check) {
logger.warn(`only check case info!`);
}
const TESTIT_ENDPOINT = 'https://testit.ringcentral.com';
const testItSdk = new TestItSDK(TESTIT_ENDPOINT);
console.log("login to testid");
loadingSpinner.start(100, {
clearChar: true
});
testItSdk.login(options.username, options.password).then(async () => {
loadingSpinner.stop();
const searchOption: SearchOptions = {
suiteName: options.suiteName,
projectName: options.projectName,
subtype: options.subType ? options.subType.split(",") : undefined
}
const query = await testItSdk.generateQuery(searchOption);
logger.info(`[search cases] start :${JSON.stringify(searchOption)}`);
loadingSpinner.start(100, {
clearChar: true
});
const response = await testItSdk.searchTestCasesByQuery(query, 'TEST_SUITES', searchOption.suiteName);
// format and print console dashboard
let total = 0;
const print = (items, prefix) => {
let str = "";
items.forEach(item => {
if (item.type === "suite") {
let caseTotal = 0;
item.children.forEach(child => {
if (child.type !== "suite") {
caseTotal++;
}
})
str += `${prefix}|- ${item.name} ${item.children && caseTotal > 0 ? caseTotal : ""}\r\n`;
} else {
total += 1;
}
if (item.children && item.type === "suite") {
str += print(item.children, prefix + "\t");
}
})
return str;
};
const treeString = print(response, "\t");
logger.info(`cases created/updated total ${total}`);
loadingSpinner.stop();
// rl.question("Did you want to print the detail cases number in tree structure? (Y/N , default Y):", (r) => {
// if (r !== "N") {
console.log(`${treeString}`);
// }
// rl.close();
// })
if (options.check) {
return;
}
console.time("handleResponse");
console.log(`preparing for case file generate`);
loadingSpinner.start(100, {
clearChar: true
});
if (response.length == 0 || response == null) { throw new Error("could not found any matched case infomation."); }
const cases: CaseInfo[] = await testItSdk.handleResponse(response);
console.timeEnd("handleResponse");
logger.info(`[search finished] matched cases total: ${cases.length}`)
// generate all cases files
const templatePath = options.template;
let templateString;
if (options.template === undefined) {
templateString = fs.readFileSync("../templates/Default.txt", "UTF-8", function (err: any) {
throw new Error("Can't not find default.txt");
});
} else {
templateString = fs.readFileSync(templatePath, "UTF-8", function (err: any) {
throw new Error(`Can't not find ${templatePath}`);
});
}
loadingSpinner.stop();
logger.info(`start generate case file with template into folder:${options.export}`)
loadingSpinner.start(100, {
clearChar: true
});
const fileGenerateTask = [];
for (const item of cases) {
fileGenerateTask.push(
new Promise<void>(async resolve => {
await testItSdk.storeFileInTree(item, templatePath, templateString);
resolve();
})
);
}
//Promise all storage
await Promise.all(fileGenerateTask);
loadingSpinner.stop();
logger.info(`[Store finished] Total Store ${fileGenerateTask.length} files`);
}).catch(e => {
logger.error(`[login failed] ${e.message}`);
});
});
}