Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
agoldis committed Dec 21, 2022
1 parent 62c160a commit a1cf4c3
Show file tree
Hide file tree
Showing 10 changed files with 7,734 additions and 10,773 deletions.
7 changes: 5 additions & 2 deletions packages/cypress-cloud/bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import { run } from "../index";
import { parseOptions } from "../lib/cli";
import { error } from "../lib/log";

const options = parseOptions();
run(options)
async function main() {
return run(await parseOptions());
}

main()
.then((result) => {
if (!result) {
process.exit(0);
Expand Down
58 changes: 10 additions & 48 deletions packages/cypress-cloud/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ import {
summarizeTestResults,
} from "./lib/results";
import { findSpecs } from "./lib/specMatcher";
import {
CypressModuleAPIRunOptions,
SummaryResults,
TestingType,
TestsResult,
} from "./types";
import { CurrentsRunParameters, SummaryResults } from "./types";

import { createInstance, createRun } from "./lib/api/api";
import { CreateInstancePayload } from "./lib/api/types/instance";
Expand All @@ -27,54 +22,21 @@ import { divider, info, spacer, title, warn } from "./lib/log";
import { getPlatformInfo } from "./lib/platform";
import { summaryTable } from "./lib/table";

interface RunOptions extends CypressModuleAPIRunOptions {
/** The project ID to use. If not specified, will use the projectId from currents.config.js or process.env.CURRENTS_PROJECT_ID */
projectId?: string;
/** The record key to use */
key?: string;
/** List of tags for the recorded run, like ["production" , "nightly"] */
tag?: string[];
}

/**
* Run the Cypress tests.
* You can either pass the options as a parameter, or run the cli.
*
* @augments RunOptions
* @returns {TestsResult | undefined} The test results, or undefined if no tests were run.
*/
export async function run(parameters: RunOptions) {
export async function run(params: CurrentsRunParameters) {
spacer();

const { key: _key, projectId: _projectId, ...cypressRunOptions } = parameters;

const { projectId: currentsProjectId } = await getCurrentsConfig();

const {
group,
parallel,
ciBuildId,
tag: tags,
testingType: _testingType,
} = parameters;
const key = _key ?? process.env.CURRENTS_RECORD_KEY;
if (!key) {
throw new Error(
"Missing 'key'. Please either pass it as a cli flag '-k, --key <record-key>', as CURRENTS_RECORD_KEY environment variable, or if using the run function directly pass it as the 'key' parameter."
);
}

const projectId =
_projectId ?? currentsProjectId ?? process.env.CURRENTS_PROJECT_ID;
if (!projectId) {
throw new Error(
"Missing projectId. Please either set it in currents.config.js, as CURRENTS_PROJECT_ID environmnet variable, or if using the run function directly pass it as the 'projectId' parameter."
);
}
const { key, projectId, group, parallel, ciBuildId, tags, testingType } =
params;

const testingType: TestingType = _testingType ?? "e2e";
const config = await mergeConfig(testingType, projectId, cypressRunOptions);
const specPattern = parameters.spec || config.specPattern;
const config = await mergeConfig(params);
const specPattern = params.spec || config.specPattern;
const specs = await findSpecs({
projectRoot: config.projectRoot,
testingType,
Expand Down Expand Up @@ -105,7 +67,7 @@ export async function run(parameters: RunOptions) {
const osPlatformInfo = await getPlatformInfo();
const platform = {
...osPlatformInfo,
...guessBrowser(parameters.browser ?? "electron", config.resolved.browsers),
...guessBrowser(params.browser ?? "electron", config.resolved.browsers),
};
const ci = getCI();
const commit = await getGitInfo(config.projectRoot);
Expand All @@ -118,7 +80,7 @@ export async function run(parameters: RunOptions) {
platform,
parallel: parallel ?? false,
ciBuildId,
projectId: config.projectId,
projectId,
recordKey: key,
specPattern,
tags,
Expand All @@ -137,7 +99,7 @@ export async function run(parameters: RunOptions) {
platform,
config,
},
cypressRunOptions
params
);

const testResults = summarizeTestResults(Object.values(results));
Expand All @@ -164,7 +126,7 @@ async function runTillDone(
}: CreateInstancePayload & {
config: ReturnType<typeof getCurrentsConfig>;
},
cypressRunOptions: CypressModuleAPIRunOptions
cypressRunOptions: CurrentsRunParameters
) {
const summary: SummaryResults = {};

Expand Down
28 changes: 18 additions & 10 deletions packages/cypress-cloud/lib/bootstrap.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import cp from "child_process";
import { getBinPath } from "cy2";
import cypress from "cypress";
import Debug from "debug";
import fs from "fs";
import { customAlphabet } from "nanoid";
import VError from "verror";
import { CypressModuleAPIRunOptions } from "../types";
import { CurrentsRunParameters } from "../types";
import { getStrippedCypressOptions, serializeOptions } from "./cli/cli";
import { createTempFile } from "./fs";
import { error } from "./log";
Expand All @@ -14,13 +13,13 @@ const getDummySpec = customAlphabet("abcdefghijklmnopqrstuvwxyz", 10);

export const bootCypress = async (
port: number,
cypressRunOptions: CypressModuleAPIRunOptions
params: CurrentsRunParameters
) => {
debug("booting cypress...");
const tempFilePath = await createTempFile();

const serializedOptions = serializeOptions(
getStrippedCypressOptions(cypressRunOptions)
getStrippedCypressOptions(params)
).flatMap((arg) => arg.split(" "));

// it is important to pass the same args in order to get the same config as for the actual run
Expand All @@ -35,12 +34,21 @@ export const bootCypress = async (
...serializedOptions,
];

try {
await cypress.run({
...getStrippedCypressOptions(params),
spec: getDummySpec(),
});
} catch (e) {
console.log(e);
}
debug("booting cypress with args: %o", args);
const cypressBin = await getBinPath(require.resolve("cypress"));
debug("cypress executable location: %s", cypressBin);
const child = cp.spawnSync(cypressBin, args, {
stdio: "pipe",
});
// const cypressBin = await getBinPath(require.resolve("cypress"));
// debug("cypress executable location: %s", cypressBin);

// const child = cp.spawnSync(cypressBin, args, {
// stdio: "pipe",
// });

if (!fs.existsSync(tempFilePath)) {
throw new VError(
Expand Down
149 changes: 124 additions & 25 deletions packages/cypress-cloud/lib/cli/__tests__/cli.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createProgram, parseOptions } from "..";
import { expect } from "@jest/globals";
import { createProgram, parseOptions } from "..";

const getProgram = () =>
createProgram()
Expand All @@ -10,36 +10,135 @@ const getProgram = () =>
outputError: () => {},
});

const p = (args: string[]) =>
parseOptions(getProgram(), ["program", "command", ...args]);

const defaults = {
parallel: false,
record: true,
testingType: "e2e",
};
describe("CLI", () => {
it("has defaults", () => expect(p([])).toMatchObject(defaults));
it("parses browser", () => {
expect(p(["--browser", "some"])).toMatchObject({
browser: "some",
});
});

it("parses --ci-build-id", () => {
expect(p(["--ci-build-id", "some"])).toMatchObject({
ciBuildId: "some",
});
});

it("parses spec into an array", async () => {
expect(
parseOptions(getProgram(), [
"program",
"command",
"--spec",
"a,b",
"--key",
"a",
])
).toMatchObject({
spec: ["a", "b"],
expect(p(["--spec", "a,b", "--spec", "c"])).toMatchObject({
spec: ["a", "b", "c"],
});
});

it("parses empty spec into nothing", async () => {
expect(p([])).toMatchObject({
spec: undefined,
});
});

it("parses --component", async () => {
expect(p(["--component"])).toMatchObject({
testingType: "component",
});
});

it("parses --e2e", async () => {
expect(p(["--e2e"])).toMatchObject({
testingType: "e2e",
});
});

it("parses --config comma-separated", async () => {
expect(p(["--config", "a=b,c=d"])).toMatchObject({
config: {
a: "b",
c: "d",
},
});
});

xit("parses --config json", async () => {
expect(p(["--config", `c={'a': 'b'}`])).toMatchObject({
config: {
a: "b",
},
});
});

it("parses --env comma-separated", async () => {
expect(p(["--env", "a=b,c=d"])).toMatchObject({
env: {
a: "b",
c: "d",
},
});
});

it("parses -C", async () => {
expect(p(["-C", "some"])).toMatchObject({
configFile: "some",
});
});

it("parses --group", async () => {
expect(p(["--group", "some"])).toMatchObject({
group: "some",
});
});

it("parses --key", async () => {
expect(p(["--key", "some"])).toMatchObject({
key: "some",
});
});

it("parses --parallel", async () => {
expect(p(["--parallel"])).toMatchObject({
parallel: true,
});
});

it("parses no --parallel", async () => {
expect(p([])).toMatchObject({
parallel: false,
});
});

it("parses --port", async () => {
expect(p(["--port", "8080"])).toMatchObject({
port: 8080,
});
});

it("parses --P", async () => {
expect(p(["-P", "some"])).toMatchObject({
project: "some",
});
});

it("parses --record", async () => {
expect(p(["--record"])).toMatchObject({
record: true,
});
});

it("parses no --record", async () => {
expect(p([""])).toMatchObject({
record: true,
});
});

it("parses tags into an array", async () => {
expect(
parseOptions(getProgram(), [
"program",
"command",
"--tag",
"a,b",
"--tag",
"c",
"--key",
"a",
])
).toMatchObject({
tag: ["a", "b", "c"],
expect(p(["--tag", "a,b", "--tag", "c", "--key", "a"])).toMatchObject({
tags: ["a", "b", "c"],
});
});

Expand Down
Loading

0 comments on commit a1cf4c3

Please sign in to comment.