generated from coulomb/repo-seed
CE-WP-0008: fix capture field values and viewport scroll retry
- Wire fieldValues state in FormsApp so controlled inputs persist typed data - Add runScrollToHighlightJob with rAF retries when utils/highlights not ready - Re-trigger scroll when highlights update after PDF load - Tests: scroll-job unit test, forms-field-values integration tests - Workplan CE-WP-0008 marked done
This commit is contained in:
82
tests/integration/forms-field-values.dom.test.tsx
Normal file
82
tests/integration/forms-field-values.dom.test.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* CE-WP-0008-T01 — capture form field values persist across re-renders.
|
||||
*/
|
||||
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { cleanup, render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { Selector } from "@shared/selector";
|
||||
|
||||
import type { PdfSelectionCapture } from "@anchor/index";
|
||||
import manifest from "../../fixtures/pdfs/manifest.json" with { type: "json" };
|
||||
|
||||
interface ViewerProps {
|
||||
pdfUrl: string;
|
||||
storedAnnotations: readonly { id: string; text: string; selectors: readonly Selector[] }[];
|
||||
onSelectionCaptured(capture: PdfSelectionCapture, selectors: Selector[]): void;
|
||||
}
|
||||
|
||||
vi.mock("@anchor/index", async (importOriginal) => {
|
||||
const original = await importOriginal<typeof import("@anchor/index")>();
|
||||
const MockPdfSpikeViewer = (_props: ViewerProps) => (
|
||||
<div data-testid="mock-pdf-viewer" />
|
||||
);
|
||||
return { ...original, PdfSpikeViewer: MockPdfSpikeViewer };
|
||||
});
|
||||
|
||||
const FIXTURE = manifest.fixtures.find((f) => f.id === "fristsetzung-bezifferung")!;
|
||||
const SYNTHETIC_CANONICAL = ["Pre.", FIXTURE.known_good_quote, "Post."].join(" ");
|
||||
|
||||
import { seedSessionWithDoc } from "./helpers/seed-session";
|
||||
|
||||
async function loadApp() {
|
||||
const { App } = await import("@app/App");
|
||||
return render(<App />);
|
||||
}
|
||||
|
||||
describe("Capture — field value persistence (CE-WP-0008-T01)", () => {
|
||||
beforeEach(() => {
|
||||
globalThis.localStorage?.clear();
|
||||
if (typeof window !== "undefined") {
|
||||
history.replaceState(null, "", window.location.pathname);
|
||||
}
|
||||
seedSessionWithDoc({
|
||||
sessionName: "T01-field-values",
|
||||
documentTitle: FIXTURE.filename,
|
||||
canonicalText: SYNTHETIC_CANONICAL,
|
||||
mode: "forms",
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
cleanup();
|
||||
});
|
||||
|
||||
it("keeps typed text after focusing another field", { timeout: 15000 }, async () => {
|
||||
const user = userEvent.setup();
|
||||
await loadApp();
|
||||
|
||||
const summary = screen.getByLabelText("Summary of the matter");
|
||||
await user.type(summary, "Tenant owes arrears");
|
||||
await user.click(screen.getByLabelText("Disputed amount"));
|
||||
await user.click(summary);
|
||||
|
||||
expect((summary as HTMLTextAreaElement).value).toBe("Tenant owes arrears");
|
||||
});
|
||||
|
||||
it("keeps a selected date after blur", { timeout: 15000 }, async () => {
|
||||
const user = userEvent.setup();
|
||||
await loadApp();
|
||||
|
||||
const deadline = screen.getByLabelText("Key deadline") as HTMLInputElement;
|
||||
await user.clear(deadline);
|
||||
await user.type(deadline, "2026-12-15");
|
||||
await user.click(screen.getByLabelText("Disputed amount"));
|
||||
|
||||
expect(deadline.value).toBe("2026-12-15");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user