diff --git a/src/components/form/Form.test.tsx b/src/components/form/Form.test.tsx index b2bf050..01d20e4 100644 --- a/src/components/form/Form.test.tsx +++ b/src/components/form/Form.test.tsx @@ -13,6 +13,8 @@ import { FormField } from "./FormField"; import { Validator } from "../../hooks/form-validation/useValidation"; import { RadioButtonGroup, RadioOption } from "./RadioButtonGroup"; import { USER_EVENT_KEYS_FOR_TESTING_ONLY } from "../../../test/user-event-keys"; +import { now } from "../../utilities/date-utilities"; +import mocked = jest.mocked; const submitEndpoint = "form-submit-endpoint"; const formLabelText = "Short information about the form"; @@ -20,6 +22,8 @@ const formLabelText = "Short information about the form"; const successMessage = "Your issue has been reported, thank you!"; const pageIdentifier = "test-page"; +jest.mock("../../utilities/date-utilities"); + describe(Form.name, () => { let capturedFormData: AccessibilityFormData; let user: UserEvent; @@ -141,7 +145,14 @@ describe(Form.name, () => { let honeypotInput: HTMLInputElement; const honeypotValue = "I'm a robot"; + const timeFormWasRendered = 42892453216246; + const timeFormWasSubmitted = 42892453641411; + beforeEach(async () => { + mocked(now) + .mockName("now") + .mockReturnValueOnce(timeFormWasRendered) + .mockReturnValueOnce(timeFormWasSubmitted); render(); form = screen.getByRole("form"); @@ -197,7 +208,13 @@ describe(Form.name, () => { }); test("the form's data is sent to the server", async () => { - expect(capturedFormData).toEqual({ name, age, color, honeypotValue }); + expect(capturedFormData).toEqual({ + name, + age, + color, + honeypotValue, + timeToFillForm: `${timeFormWasSubmitted - timeFormWasRendered} milliseconds` + }); }); describe("when form submission succeeds", () => { diff --git a/src/components/form/Form.tsx b/src/components/form/Form.tsx index 0370450..e5ecec5 100644 --- a/src/components/form/Form.tsx +++ b/src/components/form/Form.tsx @@ -8,6 +8,7 @@ import { FormProvider } from "../../contexts/FormContext"; import { Observable } from "../../utilities/observable"; import { SubmitLoadingIcon } from "./SubmitLoadingIcon"; import { useLiveRegionText } from "../../hooks/useLiveRegionText"; +import { now } from "../../utilities/date-utilities"; type FormProps = ChildrenProps & { ariaLabelledBy: string @@ -23,6 +24,7 @@ export const Form = ({ children, ariaLabelledBy, submitEndpoint, successMessage const [showSuccessMessage, setShowSuccessMessage] = useState(false); const [errorMessage, setErrorMessage] = useState(""); const [liveRegionText, setLiveRegionText] = useLiveRegionText(""); + const [timeBeganFillingForm, setTimeBeganFillingForm] = useState(now()); const postFormData = usePOST(submitEndpoint); @@ -55,6 +57,7 @@ export const Form = ({ children, ariaLabelledBy, submitEndpoint, successMessage setLiveRegionText("submitting"); const formData = extractFormData(form); + formData.timeToFillForm = `${now() - timeBeganFillingForm} milliseconds`; postFormData(formData, (ok, _, error) => { setSubmitting(false); @@ -68,7 +71,7 @@ export const Form = ({ children, ariaLabelledBy, submitEndpoint, successMessage } }); } - }, [onSubmitObservable, setLiveRegionText, postFormData, onClearObservable]); + }, [onSubmitObservable, setLiveRegionText, postFormData, onClearObservable, timeBeganFillingForm]); return (
{showSuccessMessage && diff --git a/src/utilities/date-utilities.test.ts b/src/utilities/date-utilities.test.ts new file mode 100644 index 0000000..fdfd52b --- /dev/null +++ b/src/utilities/date-utilities.test.ts @@ -0,0 +1,12 @@ +import { now } from "./date-utilities"; + +describe("date utilities", () => { + test("now returns current time in milliseconds since the epoch", () => { + const timeFromDate = Date.now(); + const time = now(); + const fiveSeconds = 5000; + + expect(time).toBeGreaterThanOrEqual(timeFromDate); + expect(time).toBeLessThanOrEqual(timeFromDate + fiveSeconds); + }); +}); diff --git a/src/utilities/date-utilities.ts b/src/utilities/date-utilities.ts new file mode 100644 index 0000000..dee6720 --- /dev/null +++ b/src/utilities/date-utilities.ts @@ -0,0 +1 @@ +export const now = (): number => Date.now();