A drag threshold is the two lines that decide whether a press was a click or the start of a drag. It looks like the most testable thing in a UI.
It is not, and the reason is structural: a test suite has no hand.
Try it: https://dev48.infy.uk/design/day76-drag-threshold.html
What a synthetic gesture can assert
pointerDown, one pointerMove, pointerUp puts the pointer in two places with nothing in between. From that, three things can be asserted:
- a big move is a drag
- no movement is a click
- the same big move in forty small steps is still a drag
All three hold for six of eight rules.
Five of those six are wrong once a real hand is on the pointer.
Because a resting hand shakes
A real "click" is not zero movement. It is a few pixels of tremor over 80–200 ms, and the rule that appears in the most code — any movement past N pixels starts a drag — reads that as intent:
It calls 959 of 960 deliberate clicks a drag.
The synthetic test never sees it, because a synthetic click has exactly zero movement, which is the one case the rule handles correctly.
And the best rule is one the tests reject
Across 2,720 generated gestures on three pointer types:
| accuracy | |
|---|---|
| best of the six that pass the properties | 88.2% |
| second-best rule of all eight | 99.7% — and the properties throw it out |
It fails one of the three assertions on a behaviour that only exists in synthetic input. A property suite that cannot represent a hand will discard the rule that handles hands best, and keep the one that fails on almost every real click.
synthetic click : 0 px movement -> every rule passes
human click : 3-6 px of tremor -> five of six rules call it a drag
Verifier 273 asserts, 0 failures.
Top comments (0)