FAILURE MAP
← Case archive

FA-8176 / Disclosure widgets / Open access

Tooltip trigger and dismissal: Pointer leave hides a tooltip still needed by keyboard focus · case 01

Pointer leave hides a tooltip still needed by keyboard focus.

Verified by executionVariant 1 · 9 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The leave operation uses `if event == 'leave': return False` where the contract requires `if event == 'leave': return bool(focused)`.

VERIFIED REPAIR

Implement the leave operation as `if event == 'leave': return bool(focused)`.

Unsuccessful approach: Always keeping it open prevents pointer-only dismissal.

Case contract

Disabled triggers hide content; Escape dismisses regardless of trigger state; focus/enter open; blur and leave preserve the other active trigger.

Why this case matters

A deterministic model of tooltip trigger and dismissal; this isolates one interface invariant without requiring a browser.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(state, event, focused, hovered, disabled):
    if disabled: return False
    if event == 'escape': return False
    if event == 'focus': return True
    if event == 'enter': return True
    if event == 'blur': return bool(hovered)
    if event == 'leave': return False
    return state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disable', solve(True, 'none', False, False, True), False)
check('escape', solve(True, 'escape', True, True, False), False)
check('focus', solve(False, 'focus', True, False, False), True)
check('blur hovered', solve(True, 'blur', False, True, False), True)
check('blur abandoned', solve(True, 'blur', False, False, False), False)
check('leave focused', solve(True, 'leave', True, False, False), True)
check('leave abandoned', solve(True, 'leave', False, False, False), False)
check('parameterized remaining trigger', solve(True, 'blur', False, bool(N%2), False), bool(N%2))
for repetition in range(N):
    check('repeat leave abandoned', solve(True, 'leave', False, False, False), False)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
disableFalseFalsePassed
escapeFalseFalsePassed
focusTrueTruePassed
blur hoveredTrueTruePassed
blur abandonedFalseFalsePassed
leave focusedFalseTrueFailed
leave abandonedFalseFalsePassed
parameterized remaining triggerTrueTruePassed
repeat leave abandonedFalseFalsePassed

SHA-256 / 470228ae61770464c998b2d5a1ed40e2a2559f53d13d2b45a56891ce75a6afd2

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(state, event, focused, hovered, disabled):
    if disabled: return False
    if event == 'escape': return False
    if event == 'focus': return True
    if event == 'enter': return True
    if event == 'blur': return bool(hovered)
    if event == 'leave': return True
    return state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disable', solve(True, 'none', False, False, True), False)
check('escape', solve(True, 'escape', True, True, False), False)
check('focus', solve(False, 'focus', True, False, False), True)
check('blur hovered', solve(True, 'blur', False, True, False), True)
check('blur abandoned', solve(True, 'blur', False, False, False), False)
check('leave focused', solve(True, 'leave', True, False, False), True)
check('leave abandoned', solve(True, 'leave', False, False, False), False)
check('parameterized remaining trigger', solve(True, 'blur', False, bool(N%2), False), bool(N%2))
for repetition in range(N):
    check('repeat leave abandoned', solve(True, 'leave', False, False, False), False)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
disableFalseFalsePassed
escapeFalseFalsePassed
focusTrueTruePassed
blur hoveredTrueTruePassed
blur abandonedFalseFalsePassed
leave focusedTrueTruePassed
leave abandonedTrueFalseFailed
parameterized remaining triggerTrueTruePassed
repeat leave abandonedTrueFalseFailed

SHA-256 / 85a918a0aeb61ec0f0040c61996954bd6420d0d0bff3a53a53458b54b6003450

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(state, event, focused, hovered, disabled):
    if disabled: return False
    if event == 'escape': return False
    if event == 'focus': return True
    if event == 'enter': return True
    if event == 'blur': return bool(hovered)
    if event == 'leave': return bool(focused)
    return state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disable', solve(True, 'none', False, False, True), False)
check('escape', solve(True, 'escape', True, True, False), False)
check('focus', solve(False, 'focus', True, False, False), True)
check('blur hovered', solve(True, 'blur', False, True, False), True)
check('blur abandoned', solve(True, 'blur', False, False, False), False)
check('leave focused', solve(True, 'leave', True, False, False), True)
check('leave abandoned', solve(True, 'leave', False, False, False), False)
check('parameterized remaining trigger', solve(True, 'blur', False, bool(N%2), False), bool(N%2))
for repetition in range(N):
    check('repeat leave abandoned', solve(True, 'leave', False, False, False), False)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
disableFalseFalsePassed
escapeFalseFalsePassed
focusTrueTruePassed
blur hoveredTrueTruePassed
blur abandonedFalseFalsePassed
leave focusedTrueTruePassed
leave abandonedFalseFalsePassed
parameterized remaining triggerTrueTruePassed
repeat leave abandonedFalseFalsePassed

SHA-256 / c75368672f7ce71ffb7a703eb2ba69ccbf407ff753a76cc5311461e6cb8448b7

Verification & scope

This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:38:19.032533+00:00.

Case digest / 690483aeca080ef5f7f107b89cc5f23fad54fc107f6bccfcff9b2defb84803b9