Skip to content

Commit

Permalink
generate a time execution reports (#9)
Browse files Browse the repository at this point in the history
* fix(path): orchestrator can accept relative paths (#9)
* feat(report): Export the executionTimeReprots per browser (#9)
* feat(docs): Generate the changelogs (#9)
  • Loading branch information
0xIslamTaha authored Oct 19, 2021
1 parent e59e003 commit 2721106
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 21 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Changelog
All notable changes to this project will be documented in this file.


## [1.1.2] - Tue Oct 19
### Added
- feat(report): Export the executionTimeReprots per browser
- fix(path): orchestrator can accept relative paths


## [1.1.1] - Thu Sep 16
### Added
- feat(subdir): support the nested direction specs folders (#7).
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@0xislamtaha/orchestrator",
"version": "1.1.1",
"version": "1.1.2",
"description": "orchestrate cypress parallel execution across multiple Docker containers",
"main": "src/orchestrator.js",
"scripts": {
Expand Down
21 changes: 13 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ Check the following repo as a public use case.

* Pares a config file.
* Create (config.parallelizm * config.browsers.length) containers in parallel.
* Split all specs across all those machines based on their execution time.
* Collect all the execution results from those containers.
* Recursively list all the specs files
* Split all the specs across all those machines based on their execution time.
* Collect all the execution json reports from those containers.
* Down all the running containers.
* Generate one HTML report that has all specs execution results.
* Analyse the execution time for each spec.
* If you fed the orchestrator with this execution time JSON file, It will split the test cases based on that.
* Generate the execution time reports per browser under ExecutionTimeReport dir.
* In the next run, The orchestrator It will split the test cases based on this execution time report to reduce the exeuction time.


## 🏹 The Splitting mechanism:
The orchestrator can measure and report the execution time for each spec per browser. It will report it as `mochawesome-report/specsExecutionTime-chrome.json` file. If you provided this path as `specsExecutionTimePath` in the next run, The orchestrator will split the specs based on its execution time to minimize the total execution time 🚀.
Expand Down Expand Up @@ -134,11 +137,6 @@ services:
type: boolen
example: true
- specsExecutionTimePath:
description: path to the execution time file.
type: string
example: "mochawesome-report/specsExecutionTime-chrome.json"
```

## 🎮 Usage:
Expand All @@ -153,6 +151,13 @@ npx orchestrator --config "/path/to/config.json"
npx orchestrator --config ./src/config.json --parallelizm 2 --environment '{"DOCKER_TAG":"master_283"}' --browsers "[chrome, firefox]" --specs "[alerts.js, avatar.js]"
```

## 📖 Reports:

The orchestrator generates two reports by default:
- The HTML report under the `mochawesome-report` dir.
- The execution time reports per browser und `ExecutionTimeReport` dir.


## 🎬 To-Do:
* Export COMPOSE_PROJECT_NAME with random value if it doesn't exist.
* list configuration rather than multiple files for multiple test suites.
Expand Down
11 changes: 7 additions & 4 deletions src/analyseReport.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ function updateSpecData(suites, specName) {
});
}

export function analyseReport(mochaReportPath) {
export function analyseReport(mochaReportPath, executiontimeReportJsonPath) {
console.log("analyse the json report .... ");

if (checkFileIsExisting(mochaReportPath)) {
const reportDir = path.dirname(mochaReportPath);
const executionTimeReportDir = path.dirname(executiontimeReportJsonPath);
const executionTimeReporJson = executiontimeReportJsonPath.split("/").pop();
const report = require(mochaReportPath);

report["results"].forEach( result => {
Expand All @@ -57,10 +58,12 @@ export function analyseReport(mochaReportPath) {
updateSpecData(suites, specFile);
});

writeJsonFile(specs, executionTimeReportDir, executionTimeReporJson);

for (let browser of browsers) {
console.log(
`------------------------- ${browser} -------------------------`
);
);
let data = orderBasedOnBrowserDuration(specs, browser).map((spec) => {
return {
specName: spec.specName,
Expand All @@ -69,7 +72,7 @@ export function analyseReport(mochaReportPath) {
),
};
});
writeJsonFile(data, reportDir, `specsExecutionTime-${browser}.json`);
writeJsonFile(data, executionTimeReportDir, `${executionTimeReporJson.split('.')[0]}-${browser}.json`);
console.table(data);
}
}
Expand Down
28 changes: 20 additions & 8 deletions src/orchestrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import {
orderBasedOnBrowserDuration,
} from "./helper.js";

const executionTimeReportDir = "executionTimeReprot";
const executionTimeReportDirPath = path.resolve(process.cwd(), executionTimeReportDir)
const executiontimeReportJson = "specsExecutionTime.json"
const executiontimeReportJsonPath = path.join(executionTimeReportDirPath, executiontimeReportJson)

function execa(command, flag = true) {
return new Promise((resolve, reject) =>
sh.exec(command, function (code, stdout, stderr) {
Expand Down Expand Up @@ -71,8 +76,9 @@ function parseArgumentsIntoConfig(rawArgs) {

function overWriteConfig(args) {
const configFile = args["--config"] || path.resolve(__dirname, "config.json");
const config = JSON.parse(fs.readFileSync(configFile, "utf-8"));
return { ...config, ...args };
const defaultConfig = JSON.parse(fs.readFileSync(configFile, "utf-8"));
const config = { ...defaultConfig, ...args };
return config;
}

function setEnvVars(config) {
Expand All @@ -91,13 +97,13 @@ function getListOfSpecs(config, browser) {
let existingSpecs = [];

if (config.specs.length > 0) {
existingSpecs = config.specs
existingSpecs = [...config.specs];
} else {
existingSpecs = sh.ls('-R', config.specsHomePath).filter((val) => val.match(/.*ts|js/));
}

if (checkFileIsExisting(config.specsExecutionTimePath)) {
let specsExecutionTime = parseJsonFile(config.specsExecutionTimePath);
if (checkFileIsExisting(executiontimeReportJsonPath)) {
let specsExecutionTime = parseJsonFile(executiontimeReportJsonPath);
let browserSpecs = orderBasedOnBrowserDuration(
specsExecutionTime,
browser
Expand Down Expand Up @@ -154,7 +160,8 @@ function genearateSpecsCommandsForMachines(config, browser) {
listOfSpecsOverMachines.forEach((listOfspecsPerMachine) => {
let result = "";
listOfspecsPerMachine.forEach((spec) => {
result = `${result},${config.specsDockerPath}${spec}`;
let specPath = path.join(config.specsDockerPath, spec);
result = `${result},${specPath}`;
});
specsCommandsOverMachines.push(result.slice(1));
});
Expand Down Expand Up @@ -230,7 +237,12 @@ function generateReport(config) {
})
)
.then(() => {
if (config.analyseReport) _analyseReport(config);
if (config.analyseReport) {
if (!fs.existsSync(executionTimeReportDirPath)){
sh.mkdir(executionTimeReportDirPath);
}
_analyseReport(config);
}
});
}

Expand All @@ -249,7 +261,7 @@ function _analyseReport(config) {
);
}

analyseReport(mergedMochawesomeJSONPath);
analyseReport(mergedMochawesomeJSONPath, executiontimeReportJsonPath);
}

function afterPromises(config, timer) {
Expand Down

0 comments on commit 2721106

Please sign in to comment.