Skip to content

Commit

Permalink
feat: Offline mode (#110)
Browse files Browse the repository at this point in the history
* chore: wip

* feat: allow running in offline mode

* chore: add offline e2e test

* chore: add offline e2e test
  • Loading branch information
agoldis committed Mar 31, 2023
1 parent b8d8f43 commit dabd843
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 32 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/e2e-smoke-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,12 @@ jobs:
--tag smoke,linux
--spec "./cypress/e2e_smoke/*.spec.js"
--ci-build-id "smoke-linux-${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt}}"
- name: Run in Offline mode
working-directory: ./examples/webapp
run: >
npx cypress-cloud run
--record false
--browser chrome
--tag smoke,linux
--spec "./cypress/e2e_smoke/*.spec.js"
3 changes: 3 additions & 0 deletions packages/cypress-cloud/bin/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ main()
if (!result) {
process.exit(0);
}
if (result.status === "failed") {
process.exit(1);
}

const overallFailed = result.totalFailed + result.totalSkipped;
if (overallFailed > 0) {
Expand Down
52 changes: 25 additions & 27 deletions packages/cypress-cloud/lib/config/params.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
CurrentsRunParameters,
CypressRunParameters,
StrippedCypressModuleAPIOptions,
ValidatedCurrentsParameters,
} from "cypress-cloud/types";
import Debug from "debug";
Expand Down Expand Up @@ -77,6 +76,7 @@ export function validateParams(
_params: CurrentsRunParameters
): ValidatedCurrentsParameters {
const params = resolveCurrentsParams(_params);

if (!params.cloudServiceUrl) {
throw new ValidationError(cloudServiceUrlError);
}
Expand Down Expand Up @@ -115,6 +115,10 @@ export function validateParams(
return params as ValidatedCurrentsParameters;
}

export function isOffline(params: CurrentsRunParameters) {
return params.record === false;
}

function parseTags(tagString: CurrentsRunParameters["tag"]): string[] {
if (!tagString) {
return [];
Expand All @@ -130,37 +134,31 @@ function parseTags(tagString: CurrentsRunParameters["tag"]): string[] {

/**
*
* @returns Cypress non-empty options without the ones that are not relevant for the runner
* @returns Cypress options without items that affect recording mode
*/
function getStrippedCypressOptions(
params: CurrentsRunParameters
): StrippedCypressModuleAPIOptions {
return _.pickBy(
_.omit(params, [
"cloudServiceUrl",
"batchSize",
"projectId",
"record",
"key",
"recordKey",
"group",
"parallel",
"tag",
"ciBuildId",
"spec",
"exit",
"headed",
"headless",
]),
Boolean
);
}

export function getCypressRunAPIParams(
params: CurrentsRunParameters
): CypressRunParameters {
return {
...getStrippedCypressOptions(params),
..._.pickBy(
_.omit(params, [
"cloudServiceUrl",
"batchSize",
"projectId",
"key",
"recordKey",
"record",
"group",
"parallel",
"tag",
"ciBuildId",
"spec",
"exit",
"headed",
"headless",
]),
Boolean
),
record: false,
};
}
19 changes: 19 additions & 0 deletions packages/cypress-cloud/lib/cypress/cypress.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
import cypress from "cypress";
import {
CurrentsRunParameters,
CypressResult,
ValidatedCurrentsParameters,
} from "cypress-cloud/types";
import Debug from "debug";
import _ from "lodash";
import { getCypressRunAPIParams } from "../config";

const debug = Debug("currents:cypress");
interface RunCypressSpecFile {
spec: string;
}

export function runBareCypress(params: CurrentsRunParameters = {}) {
// revert currents params to cypress params
// exclude record mode params
const p = {
...params,
ciBuildId: undefined,
tag: undefined,
parallel: undefined,
record: false,
group: undefined,
spec: _.flatten(params.spec).join(","),
};
debug("Running bare Cypress with params %o", p);
return cypress.run(p);
}

/**
* Run Cypress tests, we need to pass down the stripped options as if we've received them from the CLI
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/cypress-cloud/lib/docs/flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Those are separate from Cypress flags, but similar enough to be easy to use for

When we accept the flags from a user, we parse them (in lib/cli) and keeping them as an object. When needed, we either serialize them into a CLI-compatible (for `cp.spawn`) form, or pass them down as options object to `cypress.run`. It is important to remove all the flags that can invoke cloud functionality, but also keep all other params that define cypress behaviour.

We use `getStrippedCypressOptions` to remove all the irrelevant flags from the
We use `getCypressRunAPIParams` to remove all the irrelevant flags when running cypress

CLI
Expand Down
7 changes: 6 additions & 1 deletion packages/cypress-cloud/lib/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { CurrentsRunParameters } from "../types";
import { createRun } from "./api";
import { cutInitialOutput } from "./capture";
import { getCI } from "./ciProvider";
import { getMergedConfig, validateParams } from "./config";
import { getMergedConfig, isOffline, validateParams } from "./config";
import { runBareCypress } from "./cypress";
import { getGitInfo } from "./git";
import { setAPIBaseUrl, setRunId } from "./httpClient";
import { bold, divider, info, spacer, title } from "./log";
Expand All @@ -17,6 +18,10 @@ const debug = Debug("currents:run");
export async function run(params: CurrentsRunParameters = {}) {
debug("run params %o", params);

if (isOffline(params)) {
info(`Skipping cloud orchestration because --record is set to false`);
return runBareCypress(params);
}
const validatedParams = validateParams(params);
setAPIBaseUrl(validatedParams.cloudServiceUrl);

Expand Down
18 changes: 15 additions & 3 deletions packages/cypress-cloud/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,17 @@ export interface TestsResult {

export type SummaryResult = Record<string, CypressCommandLine.CypressRunResult>;

// Explicitly filter cypress-related flags - prevent triggering recording mode to avoid confusion
// Explicitly filter cypress record-related flags - prevent triggering recording mode to avoid confusion
export type StrippedCypressModuleAPIOptions = Omit<
Partial<CypressCommandLine.CypressRunOptions>,
| "tag"
| "spec"
| "exit"
| "headed"
| "record"
| "headless"
| "noExit"
| "parallel"
| "record"
| "key"
| "tag"
| "group"
Expand All @@ -129,29 +129,41 @@ export type CypressRunParameters = StrippedCypressModuleAPIOptions & {
export type CurrentsRunParameters = StrippedCypressModuleAPIOptions & {
/** The CI build ID to use for the run */
ciBuildId?: string;

/** The batch size defines how many spec files will be served in one orchestration "batch". If not specified, will use the projectId from currents.config.js, the default value is 1 (i.e. no batching) */
batchSize?: number;

/** Whether to activate record mode and connect to cloud orchestration service */
record?: boolean;

/** The URL of the currents server to use. If not specified, will use the one from currents.config.js */
cloudServiceUrl?: string;
/** The environment variables to use for the run */
env?: object;

/** The group id to use for the run */
group?: string;

/** The record key to use */
recordKey?: string;

/** Whether to run the spec files in parallel */
parallel?: boolean;

/** The project ID to use. */
projectId?: string;

/** Comma-separated string or an array of spec glob pattern for the execution */
spec?: string | string[];

/** Comma-separated string or an array of tags */
tag?: string | string[];

/** "e2e" or "component", the default value is "e2e" */
testingType?: TestingType;
};

// User-facing interface `run` interface
// User-facing `run` interface
// We can resolve the projectId and recordKey from different sources, so we can't really enforce them via the type definition
export interface CurrentsRunAPI extends CurrentsRunParameters {}

Expand Down

0 comments on commit dabd843

Please sign in to comment.