cypress-load-balancer
Version:
A simple load balancer for Cypress tests.
117 lines (116 loc) • 6.15 kB
JavaScript
"use strict";
//TODO: add type later
//eslint-disable @typescript-eslint/no-explicit-any
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@actions/core");
// @ts-expect-error There are no types for this package
const find_cypress_specs_1 = require("find-cypress-specs");
const glob_1 = require("glob");
const loadBalancer_1 = __importDefault(require("../../loadBalancer"));
const utils_1 = __importDefault(require("../../utils"));
const formatOutput = (output, type) => {
switch (type) {
case "spec":
return output.map((runner) => (runner.length > 0 ? `--spec ${runner.join(",")}` : ""));
case "string":
return output.map((runner) => runner.join(","));
case "newline":
return output.map((runner) => runner.join("\n"));
default:
return output;
}
};
exports.default = {
command: "$0",
description: "Performs load balancing against a set of runners and Cypress specs",
//@ts-expect-error Figuring out the type later
builder: function (yargs) {
return (yargs
.option("runners", {
alias: "r",
type: "number",
demandOption: true,
description: "The count of executable runners to use"
})
.option("testing-type", {
alias: "t",
type: "string",
choices: ["e2e", "component"],
demandOption: true,
description: "The testing type to use for load balancing"
})
.option("files", {
alias: "F",
type: "array",
default: [],
description: `An array of file paths relative to the current working directory to use for load balancing. Overrides finding Cypress specs by configuration file.` +
`\nIf left empty, it will utilize a Cypress configuration file to find test files to use for load balancing.` +
`\nThe Cypress configuration file is implied to exist at the base of the directory unless set by "process.env.CYPRESS_CONFIG_FILE"`
})
.option("glob", {
alias: "G",
type: "array",
default: [],
description: `Specify one or more glob pattern to match test file names.` +
`\nCan be used with "--files". Overrides finding Cypress specs by configuration file.`
})
.option("format", {
alias: "fm",
choices: ["spec", "string", "newline"],
description: `Transforms the output of the runner jobs into various formats.` +
`\n"--transform spec": Converts the output of the load balancer to be as an array of "--spec {file}" formats` +
`\n"--transform string": Spec files per runner are joined with a comma; example: "tests/spec.a.ts,tests/spec.b.ts"` +
`\n"--transform newline": Spec files per runner are joined with a newline; example: \n\t"tests/spec.a.ts\ntests/spec.b.ts"`
})
.option("set-gha-output", {
alias: "gha",
type: "boolean",
description: `Sets the output to the GitHub Actions step output as "cypressLoadBalancerSpecs"`
})
//TODO: allow using other file names. This is useful when multiple cypress configurations exist
// .option('loadBalancingMapFileName', {
// alias: 'M',
// type: 'string',
// default: process.env.CYPRESS_LOAD_BALANCING_MAP_FILE_NAME,
// describe: 'If using a file name for a different load balancing map, add it as the option here',
// coerce: opt=> {
// process.env.CYPRESS_LOAD_BALANCING_MAP_FILE_NAME = opt
// }
// })
.help()
.alias("help", "h")
.example('Load balancing for 6 runners against "component" testing with implied Cypress configuration of `./cypress.config.js`', "npx cypressLoadBalancer -r 6 -t component")
.example('Load balancing for 6 runners against "component" testing with an explicit Cypress configuration set by an environment variable', "CYPRESS_CONFIG_FILE=./src/tests/cypress.config.js npx cypressLoadBalancer -r 6 -t e2e")
.example('Load balancing for 3 runners against "e2e" testing with specified file paths', "npx cypressLoadBalancer -r 3 -t e2e -F cypress/e2e/foo.cy.js cypress/e2e/bar.cy.js cypress/e2e/wee.cy.js")
.example('Load balancing for 3 runners against "e2e" testing with a specified glob pattern and file path', "npx cypressLoadBalancer -r 3 -t e2e -F cypress/e2e/foo.cy.js -G cypress/e2e/more_tests/*.cy.js"));
},
//@ts-expect-error Figuring out the type later
handler: function (argv) {
//Assign files array to detect "--files" or files found "--glob" patterns first
let files = argv.files;
files.push(...glob_1.glob.globSync(argv.glob));
//If nothing is found from either option, use the base cypress configuration
try {
if (files.length === 0) {
utils_1.default.DEBUG("No files provided, so using Cypress configuration");
files = (0, find_cypress_specs_1.getSpecs)(undefined, argv[`testing-type`]);
}
}
catch (e) {
console.error("Could not run `getSpecs` most likely do to an incorrect Cypress configuration or missing testing type", argv[`testing-type`], "Original error", e);
}
const output = (0, loadBalancer_1.default)(argv.runners, argv["testing-type"], [
...new Set(files)
]);
argv.output = JSON.stringify(formatOutput(output, argv.format));
if (argv[`set-gha-output`]) {
(0, core_1.setOutput)("cypressLoadBalancerSpecs", argv.output);
}
if (process.env.CYPRESS_LOAD_BALANCER_DEBUG !== "true")
console.clear();
console.log(argv.output);
}
};