Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@asteasolutions/zod-to-openapi": "^8.4.3",
"@aws-sdk/client-s3": "^3.1069.0",
"@bufbuild/protobuf": "^2.11.0",
"@coveritlabs/contracts": "^1.25.0",
"@coveritlabs/contracts": "^1.26.0",
"@prisma/adapter-pg": "^7.4.2",
"@prisma/client": "^7.4.2",
"@types/multer": "^2.1.0",
Expand Down
5 changes: 5 additions & 0 deletions src/__tests__/ws/manualSessionBroker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ describe("manualSessionBroker websocket allowlists", () => {
expect(source).toContain('"recorded.step"');
});

test("allows manual pending publish messages", () => {
expect(source).toContain('"flow.publish_pending"');
expect(source).toContain('"flow.pending_published"');
});

test("allows manual session ttl messages from the crawler", () => {
expect(source).toContain('"session.ttl"');
});
Expand Down
4 changes: 2 additions & 2 deletions src/models/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import type { Message } from "@bufbuild/protobuf";
import type { MessageResponse as ContractMessageResponse } from "@coveritlabs/contracts";

/**
* Recursively strips the protobuf `$typeName` marker from Message types.
* Recursively strips protobuf metadata from Message types.
* Converts protobuf Message objects to plain JS objects.
*/
export type Plain<T> =
T extends Message<string>
? { [K in keyof Omit<T, "$typeName">]: Plain<Omit<T, "$typeName">[K]> }
? { [K in keyof Omit<T, "$typeName" | "$unknown">]: Plain<Omit<T, "$typeName" | "$unknown">[K]> }
: T extends Array<infer U>
? Array<Plain<U>>
: T extends ReadonlyArray<infer U>
Expand Down
96 changes: 43 additions & 53 deletions src/models/testFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,36 @@
// See LICENSE file in the project root for full license information.

import {
type FlowEditorConnectResponse as ContractFlowEditorConnectResponse,
type FlowEditorDetailResponse as ContractFlowEditorDetailResponse,
type FlowEditorDraftStep as ContractFlowEditorDraftStep,
type FlowEditorElementRef as ContractFlowEditorElementRef,
type FlowEditorStepStateLabel as ContractFlowEditorStepStateLabel,
type FlowEditorTestFlowSummary as ContractFlowEditorTestFlowSummary,
type FlowEditorTransitionStep as ContractFlowEditorTransitionStep,
type FlowStep as ContractFlowStep,
type SaveAllFlowsRequest as ContractSaveAllFlowsRequest,
type SaveFlowEditorStepsRequest as ContractSaveFlowEditorStepsRequest,
type SaveFlowEditorStepsResponse as ContractSaveFlowEditorStepsResponse,
type SerializedFlow as ContractSerializedFlow,
} from "@coveritlabs/contracts";
import { TestFlowType as PrismaTestFlowType } from "@generated/prisma/client";
import { CodegenConfigSchema, type CodegenConfig } from "@models/crawlSession";
import type { TestFlowStepLabelingStatus, TestFlowStepStateLabel } from "@models/testFlowStepLabels";
import type { TestFlowStepLabelingStatus } from "@models/testFlowStepLabels";
import { z } from "@utils/zod";
import type { infer as ZodInfer, ZodType } from "zod";
import type { Plain } from "./common";

type ContractFlowStepData = Plain<ContractFlowStep>;
type ContractSerializedFlowData = Plain<ContractSerializedFlow>;
type ContractFlowEditorTestFlowData = Plain<ContractFlowEditorTestFlowSummary>;
type ContractFlowEditorElementRefData = Plain<ContractFlowEditorElementRef>;
type ContractFlowEditorDraftStepData = Plain<ContractFlowEditorDraftStep>;
type ContractFlowEditorStepStateLabelData = Plain<ContractFlowEditorStepStateLabel>;
type ContractFlowEditorTransitionStepData = Plain<ContractFlowEditorTransitionStep>;
type ContractFlowEditorDetailResponseData = Plain<ContractFlowEditorDetailResponse>;
type ContractSaveFlowEditorStepsRequestData = Plain<ContractSaveFlowEditorStepsRequest>;
type ContractSaveFlowEditorStepsResponseData = Plain<ContractSaveFlowEditorStepsResponse>;

export type FlowStep = Omit<ContractFlowStepData, "stateHash" | "transition"> & {
state_hash: ContractFlowStepData["stateHash"];
Expand Down Expand Up @@ -78,45 +95,26 @@ export interface FlowEditorInlineCodeBlock {
export type ListTestFlowsQuery = ZodInfer<typeof ListTestFlowsQuerySchema>;
export type GenerateTestFlowBody = ZodInfer<typeof GenerateTestFlowBodySchema>;

export interface TestFlowCrawlSessionSummary {
id: string;
triggerType: string;
status: string;
createdAt: string;
export type TestFlowCrawlSessionSummary = Omit<NonNullable<ContractFlowEditorTestFlowData["crawlSession"]>, "finishedAt"> & {
finishedAt?: string | null;
}
};

export interface TestFlowResponse {
id: string;
crawlSessionId: string;
appVersionId: string;
appVersionName: string;
checkpointStateHash: string;
transitionRefs: string[];
export type TestFlowResponse = Omit<ContractFlowEditorTestFlowData, "testFlowType" | "status" | "generatedAt" | "crawlSession"> & {
testFlowType: TestFlowType;
stepCount: number;
editorStepCount: number;
status: TestFlowStatus;
createdAt: string;
generatedAt: string | null;
modifiedAt: string;
crawlSession: TestFlowCrawlSessionSummary;
}
};

export interface ListTestFlowsResponse {
flows: TestFlowResponse[];
nextCursor?: string | null;
}

export interface FlowEditorElementRef {
selector?: string;
export type FlowEditorElementRef = Omit<ContractFlowEditorElementRefData, "selectorCandidates" | "tag" | "attributes" | "box" | "viewport"> & {
selectorCandidates?: string[];
tag?: string | null;
text?: string;
accessibleName?: string;
attributes?: Record<string, string>;
pageUrl?: string;
stateHash?: string;
box?: {
x: number;
y: number;
Expand All @@ -127,49 +125,43 @@ export interface FlowEditorElementRef {
width: number;
height: number;
};
}
};

export interface FlowEditorDraftStep {
id: string;
export type FlowEditorDraftStep = Omit<ContractFlowEditorDraftStepData, "kind" | "position" | "element" | "definition"> & {
kind: FlowEditorStepKind;
position: {
edge: FlowEditorPositionEdge;
transitionId: string;
};
order: number;
label: string;
element?: FlowEditorElementRef;
definition: Record<string, unknown>;
createdAt: string;
updatedAt: string;
}
};

export interface FlowEditorTransitionStep {
id: string;
index: number;
transitionId: string;
label: string;
action?: string;
export type FlowEditorStepStateLabel = Omit<ContractFlowEditorStepStateLabelData, "labelingStatus"> & {
labelingStatus: TestFlowStepLabelingStatus;
fromState?: TestFlowStepStateLabel;
toState?: TestFlowStepStateLabel;
}
};

export type FlowEditorTransitionStep = Omit<ContractFlowEditorTransitionStepData, "labelingStatus" | "fromState" | "toState"> & {
labelingStatus: TestFlowStepLabelingStatus;
fromState?: FlowEditorStepStateLabel;
toState?: FlowEditorStepStateLabel;
};

export interface FlowEditorDetailResponse {
export type FlowEditorDetailResponse = Omit<ContractFlowEditorDetailResponseData, "flow" | "transitionSteps" | "editorSteps"> & {
flow: TestFlowResponse;
transitionSteps: FlowEditorTransitionStep[];
editorSteps: FlowEditorDraftStep[];
}
};

export interface SaveFlowEditorStepsResponse {
export type SaveFlowEditorStepsBody = Omit<ContractSaveFlowEditorStepsRequestData, "editorSteps"> & {
editorSteps: FlowEditorDraftStep[];
editorStepCount: number;
}
};

export interface FlowEditorConnectResponse {
editorSessionId: string;
wsTicket: string;
}
export type SaveFlowEditorStepsResponse = Omit<ContractSaveFlowEditorStepsResponseData, "editorSteps"> & {
editorSteps: FlowEditorDraftStep[];
};

export type FlowEditorConnectResponse = Plain<ContractFlowEditorConnectResponse>;

export interface GenerateTestFlowResponse {
message: string;
Expand Down Expand Up @@ -280,5 +272,3 @@ export const FlowEditorDraftStepSchema = z.object({
export const SaveFlowEditorStepsBodySchema = z.object({
editorSteps: z.array(FlowEditorDraftStepSchema).max(500),
});

export type SaveFlowEditorStepsBody = ZodInfer<typeof SaveFlowEditorStepsBodySchema>;
4 changes: 4 additions & 0 deletions src/websockets/manualSessionBroker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type SessionSockets = {
const MANUAL_SESSION_SOCKET_MESSAGE_TYPES = {
"browser.input": ManualSessionSocketMessageType.BROWSER_INPUT,
"flow.start": ManualSessionSocketMessageType.FLOW_START,
"flow.publish_pending": ManualSessionSocketMessageType.UNSPECIFIED,
"flow.finish": ManualSessionSocketMessageType.UNSPECIFIED,
"flow.rewind": ManualSessionSocketMessageType.UNSPECIFIED,
"bug.report": ManualSessionSocketMessageType.UNSPECIFIED,
Expand All @@ -42,6 +43,7 @@ const MANUAL_SESSION_SOCKET_MESSAGE_TYPES = {
"recorded.step": ManualSessionSocketMessageType.UNSPECIFIED,
"session.ttl": ManualSessionSocketMessageType.UNSPECIFIED,
"flow.started": ManualSessionSocketMessageType.FLOW_STARTED,
"flow.pending_published": ManualSessionSocketMessageType.UNSPECIFIED,
"flow.completed": ManualSessionSocketMessageType.UNSPECIFIED,
"flow.rewound": ManualSessionSocketMessageType.UNSPECIFIED,
"bug.reported": ManualSessionSocketMessageType.UNSPECIFIED,
Expand Down Expand Up @@ -76,6 +78,7 @@ type WsMessage = Omit<ManualSessionSocketMessageContract, "type" | "status" | "r
const FRONTEND_MESSAGE_TYPES = new Set<ManualSessionSocketMessageName>([
"browser.input",
"flow.start",
"flow.publish_pending",
"flow.finish",
"flow.rewind",
"bug.report",
Expand All @@ -90,6 +93,7 @@ const CRAWLER_MESSAGE_TYPES = new Set<ManualSessionSocketMessageName>([
"recorded.step",
"session.ttl",
"flow.started",
"flow.pending_published",
"flow.completed",
"flow.rewound",
"bug.reported",
Expand Down
Loading