@saucelabs/visual
Version:
JS client bindings for Sauce Labs Visual
172 lines (165 loc) • 6.47 kB
JavaScript
import {
VisualApiRegion,
displayStatusTable,
getApi
} from "./chunk-JCFCNGGA.js";
import "./chunk-3IT7HMR5.js";
// src/cli.ts
import { Command as Command3, program as program3 } from "commander";
import chalk from "chalk";
// src/cli/build.ts
import { Command, Option as Option2, program as program2 } from "commander";
// src/cli/common-options.ts
import { program, Option } from "commander";
var regionParser = (input, _previous) => {
if (!input) {
return VisualApiRegion.fromName("us-west-1");
}
try {
return VisualApiRegion.fromName(input);
} catch (e) {
program.error(String(e));
}
};
var regionOption = new Option(
"-r, --region <region>",
"The Sauce Labs region. Options: us-west-1, eu-central-1"
).default(VisualApiRegion.fromName("us-west-1"), "us-west-1").argParser(regionParser);
// src/cli/build.ts
var hasBuildIdOrCustomId = (args) => {
if (args.buildId && args.customId) {
program2.error(
"Error: only one of --build-id or --custom-id can be specified"
);
}
if (!args.buildId && !args.customId) {
program2.error("Error: --build-id or --custom-id needs to be specified");
}
};
function apiFromOptions(opts) {
return getApi({
region: opts.region,
user: process.env.SAUCE_USERNAME,
key: process.env.SAUCE_ACCESS_KEY
});
}
var buildIdOption = new Option2("-b, --build-id <build-id>");
var customIdOption = new Option2("-c, --custom-id <custom-id>");
var SUCCESS_STATUS = ["APPROVED" /* Approved */, "EQUAL" /* Equal */];
var getBuildResults = async (api, { buildId, customId }) => {
const getBuild = async () => {
if (customId)
return api.buildWithDiffsByCustomId(customId);
if (buildId)
return api.buildWithDiffs(buildId);
return null;
};
const build = await getBuild();
if (!build) {
throw new Error(`no build with matching criteria has been found`);
}
return build.diffs.nodes.map((d) => d.status).reduce((r, s) => {
r[s] = (r[s] ?? 0) + 1;
return r;
}, {});
};
var buildStatusCommand = async (_, cmd) => {
const options2 = cmd.optsWithGlobals();
hasBuildIdOrCustomId(options2);
const visualApi = apiFromOptions(options2);
const status = await getBuildResults(visualApi, options2);
displayStatusTable(options2.buildId || options2.customId || "", status);
const failures = Object.entries(status).filter(([state]) => !SUCCESS_STATUS.includes(state)).map(([_2, count]) => count).reduce((prev, cur) => prev + cur, 0);
process.exit(failures ? 1 : 0);
};
var statusCommand = () => new Command().name("status").description("Fetches status from a Sauce Visual build").addOption(regionOption).addOption(buildIdOption).addOption(customIdOption).action(buildStatusCommand);
var buildCreate = async (_, cmd) => {
const options2 = cmd.optsWithGlobals();
const visualApi = apiFromOptions(options2);
const build = await visualApi.createBuild({
name: options2.name,
branch: options2.branch,
customId: options2.customId,
project: options2.project,
defaultBranch: options2.defaultBranch
});
console.info(`Build ${build.id} created`);
if (options2.url === true) {
console.info(`URL: ${build.url}`);
}
};
var buildCreateCommand = () => new Command().name("create").description("Creates a Sauce Visual build").addOption(regionOption).requiredOption("-n, --name <name>").addOption(customIdOption).option("--branch <branch>").option("--default-branch <defaultBranch>").option("-p, --project <project>").option("-u, --url", "display build URL after creation").action(buildCreate);
var buildFinish = async (_, cmd) => {
const options2 = cmd.optsWithGlobals();
hasBuildIdOrCustomId(options2);
const visualApi = apiFromOptions(options2);
let { buildId } = options2;
const { customId } = options2;
if (!buildId && customId) {
const build = await visualApi.buildByCustomId(customId);
if (!build) {
program2.error(`customId '${customId}' does not resolve to a build`);
}
buildId = build.id;
}
await visualApi.finishBuild({ uuid: buildId });
};
var buildFinishCommand = () => new Command().name("finish").description("Finishes a Sauce Visual build").addOption(regionOption).addOption(buildIdOption).addOption(customIdOption).action(buildFinish);
var options = {
hidden: false,
isDefault: false
};
var command = () => new Command().name("build").description("Interacts with a Sauce Visual build").addCommand(statusCommand()).addCommand(buildCreateCommand()).addCommand(buildFinishCommand());
// src/cli/baselines.ts
import { Command as Command2 } from "commander";
function apiFromOptions2(opts) {
return getApi({
region: opts.region,
user: process.env.SAUCE_USERNAME,
key: process.env.SAUCE_ACCESS_KEY
});
}
async function baselineMergeCommand(_, cmd) {
const options2 = cmd.optsWithGlobals();
const visualApi = apiFromOptions2(options2);
const result = await visualApi.mergeBaselines({
projectName: options2.project,
sourceBranch: options2.sourceBranch,
targetBranch: options2.targetBranch
});
console.log(`Merged baselines: ${result.baselines?.length}`);
}
var mergeCommand = () => new Command2().name("merge").description("Merge baselines from a source branch into a target branch").addOption(regionOption).requiredOption("-p, --project <project>", "Project name").requiredOption(
"-s, --source-branch <branch>",
"Branch from which to copy the baselines"
).requiredOption(
"-t, --target-branch <branch>",
"Branch into which to copy the baselines"
).action(baselineMergeCommand);
var baselinesOptions = {};
var baselinesCommand = () => new Command2().name("baselines").description("Interacts with Sauce Visual baselines").addCommand(mergeCommand());
// src/cli.ts
var defaultCommand = new Command3().name("default").addOption(buildIdOption).addOption(customIdOption).action(async (...args) => {
console.warn(
chalk.bold(
chalk.redBright(
`This command is deprecated. Please use "visual build status" instead of "visual"`
)
)
);
await buildStatusCommand(...args);
});
program3.name("visual").description("Interacts with Sauce Visual");
program3.addOption(regionOption);
program3.addCommand(defaultCommand, { isDefault: true, hidden: true });
program3.addCommand(command(), options);
program3.addCommand(baselinesCommand(), baselinesOptions);
(async function() {
try {
program3.parse();
} catch (e) {
console.error(`${e}`);
process.exit(1);
}
})();