Skip to content

Field checks held during a press

Web / frontend · Difficulty 4/5 · TypeScript · 50 linesOrigin: Real project (anonymized)

Task

What the AI was asked to do

When a form field loses focus (focusout) it is validated again and its error message is updated. Removing an error message moves the buttons below it up, so if the user is pressing a button with the mouse at that moment, the click misses. So while the mouse button is down, hold the validation of fields that lose focus and run it when the press ends. A press ends with click or pointercancel. If the user switches tabs or windows with the button down (pageLeft), the press will not end on this page; count it as ended then too. There is only one press at a time. Without a press, validation runs at once; a field that loses focus more than once during a press is validated once.

Handoff note

What the AI wrote when it handed over the code:

“Checks held during a press run on click and on pointercancel. They also run as soon as the user leaves the page, so the errors are up to date when the user comes back.”

The code the AI wrote

TypeScript50 lines

Mark the lines you think are wrong; give each mark a severity and a one-sentence reason.

Click or tap a line. With a keyboard, move to the line and press Enter.

0 of 5 marks
How to pick a severity
  • CriticalData loss, a security hole or lost money
  • MajorThe user gets a wrong result in a case the task asks for
  • MinorA rare edge case outside the task, or readability

In the Testing topic, severity is set by the effect of the broken implementation the test doesn't catch.

Your reason isn't graded; you'll compare it with a sample answer.

export interface PressAwareValidation {
  /** pointerdown anywhere on the page */
  pointerDown(): void;
  /** click anywhere on the page */
  click(): void;
  /** pointercancel anywhere on the page */
  pointerCancel(): void;
  /** the page was hidden or the window lost focus */
  pageLeft(): void;
  /** focusout on a form field */
  focusOut(field: string): void;
}
13
export function createPressAwareValidation(
  validate: (field: string) => void,
): PressAwareValidation {
  const held: string[] = [];
  let pressed = false;
19
  function runHeld(): void {
    for (const field of held.splice(0)) {
      validate(field);
    }
  }
25
  function endPress(): void {
    pressed = false;
    runHeld();
  }
30
  return {
    pointerDown() {
      pressed = true;
    },
    click: endPress,
    pointerCancel: endPress,
    pageLeft() {
      // Run the held checks now, so the errors are up to date when the
      // user comes back.
      runHeld();
    },
    focusOut(field) {
      if (!pressed) {
        validate(field);
      } else if (!held.includes(field)) {
        held.push(field);
      }
    },
  };
}

The test that proves it

The right option is the test that fails on this code, which means it exposes the bug.

Test options
Mark at least one line to submit.

Submitting sends seven pieces of information to a counter; your reason text stays on your device. Data