/**
 * TestCase — declarative description of a UI contract test.
 *
 * Rules (pure functions) produce TestCase[]. The translator renders
 * each TestCase into a Playwright `.spec.ts` file that imports helpers
 * from `@specverse/runtime/test-harness`. Neither rules nor test cases
 * know anything about React Query, cache invalidation, or any
 * implementation detail — they speak only spec language.
 *
 * v1 steps cover navigation + assertion. Later phases add create /
 * delete / evolve / expect-absent for state-sync rules.
 */
export type TestStep = {
    action: 'bootRuntime';
} | {
    action: 'expectNavHasModel';
    modelName: string;
} | {
    action: 'navigateToModel';
    modelName: string;
} | {
    action: 'navigateToModelForm';
    modelName: string;
} | {
    action: 'navigateToModelDetail';
    modelName: string;
} | {
    action: 'expectViewRenders';
} | {
    action: 'expectListColumn';
    modelName: string;
    attributeName: string;
} | {
    action: 'expectFormInput';
    modelName: string;
    attributeName: string;
    required?: boolean;
} | {
    action: 'expectLifecycleState';
    modelName: string;
    stateName: string;
} | {
    action: 'expectRelationshipSection';
    modelName: string;
    relationshipName: string;
} | {
    action: 'expectActionButton';
    modelName: string;
    actionLabel: string;
} | {
    action: 'createEntity';
    modelName: string;
    data: Record<string, unknown>;
    bindAs?: string;
    uniqueField?: string;
} | {
    action: 'deleteEntity';
    modelName: string;
    idExpr: string;
} | {
    action: 'evolveEntity';
    modelName: string;
    idExpr: string;
    targetState: string;
} | {
    action: 'expectEntityInList';
    modelName: string;
    displayValue?: string;
    displayExpr?: string;
} | {
    action: 'expectEntityAbsent';
    modelName: string;
    displayValue?: string;
    displayExpr?: string;
};
export interface TestCase {
    /** The rule that produced this test case. Used in test names for attribution. */
    ruleId: string;
    /** The spec element the case applies to (e.g. 'Poll', 'PollController.delete'). */
    specElement: string;
    /** Full test name — shown by Playwright reporter. */
    name: string;
    /** Ordered sequence of actions/assertions. */
    steps: TestStep[];
}
/**
 * A rule is a pure function from a normalized spec to a list of test
 * cases. Rules never touch the filesystem, the network, or any mutable
 * state — they just describe what should be tested.
 */
export type UiContractRule = (spec: NormalizedSpec) => TestCase[];
/**
 * Minimal normalized spec shape the rules operate on. The realize
 * pipeline converts raw spec output into this shape before running
 * rules. Kept deliberately small — rules grow their own helpers as
 * they need richer data.
 */
export interface NormalizedSpec {
    models: ModelInfo[];
    controllers?: ControllerInfo[];
    services?: ServiceInfo[];
    views?: ViewInfo[];
}
export interface ModelInfo {
    name: string;
    attributes?: AttributeInfo[];
    lifecycles?: Record<string, unknown>;
    relationships?: RelationshipInfo[];
}
export interface AttributeInfo {
    name: string;
    type?: string;
    required?: boolean;
    category?: 'business' | 'metadata' | 'relationship';
}
export interface RelationshipInfo {
    name: string;
    type: string;
    target?: string;
}
export interface ControllerInfo {
    name: string;
    model?: string;
    cured?: Record<string, unknown>;
}
export interface ServiceInfo {
    name: string;
    operations?: Record<string, unknown>;
}
export interface ViewInfo {
    name: string;
    type: string;
    model?: string;
}
//# sourceMappingURL=test-case-types.d.ts.map