Skip to content

Commit

Permalink
fix: pick test:after results explicitly
Browse files Browse the repository at this point in the history
  • Loading branch information
agoldis committed Sep 14, 2023
1 parent 6773bab commit 67e6a0d
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 87 deletions.
12 changes: 12 additions & 0 deletions examples/webapp/cypress/e2e/hang.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
describe("Example spec", () => {
beforeEach(() => {
console.log("beforeEach");
});
afterEach(() => {
console.log("after");
});
it("should open a page", () => {
cy.visit("https://launchdarkly.com/");
cy.get("a").contains("Get started").should("be.visible");
});
});
46 changes: 3 additions & 43 deletions packages/cypress-cloud/lib/results/captureHooks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExecutionState } from "../state";
import { ExecutionState, TestAfterTaskPayload } from "../state";

export function handleScreenshotEvent(
screenshot: Cypress.ScreenshotDetails,
Expand All @@ -25,46 +25,6 @@ export function handleTestAfter(
testAttempt: string,
executionState: ExecutionState
) {
const test = JSON.parse(testAttempt);
const {
title,
body,
retries,
_currentRetry,
pending,
type,
invocationDetails,
id,
hooks,
order,
wallClockStartedAt,
timings,
_events,
_eventsCount,
duration,
err,
state,
fullTitle,
} = test;
const attempt = {
title,
fullTitle,
body,
retries,
_currentRetry,
pending,
type,
invocationDetails,
id,
hooks,
order,
wallClockStartedAt,
timings,
_events,
_eventsCount,
duration,
err,
state,
};
executionState.setAttemptsData(attempt);
const test: TestAfterTaskPayload = JSON.parse(testAttempt);
executionState.setAttemptsData(test);
}
19 changes: 15 additions & 4 deletions packages/cypress-cloud/lib/results/combine.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { parseISO } from "date-fns";
import _ from "lodash";
import { SpecResult } from "../runner/spec.type";
import { ExecutionState } from "../state";
import {
AfterScreenshotPayload,
ExecutionState,
MochaError,
TestAfterTaskPayload,
} from "../state";

function getAttemptError(err: any) {
function getAttemptError(err: MochaError | null) {
if (!err) {
return null;
}
Expand All @@ -15,7 +20,10 @@ function getAttemptError(err: any) {
};
}

function parseScreenshotResults(results: any, allScreenshots?: any[]) {
function parseScreenshotResults(
results: ReturnType<typeof getSpecResults>,
allScreenshots?: AfterScreenshotPayload[]
) {
if (!allScreenshots?.length) {
return results;
}
Expand All @@ -37,7 +45,10 @@ function getAttemptVideoTimestamp(
) {
return Math.max(attemptStartedAtMs - specStartedAtMs, 0);
}
function getSpecResults(specResults: SpecResult, attempts?: any[]) {
function getSpecResults(
specResults: SpecResult,
attempts?: TestAfterTaskPayload[]
) {
if (!attempts) {
return specResults;
}
Expand Down
112 changes: 82 additions & 30 deletions packages/cypress-cloud/lib/state/execution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,60 @@ type InstanceExecutionState = {
specFileData?: SpecResult;
};

type InvocationDetails = {
export type TestAfterTaskPayload = {
async: boolean;
body: string;
duration: number;
err: MochaError;
final: boolean;
hooks: HookData[];
id: string;
invocationDetails: InvocationDetails;
order: number;
pending: boolean;
retries: number;
state: string;
sync: boolean;
timedOut: boolean;
timings: Timing;
type: string;
wallClockStartedAt: string;
title: string;
currentRetry: string;
fullTitle: string;
};

interface ParsedStackItem {
message: string;
whitespace: string;
function?: string;
fileUrl?: string;
originalFile?: string;
relativeFile?: string;
absoluteFile?: string;
line?: number;
column?: number;
}

interface CodeFrame {
line: number;
column: number;
originalFile: string;
relativeFile: string;
absoluteFile: string;
frame: string;
language: string;
}

export interface MochaError {
message: string;
name: string;
stack: string;
parsedStack: ParsedStackItem[];
codeFrame: CodeFrame;
}

interface InvocationDetails {
function: string;
fileUrl: string;
originalFile: string;
Expand All @@ -36,42 +89,41 @@ type InvocationDetails = {
column: number;
whitespace: string;
stack: string;
};
}

type AttepmtHook = {
interface HookData {
title: string;
hookName: string;
hookId: string;
pending: boolean;
body: string;
type: string;
file: string | null;
file: null | string;
invocationDetails: InvocationDetails;
currentRetry: number;
retries: number;
_slow: number;
};
}

export type AttemptData = {
title: string;
body: string;
retries: number;
_currentRetry: number;
pending: boolean;
type: string;
invocationDetails: InvocationDetails;
id: string;
hooks: AttepmtHook[];
order: number;
wallClockStartedAt: string;
timings: Record<string, any>;
_eventsCount: number;
duration: number;
err: Record<string, any>;
state: string;
};
interface TimingDetail {
hookId: string;
fnDuration: number;
afterFnDuration: number;
}

interface TestTiminDetail {
fnDuration: number;
afterFnDuration: number;
}

interface Timing {
lifecycle: number;
"before each": TimingDetail[];
test: TestTiminDetail;
"after each": TimingDetail[];
}

export type ScreenshotData = {
export type AfterScreenshotPayload = {
testAttemptIndex: number;
size: number;
takenAt: string;
Expand All @@ -85,8 +137,8 @@ export type ScreenshotData = {
};

export class ExecutionState {
private attemptsData: AttemptData[] = [];
private screenshotsData: ScreenshotData[] = [];
private attemptsData: TestAfterTaskPayload[] = [];
private screenshotsData: AfterScreenshotPayload[] = [];
private currentTestID?: string;
private state: Record<InstanceId, InstanceExecutionState> = {};

Expand Down Expand Up @@ -217,19 +269,19 @@ export class ExecutionState {
});
}

public setAttemptsData(attemptDetails: AttemptData) {
public setAttemptsData(attemptDetails: TestAfterTaskPayload) {
this.attemptsData.push(attemptDetails);
}

public getAttemptsData(): AttemptData[] | undefined {
public getAttemptsData(): TestAfterTaskPayload[] | undefined {
return this.attemptsData;
}

public setScreenshotsData(screenshotsData: ScreenshotData) {
public setScreenshotsData(screenshotsData: AfterScreenshotPayload) {
this.screenshotsData.push(screenshotsData);
}

public getScreenshotsData(): ScreenshotData[] | undefined {
public getScreenshotsData(): AfterScreenshotPayload[] | undefined {
return this.screenshotsData;
}

Expand Down
47 changes: 37 additions & 10 deletions packages/cypress-cloud/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,40 @@ import safeStringify from "fast-safe-stringify";
const afterReportedTests: string[] = [];
const beforeReportedTests: string[] = [];

function pickTestData(test: Mocha.Runnable) {
return {
async: test.async,
body: test.body,
duration: test.duration,
// @ts-ignore
err: test.err,
// @ts-ignore
final: test.final,
// @ts-ignore
hooks: test.hooks,
// @ts-ignore
id: test.id,
// @ts-ignore
invocationDetails: test.invocationDetails,
// @ts-ignore
order: test.order,
pending: test.pending,
retries: test.retries(),
state: test.state,
sync: test.sync,
timedOut: test.timedOut,
// @ts-ignore
timings: test.timings,
// @ts-ignore
type: test.type,
// @ts-ignore
wallClockStartedAt: test.wallClockStartedAt,
title: test.title,
// @ts-ignore
currentRetry: test._currentRetry,
fullTitle: test.fullTitle(),
};
}
function sendTestAfterMetrics(test: Mocha.Runnable) {
if (test.pending || !test.state) {
// Test is either skipped or hasn't ran yet.
Expand All @@ -12,16 +46,9 @@ function sendTestAfterMetrics(test: Mocha.Runnable) {
}
// @ts-ignore
afterReportedTests.push(getTestHash(test));
cy.task(
`currents:test:after:run`,
safeStringify({
...test,
fullTitle: test.fullTitle(),
}),
{
log: false,
}
);
cy.task(`currents:test:after:run`, safeStringify(pickTestData(test)), {
log: false,
});
}

function sendTestBeforeMetrics(test: Mocha.Runnable) {
Expand Down

0 comments on commit 67e6a0d

Please sign in to comment.